Search in sources :

Example 11 with Type

use of kalang.core.Type 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 12 with Type

use of kalang.core.Type in project kalang by kasonyang.

the class AstBuilder method getObjectInvokeExpr.

@Nullable
private ExprNode getObjectInvokeExpr(ExprNode target, String methodName, ExprNode[] args, ParserRuleContext ctx) {
    if ("<init>".equals(methodName)) {
        throw Exceptions.unexceptedException("Don't get constructor by this method.");
    }
    Type targetType = target.getType();
    if (!(targetType instanceof ObjectType)) {
        handleSyntaxError("class type required.", ctx);
        return null;
    }
    ObjectType targetClassType = (ObjectType) targetType;
    if (targetClassType.getNullable() == NullableKind.NULLABLE) {
        handleSyntaxError("expression may be null", ctx);
        return null;
    }
    ExprNode expr;
    try {
        ObjectInvokeExpr invoke = ObjectInvokeExpr.create(target, methodName, args, thisClazz);
        if (invoke.getMethod().getMethodNode().getType() instanceof GenericType) {
            Type invokeType = invoke.getType();
            if (invokeType instanceof ObjectType) {
                expr = new CastExpr(invokeType, invoke);
            } else {
                expr = invoke;
            }
        } else {
            expr = invoke;
        }
    } catch (MethodNotFoundException ex) {
        methodNotFound(ctx.start, className, methodName, args);
        expr = new UnknownInvocationExpr(target, methodName, args);
    } catch (AmbiguousMethodException ex) {
        methodIsAmbiguous(ctx.start, ex);
        return null;
    }
    mapAst(expr, ctx);
    return expr;
}
Also used : ExprNode(kalang.ast.ExprNode) ObjectType(kalang.core.ObjectType) 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) GenericType(kalang.core.GenericType) ObjectInvokeExpr(kalang.ast.ObjectInvokeExpr) PrimitiveCastExpr(kalang.ast.PrimitiveCastExpr) CastExpr(kalang.ast.CastExpr) MethodNotFoundException(kalang.MethodNotFoundException) UnknownInvocationExpr(kalang.ast.UnknownInvocationExpr) AmbiguousMethodException(kalang.AmbiguousMethodException) Nullable(javax.annotation.Nullable)

Example 13 with Type

use of kalang.core.Type 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 14 with Type

use of kalang.core.Type in project kalang by kasonyang.

the class AstBuilder method visitIfStat.

@Override
public AstNode visitIfStat(IfStatContext ctx) {
    ExprNode expr = visitExpression(ctx.expression());
    if (expr == null) {
        return null;
    }
    Type exprType = expr.getType();
    expr = BoxUtil.assign(expr, expr.getType(), Types.BOOLEAN_TYPE);
    if (expr == null) {
        this.diagnosisReporter.report(Diagnosis.Kind.ERROR, exprType + " cannot be converted to boolean", ctx.expression());
        return null;
    }
    BlockStmt trueBody = null;
    BlockStmt falseBody = null;
    VarTable<VarObject, Integer> trueAssigned, falseAssigned;
    this.nullState = trueAssigned = this.nullState.newStack();
    newOverrideTypeStack();
    onIf(expr, true);
    if (ctx.trueStmt != null) {
        trueBody = requireBlock(ctx.trueStmt);
    }
    popOverrideTypeStack();
    this.nullState = this.nullState.popStack();
    boolean trueReturned = this.returned;
    this.returned = false;
    this.nullState = falseAssigned = this.nullState.newStack();
    newOverrideTypeStack();
    onIf(expr, false);
    if (ctx.falseStmt != null) {
        falseBody = requireBlock(ctx.falseStmt);
    }
    popOverrideTypeStack();
    this.nullState = this.nullState.popStack();
    handleMultiBranchedAssign(trueAssigned.vars(), falseAssigned.vars());
    boolean falseReturned = this.returned;
    if (trueReturned)
        onIf(expr, false);
    if (falseReturned)
        onIf(expr, true);
    this.returned = falseReturned && trueReturned;
    IfStmt ifStmt = new IfStmt(expr, trueBody, falseBody);
    mapAst(ifStmt, ctx);
    return ifStmt;
}
Also used : 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) IfStmt(kalang.ast.IfStmt) BlockStmt(kalang.ast.BlockStmt) VarObject(kalang.ast.VarObject)

Example 15 with Type

use of kalang.core.Type in project kalang by kasonyang.

the class AstBuilder method visitArrayExpr.

@Override
public Object visitArrayExpr(KalangParser.ArrayExprContext ctx) {
    ExprNode[] initExprs;
    List<ExpressionContext> exprCtx = ctx.expression();
    if (exprCtx != null) {
        initExprs = new ExprNode[exprCtx.size()];
        for (int i = 0; i < initExprs.length; i++) {
            initExprs[i] = visitExpression(exprCtx.get(i));
        }
    } else {
        initExprs = new ExprNode[0];
    }
    TypeContext typeCtx = ctx.type();
    Type type;
    if (typeCtx != null) {
        type = parseType(typeCtx);
    } else {
        type = TypeUtil.getCommonType(AstUtil.getExprTypes(initExprs));
    }
    for (int i = 0; i < initExprs.length; i++) {
        if (exprCtx == null)
            throw Exceptions.unexceptedValue(exprCtx);
        initExprs[i] = requireCastable(initExprs[i], initExprs[i].getType(), type, exprCtx.get(i).getStart());
        if (initExprs[i] == null)
            return null;
    }
    ExprNode arrExpr = createInitializedArray(type, initExprs);
    mapAst(arrExpr, ctx);
    return arrExpr;
}
Also used : 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) ExpressionContext(kalang.antlr.KalangParser.ExpressionContext) TypeContext(kalang.antlr.KalangParser.TypeContext)

Aggregations

ObjectType (kalang.core.ObjectType)44 Type (kalang.core.Type)44 ArrayType (kalang.core.ArrayType)37 ClassType (kalang.core.ClassType)36 GenericType (kalang.core.GenericType)36 PrimitiveType (kalang.core.PrimitiveType)33 WildcardType (kalang.core.WildcardType)30 ExprNode (kalang.ast.ExprNode)17 LinkedList (java.util.LinkedList)7 ExprStmt (kalang.ast.ExprStmt)7 VarExpr (kalang.ast.VarExpr)7 Nullable (javax.annotation.Nullable)6 AssignExpr (kalang.ast.AssignExpr)6 LocalVarNode (kalang.ast.LocalVarNode)6 BlockStmt (kalang.ast.BlockStmt)5 VarDeclStmt (kalang.ast.VarDeclStmt)5 AmbiguousMethodException (kalang.AmbiguousMethodException)4 MethodNotFoundException (kalang.MethodNotFoundException)4 ConstExpr (kalang.ast.ConstExpr)4 MethodNode (kalang.ast.MethodNode)4