Search in sources :

Example 1 with ExpressionContext

use of kalang.antlr.KalangParser.ExpressionContext in project kalang by kasonyang.

the class AstBuilder method visitLocalVarDecl.

@Override
public Statement visitLocalVarDecl(LocalVarDeclContext ctx) {
    MultiStmt ms = new MultiStmt();
    for (VarDeclContext v : ctx.varDecl()) {
        TypeContext varType = v.varType;
        Type exceptedType = varType == null ? null : parseType(varType);
        ExprNode initExpr = null;
        ExpressionContext initExprContext = v.expression();
        if (initExprContext != null) {
            if (initExprContext instanceof LiteralExprContext) {
                initExpr = this.parseLiteral(((LiteralExprContext) initExprContext).literal(), exceptedType);
            } else {
                initExpr = visitExpression(initExprContext);
            }
        }
        VarInfo varInfo = varDecl(v, initExpr == null ? Types.getRootType() : initExpr.getType());
        LocalVarNode localVar = this.declareLocalVar(varInfo.name, varInfo.type, varInfo.modifier, ctx);
        if (localVar == null)
            return null;
        VarDeclStmt vds = new VarDeclStmt(localVar);
        ms.statements.add(vds);
        if (initExpr != null) {
            AssignExpr assignExpr = new AssignExpr(new VarExpr(localVar), initExpr);
            mapAst(assignExpr, v);
            ms.statements.add(new ExprStmt(assignExpr));
        }
        mapAst(localVar, ctx);
    }
    return ms;
}
Also used : MultiStmt(kalang.ast.MultiStmt) TypeContext(kalang.antlr.KalangParser.TypeContext) AssignExpr(kalang.ast.AssignExpr) ExprNode(kalang.ast.ExprNode) WildcardType(kalang.core.WildcardType) ArrayType(kalang.core.ArrayType) ClassType(kalang.core.ClassType) PrimitiveType(kalang.core.PrimitiveType) Type(kalang.core.Type) GenericType(kalang.core.GenericType) ObjectType(kalang.core.ObjectType) ExprStmt(kalang.ast.ExprStmt) ExpressionContext(kalang.antlr.KalangParser.ExpressionContext) VarDeclStmt(kalang.ast.VarDeclStmt) VarExpr(kalang.ast.VarExpr) LiteralExprContext(kalang.antlr.KalangParser.LiteralExprContext) LocalVarNode(kalang.ast.LocalVarNode) VarDeclContext(kalang.antlr.KalangParser.VarDeclContext) LocalVarDeclContext(kalang.antlr.KalangParser.LocalVarDeclContext)

Example 2 with ExpressionContext

use of kalang.antlr.KalangParser.ExpressionContext in project kalang by kasonyang.

the class AstBuilder method visitInterpolationExpr.

@Override
public Object visitInterpolationExpr(KalangParser.InterpolationExprContext ctx) {
    List<ParseTree> children = ctx.children;
    ExprNode[] exprs = new ExprNode[children.size()];
    Token[] exprTokens = new Token[children.size()];
    for (int i = 0; i < exprs.length; i++) {
        ParseTree c = children.get(i);
        if (c instanceof TerminalNode) {
            Token token = ((TerminalNode) c).getSymbol();
            int t = token.getType();
            String rawText = c.getText();
            String text;
            switch(t) {
                case KalangLexer.InterpolationPreffixString:
                    text = rawText.substring(1, rawText.length() - 2);
                    break;
                case KalangLexer.INTERPOLATION_STRING:
                    text = rawText;
                    break;
                case KalangLexer.RBRACE:
                case KalangLexer.INTERPOLATION_END:
                case KalangLexer.INTERPOLATION_INTERUPT:
                    // TODO optimize empty string
                    text = "";
                    break;
                default:
                    throw Exceptions.unexceptedValue(t);
            }
            exprs[i] = new ConstExpr(StringLiteralUtil.parse(text));
            exprTokens[i] = token;
        } else if (c instanceof ExpressionContext) {
            ExprNode expr = this.visitExpression((ExpressionContext) c);
            if (expr == null)
                return null;
            exprs[i] = expr;
            exprTokens[i] = ((ExpressionContext) c).getStart();
        } else {
            throw Exceptions.unexceptedValue(c);
        }
    }
    return this.concatExpressionsToStringExpr(exprs, exprTokens);
}
Also used : ExprNode(kalang.ast.ExprNode) ConstExpr(kalang.ast.ConstExpr) ExpressionContext(kalang.antlr.KalangParser.ExpressionContext) Token(org.antlr.v4.runtime.Token) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode) ParseTree(org.antlr.v4.runtime.tree.ParseTree)

Example 3 with ExpressionContext

use of kalang.antlr.KalangParser.ExpressionContext in project kalang by kasonyang.

the class AstBuilder method visitAssignExpr.

@Override
public ExprNode visitAssignExpr(AssignExprContext ctx) {
    ExprNode expr;
    String assignOp = ctx.getChild(1).getText();
    ExpressionContext toCtx = ctx.expression(0);
    ExpressionContext fromCtx = ctx.expression(1);
    if (toCtx instanceof GetFieldExprContext) {
        // TODO check readonly
        expr = createFieldExpr((GetFieldExprContext) toCtx, fromCtx, OffsetRangeHelper.getOffsetRange(ctx));
    } else {
        ExprNode to = visitExpression(toCtx);
        ExprNode from = visitExpression(fromCtx);
        if (assignOp.length() > 1) {
            String op = assignOp.substring(0, assignOp.length() - 1);
            from = createBinaryExpr(to, from, op);
        }
        AssignableExpr toExpr;
        if (to instanceof AssignableExpr) {
            toExpr = (AssignableExpr) to;
            if (!this.semanticAnalyzer.validateAssign(toExpr, from, OffsetRangeHelper.getOffsetRange(ctx))) {
                return null;
            }
            AssignExpr aexpr = new AssignExpr(toExpr, from);
            mapAst(aexpr, ctx);
            // TODO remove override information before assign
            onAssign(toExpr, from);
            expr = aexpr;
        } else {
            AstBuilder.this.handleSyntaxError("unsupported assign statement", ctx);
            return null;
        }
    }
    return expr;
}
Also used : ExprNode(kalang.ast.ExprNode) ExpressionContext(kalang.antlr.KalangParser.ExpressionContext) AssignableExpr(kalang.ast.AssignableExpr) GetFieldExprContext(kalang.antlr.KalangParser.GetFieldExprContext) AssignExpr(kalang.ast.AssignExpr)

Example 4 with ExpressionContext

use of kalang.antlr.KalangParser.ExpressionContext in project kalang by kasonyang.

the class AstBuilder method visitMapExpr.

@Override
public MultiStmtExpr visitMapExpr(KalangParser.MapExprContext ctx) {
    Type keyType = ctx.keyType != null ? requireClassType(ctx.keyType) : Types.getRootType();
    Type valueType = ctx.valueType != null ? requireClassType(ctx.valueType) : Types.getRootType();
    if (keyType == null || valueType == null)
        return null;
    LocalVarNode vo = declareTempLocalVar(Types.getClassType(Types.getMapImplClassType().getClassNode(), new Type[] { keyType, valueType }));
    VarDeclStmt vds = new VarDeclStmt(vo);
    NewObjectExpr newExpr;
    try {
        newExpr = new NewObjectExpr(Types.getMapImplClassType());
    } catch (MethodNotFoundException | AmbiguousMethodException ex) {
        throw Exceptions.unexceptedException(ex);
    }
    List<Statement> stmts = new LinkedList<>();
    stmts.add(vds);
    stmts.add(new ExprStmt(new AssignExpr(new VarExpr(vo), newExpr)));
    VarExpr ve = new VarExpr(vo);
    List<TerminalNode> ids = ctx.Identifier();
    for (int i = 0; i < ids.size(); i++) {
        ExpressionContext e = ctx.expression(i);
        ExprNode v = (ExprNode) visit(e);
        ConstExpr k = new ConstExpr(ctx.Identifier(i).getText());
        ExprNode[] args = new ExprNode[] { k, v };
        InvocationExpr iv;
        try {
            iv = ObjectInvokeExpr.create(ve, "put", args);
        } catch (MethodNotFoundException | AmbiguousMethodException ex) {
            throw Exceptions.unexceptedException(ex);
        }
        ExprStmt es = new ExprStmt(iv);
        stmts.add(es);
    }
    MultiStmtExpr mse = new MultiStmtExpr(stmts, ve);
    mapAst(mse, ctx);
    return mse;
}
Also used : ConstExpr(kalang.ast.ConstExpr) Statement(kalang.ast.Statement) NewObjectExpr(kalang.ast.NewObjectExpr) LinkedList(java.util.LinkedList) AssignExpr(kalang.ast.AssignExpr) ExprNode(kalang.ast.ExprNode) MultiStmtExpr(kalang.ast.MultiStmtExpr) WildcardType(kalang.core.WildcardType) ArrayType(kalang.core.ArrayType) ClassType(kalang.core.ClassType) PrimitiveType(kalang.core.PrimitiveType) Type(kalang.core.Type) GenericType(kalang.core.GenericType) ObjectType(kalang.core.ObjectType) ExprStmt(kalang.ast.ExprStmt) ExpressionContext(kalang.antlr.KalangParser.ExpressionContext) VarDeclStmt(kalang.ast.VarDeclStmt) VarExpr(kalang.ast.VarExpr) TerminalNode(org.antlr.v4.runtime.tree.TerminalNode) LocalVarNode(kalang.ast.LocalVarNode) MethodNotFoundException(kalang.MethodNotFoundException) InvocationExpr(kalang.ast.InvocationExpr) UnknownInvocationExpr(kalang.ast.UnknownInvocationExpr) AmbiguousMethodException(kalang.AmbiguousMethodException)

Example 5 with ExpressionContext

use of kalang.antlr.KalangParser.ExpressionContext in project kalang by kasonyang.

the class AstBuilder method createFieldExpr.

protected ExprNode createFieldExpr(GetFieldExprContext to, @Nullable ExpressionContext fromCtx, OffsetRange offsetRange) {
    // TODO support iterating syntax
    String refKey = to.refKey.getText();
    ExpressionContext exp = to.expression();
    String fname = to.Identifier().getText();
    AssignableExpr toExpr;
    Object expr = visit(exp);
    if (refKey.equals(".")) {
        ExprNode fieldExpr;
        if (expr instanceof ExprNode) {
            ExprNode exprNode = (ExprNode) expr;
            fieldExpr = getObjectFieldLikeExpr(exprNode, fname, to);
        } else if (expr instanceof ClassReference) {
            fieldExpr = getStaticFieldExpr((ClassReference) expr, fname, to);
        } else {
            throw new UnknownError("unknown node:" + expr);
        }
        if (fromCtx == null) {
            return fieldExpr;
        } else {
            if (fieldExpr instanceof AssignableExpr) {
                toExpr = (AssignableExpr) fieldExpr;
            } else {
                AstBuilder.this.handleSyntaxError("unsupported", to);
                return null;
            }
            ExprNode fromExpr = visitExpression(fromCtx);
            if (!this.semanticAnalyzer.validateAssign(toExpr, fromExpr, offsetRange)) {
                return null;
            }
            return new AssignExpr(toExpr, fromExpr);
        }
    } else if (refKey.equals("->")) {
        ExprNode[] params;
        String methodName;
        if (fromCtx == null) {
            params = new ExprNode[0];
            methodName = "get" + NameUtil.firstCharToUpperCase(fname);
        } else {
            params = new ExprNode[1];
            methodName = "set" + NameUtil.firstCharToUpperCase(fname);
        }
        if (expr instanceof ExprNode) {
            if (fromCtx != null)
                params[0] = visitExpression(fromCtx);
            return getObjectInvokeExpr((ExprNode) expr, methodName, params, to);
        } else {
            // don't support static property
            handleSyntaxError("object expression required.", to);
            return null;
        }
    } else {
        throw Exceptions.unknownValue(refKey);
    }
}
Also used : ExprNode(kalang.ast.ExprNode) ExpressionContext(kalang.antlr.KalangParser.ExpressionContext) AssignableExpr(kalang.ast.AssignableExpr) VarObject(kalang.ast.VarObject) ClassReference(kalang.ast.ClassReference) AssignExpr(kalang.ast.AssignExpr)

Aggregations

ExpressionContext (kalang.antlr.KalangParser.ExpressionContext)7 ExprNode (kalang.ast.ExprNode)7 AssignExpr (kalang.ast.AssignExpr)4 ExprStmt (kalang.ast.ExprStmt)3 ArrayType (kalang.core.ArrayType)3 ClassType (kalang.core.ClassType)3 GenericType (kalang.core.GenericType)3 ObjectType (kalang.core.ObjectType)3 PrimitiveType (kalang.core.PrimitiveType)3 Type (kalang.core.Type)3 WildcardType (kalang.core.WildcardType)3 LinkedList (java.util.LinkedList)2 TypeContext (kalang.antlr.KalangParser.TypeContext)2 AssignableExpr (kalang.ast.AssignableExpr)2 ConstExpr (kalang.ast.ConstExpr)2 LocalVarNode (kalang.ast.LocalVarNode)2 Statement (kalang.ast.Statement)2 VarDeclStmt (kalang.ast.VarDeclStmt)2 VarExpr (kalang.ast.VarExpr)2 TerminalNode (org.antlr.v4.runtime.tree.TerminalNode)2