use of kalang.ast.LoopStmt in project kalang by kasonyang.
the class AstBuilder method visitWhileStat.
@Override
public AstNode visitWhileStat(WhileStatContext ctx) {
ExprNode preConditionExpr = visitExpression(ctx.expression());
BlockStmt loopBody = null;
if (ctx.stat() != null) {
loopBody = requireBlock(ctx.stat());
}
LoopStmt ws = new LoopStmt(preConditionExpr, null, loopBody, null);
mapAst(ws, ctx);
return ws;
}
use of kalang.ast.LoopStmt in project kalang by kasonyang.
the class AstBuilder method visitDoWhileStat.
@Override
public AstNode visitDoWhileStat(DoWhileStatContext ctx) {
BlockStmt loopBody = null;
if (ctx.blockStmt() != null) {
loopBody = requireBlock(ctx.blockStmt());
}
ExprNode postConditionExpr = visitExpression(ctx.expression());
LoopStmt ls = new LoopStmt(null, postConditionExpr, loopBody, null);
mapAst(ls, ctx);
return ls;
}
use of kalang.ast.LoopStmt 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.LoopStmt 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.LoopStmt in project kalang by kasonyang.
the class AstBuilder method visitForEachStat.
@Override
public Object visitForEachStat(KalangParser.ForEachStatContext ctx) {
BlockStmt block = newBlock();
ExprNode expr = this.visitExpression(ctx.expression());
Type exprType = expr.getType();
List<TerminalNode> idsCtx = ctx.Identifier();
VarExpr indexVarExpr = null;
TerminalNode varId;
if (idsCtx.size() == 1) {
varId = idsCtx.get(0);
} else {
TerminalNode indexId = idsCtx.get(0);
LocalVarNode indexVar = this.declareLocalVar(indexId.getText(), Types.INT_TYPE, Modifier.FINAL, ctx);
if (indexVar == null)
return null;
block.statements.add(new VarDeclStmt(indexVar));
indexVarExpr = new VarExpr(indexVar);
varId = idsCtx.get(1);
}
LoopStmt loopStmt;
if (exprType instanceof ArrayType) {
LocalVarNode localVarNode = this.declareLocalVar(varId.getText(), ((ArrayType) exprType).getComponentType(), Modifier.FINAL, ctx);
if (localVarNode == null)
return null;
VarExpr localVariable = new VarExpr(localVarNode);
block.statements.add(new VarDeclStmt(localVarNode));
LocalVarNode lenVar = this.declareTempLocalVar(Types.INT_TYPE);
LocalVarNode counterVar = this.declareTempLocalVar(Types.INT_TYPE);
// var len
block.statements.add(new VarDeclStmt(lenVar));
// var i
block.statements.add(new VarDeclStmt(counterVar));
VarExpr counterVarExpr = new VarExpr(counterVar);
VarExpr lenVarExpr = new VarExpr(lenVar);
block.statements.add(new ExprStmt(new AssignExpr(lenVarExpr, new ArrayLengthExpr(expr))));
// l = array.length
block.statements.add(new ExprStmt(new AssignExpr(counterVarExpr, new ConstExpr(0))));
// i=0
ExprNode cnd = new CompareExpr(counterVarExpr, lenVarExpr, CompareExpr.OP_LT);
BlockStmt loopBody = this.newBlock();
loopBody.statements.add(new ExprStmt(new AssignExpr(localVariable, new ElementExpr(expr, counterVarExpr))));
if (indexVarExpr != null) {
loopBody.statements.add(new ExprStmt(new AssignExpr(indexVarExpr, counterVarExpr)));
}
loopBody.statements.add(visitStat(ctx.stat()));
popBlock();
BlockStmt updateBs = newBlock();
// increment counter
updateBs.statements.add(new ExprStmt(new AssignExpr(counterVarExpr, new MathExpr(counterVarExpr, new ConstExpr(1), MathExpr.OP_ADD))));
popBlock();
loopStmt = new LoopStmt(cnd, null, loopBody, updateBs);
} else {
ObjectType iterType = Types.getIterableClassType();
if (iterType.isAssignableFrom(exprType)) {
ObjectInvokeExpr getIterableExpr;
try {
getIterableExpr = ObjectInvokeExpr.create(expr, "iterator", null);
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
throw Exceptions.unexceptedException(ex);
}
LocalVarNode iterableVarNode = this.declareTempLocalVar(getIterableExpr.getType());
block.statements.add(new VarDeclStmt(iterableVarNode));
VarExpr iterableVarExpr = new VarExpr(iterableVarNode);
block.statements.add(new ExprStmt(new AssignExpr(iterableVarExpr, getIterableExpr)));
// set index = 0
if (indexVarExpr != null) {
block.statements.add(new ExprStmt(new AssignExpr(indexVarExpr, new ConstExpr(0))));
}
ObjectInvokeExpr cnd;
try {
cnd = ObjectInvokeExpr.create(iterableVarExpr, "hasNext", null);
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
throw Exceptions.unexceptedException(ex);
}
BlockStmt loopBody = this.newBlock();
ObjectInvokeExpr nextInvokeExpr;
try {
nextInvokeExpr = ObjectInvokeExpr.create(iterableVarExpr, "next", null);
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
throw Exceptions.unexceptedException(ex);
}
LocalVarNode localVarNode = this.declareLocalVar(varId.getText(), nextInvokeExpr.getType(), Modifier.FINAL, ctx);
if (localVarNode == null)
return null;
VarExpr localVariable = new VarExpr(localVarNode);
loopBody.statements.add(new VarDeclStmt(localVarNode));
loopBody.statements.add(new ExprStmt(new AssignExpr(localVariable, new CastExpr(localVariable.getType(), nextInvokeExpr))));
loopBody.statements.add(visitStat(ctx.stat()));
popBlock();
BlockStmt updateBs = newBlock();
if (indexVarExpr != null) {
// do index++
updateBs.statements.add(new ExprStmt(new AssignExpr(indexVarExpr, new MathExpr(indexVarExpr, new ConstExpr(1), BinaryExpr.OP_ADD))));
}
popBlock();
loopStmt = new LoopStmt(cnd, null, loopBody, updateBs);
} else {
this.handleSyntaxError("require array type or iterable type", ctx.expression());
loopStmt = null;
}
}
popBlock();
if (loopStmt != null)
block.statements.add(loopStmt);
return block;
}
Aggregations