Search in sources :

Example 6 with AssignExpr

use of kalang.ast.AssignExpr in project kalang by kasonyang.

the class AstBuilder method visitInvokeExpr.

@Override
public AstNode visitInvokeExpr(InvokeExprContext ctx) {
    Object target = visit(ctx.target);
    if (target == null)
        return null;
    String mdName = ctx.Identifier().getText();
    String refKey = ctx.refKey.getText();
    if (refKey.equals(".")) {
        if (target instanceof ClassReference) {
            return getStaticInvokeExpr((ClassReference) target, mdName, ctx.params, ctx);
        } else if (target instanceof ExprNode) {
            return getObjectInvokeExpr((ExprNode) target, mdName, ctx.params, ctx);
        } else {
            throw Exceptions.unexceptedValue(target);
        }
    } else if (refKey.equals("->")) {
        ExprNode[] invokeArgs = new ExprNode[3];
        ExprNode[] params = new ExprNode[ctx.params.size()];
        if (target instanceof ClassReference) {
            invokeArgs[0] = new ConstExpr(null);
        } else if (target instanceof ExprNode) {
            invokeArgs[0] = ((ExprNode) target);
        }
        invokeArgs[1] = new ConstExpr(mdName);
        for (int i = 0; i < params.length; i++) {
            params[i] = visitExpression(ctx.params.get(i));
        }
        invokeArgs[2] = createInitializedArray(Types.getRootType(), params);
        ClassNode dispatcherAst = getAst("kalang.runtime.dynamic.MethodDispatcher");
        if (dispatcherAst == null) {
            throw Exceptions.unexceptedException("Runtime library is required!");
        }
        return getStaticInvokeExpr(new ClassReference(dispatcherAst), "invokeMethod", invokeArgs, ctx);
    } else if (refKey.equals("*.")) {
        if (!(target instanceof ExprNode)) {
            handleSyntaxError("expression required", ctx.expression);
            return null;
        }
        ExprNode targetExpr = (ExprNode) target;
        Type targetType = targetExpr.getType();
        if (!(targetType instanceof ArrayType)) {
            handleSyntaxError("array required", ctx.expression);
            return null;
        }
        List<Statement> stats = new LinkedList();
        LocalVarNode varArrLen = this.declareTempLocalVar(Types.INT_TYPE);
        LocalVarNode varCounter = this.declareTempLocalVar(Types.INT_TYPE);
        stats.add(new VarDeclStmt(Arrays.asList(varArrLen, varCounter)));
        VarExpr varArrLenExpr = new VarExpr(varArrLen);
        VarExpr varCounterExpr = new VarExpr(varCounter);
        stats.add(new ExprStmt(new AssignExpr(varArrLenExpr, new ArrayLengthExpr(targetExpr))));
        stats.add(new ExprStmt(new AssignExpr(varCounterExpr, new ConstExpr(0))));
        CompareExpr conditionExpr = new CompareExpr(varCounterExpr, varArrLenExpr, CompareExpr.OP_LT);
        ExprNode targetEleExpr = new ElementExpr(targetExpr, varCounterExpr);
        ExprNode invokeExpr = getObjectInvokeExpr(targetEleExpr, mdName, ctx.params, ctx);
        if (invokeExpr == null)
            return null;
        LocalVarNode varRet = this.declareTempLocalVar(Types.getArrayType(invokeExpr.getType()));
        VarExpr varRetExpr = new VarExpr(varRet);
        stats.add(new VarDeclStmt(varRet));
        stats.add(new ExprStmt(new AssignExpr(varRetExpr, new NewArrayExpr(invokeExpr.getType(), varArrLenExpr))));
        BlockStmt loopBody = this.newBlock();
        loopBody.statements.add(new ExprStmt(new AssignExpr(new ElementExpr(varRetExpr, varCounterExpr), invokeExpr)));
        popBlock();
        BlockStmt updateBs = newBlock();
        updateBs.statements.add(new ExprStmt(new AssignExpr(varCounterExpr, new MathExpr(varCounterExpr, new ConstExpr(1), MathExpr.OP_ADD))));
        this.popBlock();
        LoopStmt loopStmt = new LoopStmt(conditionExpr, null, loopBody, updateBs);
        stats.add(loopStmt);
        return new MultiStmtExpr(stats, varRetExpr);
    } else {
        throw Exceptions.unexceptedException(refKey);
    }
}
Also used : ClassNode(kalang.ast.ClassNode) ConstExpr(kalang.ast.ConstExpr) LoopStmt(kalang.ast.LoopStmt) Statement(kalang.ast.Statement) BlockStmt(kalang.ast.BlockStmt) ArrayLengthExpr(kalang.ast.ArrayLengthExpr) LinkedList(java.util.LinkedList) AssignExpr(kalang.ast.AssignExpr) ExprNode(kalang.ast.ExprNode) ArrayType(kalang.core.ArrayType) 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) CompareExpr(kalang.ast.CompareExpr) NewArrayExpr(kalang.ast.NewArrayExpr) VarDeclStmt(kalang.ast.VarDeclStmt) VarExpr(kalang.ast.VarExpr) VarObject(kalang.ast.VarObject) ClassReference(kalang.ast.ClassReference) LocalVarNode(kalang.ast.LocalVarNode) MathExpr(kalang.ast.MathExpr) ElementExpr(kalang.ast.ElementExpr)

Example 7 with AssignExpr

use of kalang.ast.AssignExpr in project kalang by kasonyang.

the class AstBuilder method visitFieldDecl.

@Override
public Void visitFieldDecl(FieldDeclContext ctx) {
    int fieldModifier = this.parseModifier(ctx.varModifier());
    for (VarDeclContext vd : ctx.varDecl()) {
        ExprNode initExpr;
        if (vd.expression() != null) {
            initExpr = visitExpression(vd.expression());
        } else {
            initExpr = null;
        }
        VarInfo varInfo = varDecl(vd, initExpr == null ? Types.getRootType() : initExpr.getType());
        varInfo.modifier |= fieldModifier;
        FieldNode fieldNode = thisClazz.createField(varInfo.type, varInfo.name, varInfo.modifier);
        // TODO simplify it
        if (initExpr != null) {
            if (AstUtil.isStatic(fieldNode.modifier)) {
                thisClazz.staticInitStmts.add(new ExprStmt(new AssignExpr(new StaticFieldExpr(new ClassReference(thisClazz), fieldNode), initExpr)));
            } else {
                thisClazz.initStmts.add(new ExprStmt(new AssignExpr(new ObjectFieldExpr(new ThisExpr(getThisType()), fieldNode), initExpr)));
            }
        }
    }
    return null;
}
Also used : ExprNode(kalang.ast.ExprNode) StaticFieldExpr(kalang.ast.StaticFieldExpr) ObjectFieldExpr(kalang.ast.ObjectFieldExpr) FieldNode(kalang.ast.FieldNode) ExprStmt(kalang.ast.ExprStmt) ClassReference(kalang.ast.ClassReference) ThisExpr(kalang.ast.ThisExpr) VarDeclContext(kalang.antlr.KalangParser.VarDeclContext) LocalVarDeclContext(kalang.antlr.KalangParser.LocalVarDeclContext) AssignExpr(kalang.ast.AssignExpr)

Example 8 with AssignExpr

use of kalang.ast.AssignExpr 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)

Example 9 with AssignExpr

use of kalang.ast.AssignExpr in project kalang by kasonyang.

the class AstBuilder method createInitializedArray.

public ExprNode createInitializedArray(Type type, ExprNode[] exprs) {
    NewArrayExpr ae = new NewArrayExpr(type, new ConstExpr(exprs.length));
    if (exprs.length > 0) {
        Statement[] initStmts = new Statement[exprs.length + 2];
        // TODO create a method for temp var creation
        // TODO localVarNode should add a type parameter
        LocalVarNode local = this.declareTempLocalVar(ae.getType());
        initStmts[0] = new VarDeclStmt(local);
        VarExpr arrVar = new VarExpr(local);
        initStmts[1] = new ExprStmt(new AssignExpr(arrVar, ae));
        for (int i = 0; i < exprs.length; i++) {
            initStmts[i + 2] = new ExprStmt(new AssignExpr(new ElementExpr(arrVar, new ConstExpr(i)), exprs[i]));
        }
        return new MultiStmtExpr(Arrays.asList(initStmts), arrVar);
    } else {
        return ae;
    }
}
Also used : MultiStmtExpr(kalang.ast.MultiStmtExpr) ConstExpr(kalang.ast.ConstExpr) ExprStmt(kalang.ast.ExprStmt) NewArrayExpr(kalang.ast.NewArrayExpr) Statement(kalang.ast.Statement) VarDeclStmt(kalang.ast.VarDeclStmt) VarExpr(kalang.ast.VarExpr) LocalVarNode(kalang.ast.LocalVarNode) AssignExpr(kalang.ast.AssignExpr) ElementExpr(kalang.ast.ElementExpr)

Example 10 with AssignExpr

use of kalang.ast.AssignExpr in project kalang by kasonyang.

the class ClassNodeMetaBuilder method visitFieldDecl.

@Override
public Void visitFieldDecl(KalangParser.FieldDeclContext ctx) {
    int fieldModifier = astBuilder.parseModifier(ctx.varModifier());
    for (KalangParser.VarDeclContext vd : ctx.varDecl()) {
        ExprNode initExpr;
        if (vd.expression() != null) {
            initExpr = astBuilder.visitExpression(vd.expression());
        } else {
            initExpr = null;
        }
        AstBuilder.VarInfo varInfo = astBuilder.varDecl(vd, initExpr == null ? Types.getRootType() : initExpr.getType());
        varInfo.modifier |= fieldModifier;
        FieldNode fieldNode = thisClazz.createField(varInfo.type, varInfo.name, varInfo.modifier);
        // TODO simplify it
        if (initExpr != null) {
            if (AstUtil.isStatic(fieldNode.modifier)) {
                thisClazz.staticInitStmts.add(new ExprStmt(new AssignExpr(new StaticFieldExpr(new ClassReference(thisClazz), fieldNode), initExpr)));
            } else {
                thisClazz.initStmts.add(new ExprStmt(new AssignExpr(new ObjectFieldExpr(new ThisExpr(Types.getClassType(thisClazz)), fieldNode), initExpr)));
            }
        }
    }
    return null;
}
Also used : FieldNode(kalang.ast.FieldNode) AssignExpr(kalang.ast.AssignExpr) ExprNode(kalang.ast.ExprNode) StaticFieldExpr(kalang.ast.StaticFieldExpr) ObjectFieldExpr(kalang.ast.ObjectFieldExpr) KalangParser(kalang.antlr.KalangParser) ExprStmt(kalang.ast.ExprStmt) ClassReference(kalang.ast.ClassReference) ThisExpr(kalang.ast.ThisExpr)

Aggregations

AssignExpr (kalang.ast.AssignExpr)14 ExprNode (kalang.ast.ExprNode)12 ExprStmt (kalang.ast.ExprStmt)11 GenericType (kalang.core.GenericType)7 ObjectType (kalang.core.ObjectType)7 LocalVarNode (kalang.ast.LocalVarNode)6 VarDeclStmt (kalang.ast.VarDeclStmt)6 VarExpr (kalang.ast.VarExpr)6 ArrayType (kalang.core.ArrayType)6 ClassType (kalang.core.ClassType)6 PrimitiveType (kalang.core.PrimitiveType)6 Type (kalang.core.Type)6 WildcardType (kalang.core.WildcardType)6 ClassReference (kalang.ast.ClassReference)5 ConstExpr (kalang.ast.ConstExpr)5 ExpressionContext (kalang.antlr.KalangParser.ExpressionContext)4 BlockStmt (kalang.ast.BlockStmt)4 MultiStmtExpr (kalang.ast.MultiStmtExpr)4 Statement (kalang.ast.Statement)4 ThisExpr (kalang.ast.ThisExpr)4