visitExpr()

in lib/generator.js [1306:1454]


  visitExpr(ast, level, env = {}) {
    if (ast.type === 'boolean') {
      this.emit(ast.value);
    } else if (ast.type === 'property_access') {
      this.visitPropertyAccess(ast, level, env);
    } else if (ast.type === 'string') {
      let val = _string(ast.value);
      val = val.replace(/(?<!\\)(?:\\{2})*"/g, '\\"');
      this.emit(`"${val}"`);
    } else if (ast.type === 'number') {
      this.emit(ast.value.value);
      if (ast.value.type === 'float') {
        this.emit('f');
      }
    } else if (ast.type === 'object') {
      this.visitObject(ast, level, env);
    } else if (ast.type === 'variable') {
      var id = _name(ast.id);
      if (id === '__response') {
        this.emit(RESPONSE);
      } else if (id === '__request') {
        this.emit(REQUEST);
      } else if (ast.inferred && ast.inferred.name === 'class') {
        this.emit('typeof(' + _avoidReserveName(id) + ')');
      }
      else {
        this.emit(_avoidReserveName(id));
      }
    } else if (ast.type === 'virtualVariable') {
      const vid = `_${_lowerFirst(_name(ast.vid).substr(1))}`;
      if (_name(ast.inferred) === 'boolean') {
        this.emit(`${vid}.Value`);
      } else {
        this.emit(`${vid}`);
      }
    } else if (ast.type === 'decrement') {
      if (ast.position === 'front') {
        this.emit('--');
      }
      this.visitExpr(ast.expr, level, env);
      if (ast.position === 'backend') {
        this.emit('--');
      }
    } else if (ast.type === 'increment') {
      if (ast.position === 'front') {
        this.emit('++');
      }
      this.visitExpr(ast.expr, level, env);
      if (ast.position === 'backend') {
        this.emit('++');
      }
    } else if (ast.type === 'template_string') {
      var elements = ast.elements.filter((item) => {
        return item.type !== 'element' || item.value.string.length > 0;
      });

      for (var i = 0; i < elements.length; i++) {
        var item = elements[i];
        if (item.type === 'element') {
          this.emit('"');
          let val = _string(item.value);
          val = val.replace(/(?<!\\)(?:\\{2})*"/g, '\\"');
          val = val.replace(/[\n]/g, '" + \n"');
          this.emit(val);
          this.emit('"');
        } else if (item.type === 'expr') {
          if (i === 0) {
            this.emit('"" + ');
          }
          env.groupOp = true;
          this.visitExpr(item.expr, level, env);
        } else {
          throw new Error('unimpelemented');
        }

        if (i < elements.length - 1) {
          this.emit(' + ');
        }
      }
    } else if (ast.type === 'call') {
      this.visitCall(ast, level, env);
    } else if (ast.type === 'construct') {
      this.visitConstruct(ast, level, env);
    } else if (ast.type === 'group') {
      env.groupOp = false;
      this.emit('(');
      this.visitExpr(ast.expr, level, env);
      this.emit(')');
    } else if (_isBinaryOp(ast.type)) {
      env.groupOp = true;
      this.visitExpr(ast.left, level, env);
      if (ast.type === 'or') {
        this.emit(' || ');
      } else if (ast.type === 'add') {
        this.emit(' + ');
      } else if (ast.type === 'subtract') {
        this.emit(' - ');
      } else if (ast.type === 'div') {
        this.emit(' / ');
      } else if (ast.type === 'multi') {
        this.emit(' * ');
      } else if (ast.type === 'and') {
        this.emit(' && ');
      } else if (ast.type === 'lte') {
        this.emit(' <= ');
      } else if (ast.type === 'lt') {
        this.emit(' < ');
      } else if (ast.type === 'gte') {
        this.emit(' >= ');
      } else if (ast.type === 'gt') {
        this.emit(' > ');
      } else if (ast.type === 'neq') {
        this.emit(' != ');
      } else if (ast.type === 'eq') {
        this.emit(' == ');
      }
      this.visitExpr(ast.right, level, env);
    }
    else if (ast.type === 'array') {
      this.visitArray(ast, level, env);
    } else if (ast.type === 'null') {
      this.emit('null');
    } else if (ast.type === 'not') {
      env.groupOp = true;
      this.emit('!');

      let wrapName;
      if (ast.expr.left && ast.expr.left.id) {
        wrapName = _upperFirst(_name(ast.expr.left.id));
      }
      if (ast.expr.type === 'call' && wrapName && !wrapName.startsWith('$') && !this.builtin[wrapName]) {
        this.emit('(');
      }
      this.visitExpr(ast.expr, level, env);
      if (ast.expr.type === 'call' && wrapName && !wrapName.startsWith('$') && !this.builtin[wrapName]) {
        this.emit(').Value');
      }
    } else if (ast.type === 'construct_model') {
      this.visitConstructModel(ast, level, env);
    } else if (ast.type === 'map_access') {
      this.visitMapAccess(ast, level, env);
    } else if (ast.type === 'super') {
      //no need
    } else if (ast.type === 'array_access') {
      this.visitArrayAccess(ast, level, env);
    } else {
      throw new Error('unimpelemented');
    }
  }