use of kalang.ast.ExprNode in project kalang by kasonyang.
the class AstBuilder method visitForStat.
@Override
public AstNode visitForStat(ForStatContext ctx) {
// TODO It seems that here lacks of var stack
BlockStmt forStmt = newBlock();
if (ctx.localVarDecl() != null) {
Statement vars = visitLocalVarDecl(ctx.localVarDecl());
forStmt.statements.add(vars);
}
if (ctx.initExpressions != null) {
forStmt.statements.addAll(visitExpressions(ctx.initExpressions));
}
ExprNode preConditionExpr = ctx.condition != null ? visitExpression(ctx.condition) : null;
BlockStmt bs = newBlock();
if (ctx.stat() != null) {
Statement st = visitStat(ctx.stat());
if (st instanceof BlockStmt) {
bs.statements.addAll(((BlockStmt) st).statements);
}
}
popBlock();
BlockStmt updateBs = newBlock();
if (ctx.updateExpressions != null) {
updateBs.statements.addAll(visitExpressions(ctx.updateExpressions));
}
popBlock();
LoopStmt ls = new LoopStmt(preConditionExpr, null, bs, updateBs);
mapAst(ls, ctx);
forStmt.statements.add(ls);
popBlock();
return forStmt;
}
use of kalang.ast.ExprNode 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);
}
}
use of kalang.ast.ExprNode 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;
}
use of kalang.ast.ExprNode 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;
}
use of kalang.ast.ExprNode in project kalang by kasonyang.
the class AstBuilder method getImplicitInvokeExpr.
@Nullable
private ExprNode getImplicitInvokeExpr(String methodName, ExprNode[] args, ParserRuleContext ctx) {
ExprNode expr = null;
try {
ObjectType clazzType = getThisType();
InvocationExpr.MethodSelection ms = InvocationExpr.applyMethod(clazzType, methodName, args, clazzType.getMethodDescriptors(thisClazz, true, true));
if (Modifier.isStatic(ms.selectedMethod.getModifier())) {
expr = new StaticInvokeExpr(new ClassReference(thisClazz), ms.selectedMethod, ms.appliedArguments);
} else {
expr = new ObjectInvokeExpr(new ThisExpr(getThisType()), ms.selectedMethod, ms.appliedArguments);
}
} catch (MethodNotFoundException ex) {
if (args.length == 1 && (methodName.equals("print") || methodName.equals("println"))) {
try {
StaticFieldExpr fieldExpr = StaticFieldExpr.create(new ClassReference(Types.requireClassType("java.lang.System").getClassNode()), "out", null);
expr = getObjectInvokeExpr(fieldExpr, methodName, args, ctx);
} catch (FieldNotFoundException fnfEx) {
throw Exceptions.unexceptedException(fnfEx);
}
}
if (expr == null) {
this.methodNotFound(ctx.getStart(), className, methodName, args);
expr = new UnknownInvocationExpr(null, methodName, args);
}
} catch (AmbiguousMethodException ex) {
methodIsAmbiguous(ctx.start, ex);
return null;
}
mapAst(expr, ctx);
return expr;
}
Aggregations