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);
}
}
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;
}
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);
}
}
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;
}
}
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;
}
Aggregations