use of kalang.ast.IfStmt in project kalang by kasonyang.
the class AstBuilder method visitPostIfStmt.
@Override
public AstNode visitPostIfStmt(KalangParser.PostIfStmtContext ctx) {
ExprNode leftExpr = visitExpression(ctx.expression(0));
if (!(leftExpr instanceof AssignExpr)) {
diagnosisReporter.report(Diagnosis.Kind.ERROR, "AssignExpr required", ctx);
}
AssignExpr assignExpr = (AssignExpr) leftExpr;
AssignableExpr to = assignExpr.getTo();
ExprNode from = assignExpr.getFrom();
ExprNode cond = visitExpression(ctx.expression(1));
Token op = ctx.op;
if (op != null) {
String opStr = op.getText();
BinaryExpr be = createBinaryExpr(to, cond, opStr);
cond = be;
}
AssignExpr as = new AssignExpr(to, from);
IfStmt is = new IfStmt(cond);
is.getTrueBody().statements.add(new ExprStmt(as));
mapAst(is, ctx);
return is;
}
use of kalang.ast.IfStmt 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.IfStmt in project kalang by kasonyang.
the class AstBuilder method visitQuestionExpr.
@Override
public AstNode visitQuestionExpr(KalangParser.QuestionExprContext ctx) {
List<Statement> stmts = new LinkedList<>();
ExprNode conditionExpr = (ExprNode) visit(ctx.expression(0));
ExprNode trueExpr = (ExprNode) visit(ctx.expression(1));
ExprNode falseExpr = (ExprNode) visit(ctx.expression(2));
Type trueType = trueExpr.getType();
Type falseType = falseExpr.getType();
Type type;
if (trueType.equals(falseType)) {
type = trueType;
} else {
type = TypeUtil.getCommonType(trueType, falseType);
}
LocalVarNode vo = this.declareTempLocalVar(type);
VarDeclStmt vds = new VarDeclStmt(vo);
stmts.add(vds);
VarExpr ve = new VarExpr(vo);
IfStmt is = new IfStmt(conditionExpr);
is.getTrueBody().statements.add(new ExprStmt(new AssignExpr(ve, trueExpr)));
is.getFalseBody().statements.add(new ExprStmt(new AssignExpr(ve, falseExpr)));
stmts.add(is);
MultiStmtExpr mse = new MultiStmtExpr(stmts, ve);
mapAst(ve, ctx);
return mse;
}
use of kalang.ast.IfStmt in project kalang by kasonyang.
the class AstBuilder method visitAssertStmt.
@Override
public Object visitAssertStmt(KalangParser.AssertStmtContext ctx) {
ExprNode failExpr = visitExpression(ctx.testCondition);
if (failExpr == null)
return null;
failExpr = BoxUtil.assign(failExpr, failExpr.getType(), Types.BOOLEAN_TYPE);
if (failExpr == null) {
this.diagnosisReporter.report(Diagnosis.Kind.ERROR, "boolean type expected", ctx.testCondition);
return null;
}
failExpr = new UnaryExpr(failExpr, UnaryExpr.OPERATION_LOGIC_NOT);
ExprNode failMsgExpr = null;
if (ctx.failMessage != null) {
failMsgExpr = visitExpression(ctx.failMessage);
if (failMsgExpr == null)
return null;
if (Types.VOID_TYPE.equals(failMsgExpr.getType())) {
this.diagnosisReporter.report(Diagnosis.Kind.ERROR, "non-void type expected", ctx.failMessage);
return null;
}
}
BlockStmt body = this.newBlock();
NewObjectExpr newErrorExpr;
try {
newErrorExpr = new NewObjectExpr(Types.requireAssertionErrorClassType(), failMsgExpr != null ? new ExprNode[] { failMsgExpr } : new ExprNode[0]);
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
throw Exceptions.unexceptedException(ex);
}
body.statements.add(new ThrowStmt(newErrorExpr));
popBlock();
return new IfStmt(failExpr, body, null);
}
Aggregations