grammerExpr()

in src/langs/cpp/combinator.js [1529:1626]


  grammerExpr(emitter, gram) {
    if (gram.opt === Symbol.concat()) {
      // implement by behaviorTamplateString
      debug.stack(gram);
    }
    this.exprIsAssignToPtr = this.isPointerVar(gram.left);
    if (!gram.left && !gram.right) {
      // only emit symbol
      emitter.emit(` ${_symbol(gram.opt)} `);
      this.exprIsAssignToPtr = null;
      return;
    }
    // emit left of expr
    if (gram.opt !== Symbol.assign() && this.exprIsAssignToPtr) {
      emitter.emit('*');
    }
    this.grammer(emitter, gram.left, false, false);

    if (gram.right.type === 'null') {
      // not emit symbol&right if right of expr is null
      this.exprIsAssignToPtr = null;
      if (gram.left instanceof GrammerVar) { return; }
    }

    // emit right of expr
    if (gram.opt === Symbol.assign()) {
      let isNewObject = false;
      let right = null;
      if (gram.right instanceof GrammerValue && gram.right.type === 'instance' && gram.right.value instanceof GrammerNewObject) {
        isNewObject = true;
        right = gram.right.value;
      } else if (gram.right instanceof GrammerNewObject) {
        isNewObject = true;
        right = gram.right;
      }
      if (isNewObject) {
        this.exprIsAssignToPtr = this.isPointerVar(gram.left);
        // is new object
        if (this.isPointerVar(gram.left)) {
          // new object to ptr property
          emitter.emit(` ${_symbol(gram.opt)} `); // emit symbol of expr
          this.grammerNewObject(emitter, right, true, true);
          this.exprIsAssignToPtr = null;
          return;
        }
        this.grammerNewObject(emitter, right, false);
        this.exprIsAssignToPtr = null;
        return;
      }
      emitter.emit(` ${_symbol(gram.opt)} `); // emit symbol of expr
      let toStream = false;
      let leftIsPointer;
      let leftDataType = this.resolveDataType(gram.left);
      if (leftDataType !== 'Darabonba::Stream' && gram.left instanceof GrammerValue && gram.left.type === 'call' && gram.left.value.path[1].name === 'body') {
        const k = gram.left.value.path.map(item => item.name).join('.');
        toStream = k === '__request.body' && is.string(gram.right.dataType);
        leftIsPointer = true;
      } else {
        toStream = leftDataType === 'Darabonba::Stream';
        leftIsPointer = this.isPointerVar(gram.left);
      }
      let rightIsPointer = this.isPointerVar(gram.right);
      if (toStream) {
        emitter.emit(`${this.config.tea.converter.name}::toStream(`);
      }
      let dataType = this.resolveDataType(gram.right);
      if (dataType === null) {
        dataType = this.resolveDataType(gram.left);
      }
      if (leftIsPointer && rightIsPointer) {
        if (toStream) {
          emitter.emit('*');
        }
        this.exprIsAssignToPtr = true;
        this.grammer(emitter, gram.right, false, false);
      } else if (leftIsPointer && !rightIsPointer) {
        this.exprIsAssignToPtr = true;
        if (toStream) {
          this.grammer(emitter, gram.right, false, false);
        } else {
          emitter.emit(this.emitMakeShared(dataType, gram.right));
        }
      } else if (!leftIsPointer && rightIsPointer) {
        emitter.emit('*');
        this.grammer(emitter, gram.right, false, false);
      } else {
        this.grammer(emitter, gram.right, false, false);
      }
      if (toStream) {
        emitter.emit(')');
      }
      this.exprIsAssignToPtr = null;
      return;
    }
    emitter.emit(` ${_symbol(gram.opt)} `); // emit symbol of expr
    this.grammer(emitter, gram.right, false, false);
    this.exprIsAssignToPtr = null;
  }