use of kalang.ast.ClassReference in project kalang by kasonyang.
the class AstBuilder method visitInstanceofExpr.
@Override
public Object visitInstanceofExpr(KalangParser.InstanceofExprContext ctx) {
ExprNode expr = visitExpression(ctx.expression());
Token ts = ctx.Identifier().getSymbol();
AstNode tnode = getNodeById(ts.getText(), ts);
if (tnode instanceof ClassReference) {
InstanceOfExpr ie = new InstanceOfExpr(expr, (ClassReference) tnode);
mapAst(ie, ctx);
return ie;
} else {
AstBuilder.this.handleSyntaxError("unsupported type", ts);
return null;
}
}
use of kalang.ast.ClassReference in project kalang by kasonyang.
the class AstBuilder method getNodeById.
@Nullable
private AstNode getNodeById(@Nonnull String name, @Nullable Token token) {
// find local var
LocalVarNode var = this.getNamedLocalVar(name);
if (var != null) {
VarExpr ve = new VarExpr(var, getVarObjectType(var));
if (token != null)
mapAst(ve, token);
return ve;
}
// find parameters
ParameterNode paramNode = this.getNamedParameter(name);
if (paramNode != null) {
ParameterExpr ve = new ParameterExpr(paramNode, this.getVarObjectType(paramNode));
if (token != null)
mapAst(ve, token);
return ve;
}
// find field
ExprNode fieldExpr = this.getObjectFieldExpr(new ThisExpr(this.getThisType()), name, ParserRuleContext.EMPTY);
if (fieldExpr == null)
fieldExpr = this.getStaticFieldExpr(new ClassReference(thisClazz), name, ParserRuleContext.EMPTY);
if (fieldExpr != null)
return fieldExpr;
ExprNode outerClassInstanceExpr = this.getOuterClassInstanceExpr(new ThisExpr(this.getThisType()));
while (outerClassInstanceExpr != null) {
ExprNode fe = this.getObjectFieldExpr(outerClassInstanceExpr, name, ParserRuleContext.EMPTY);
if (fe == null)
fe = this.getStaticFieldExpr(new ClassReference(thisClazz), name, ParserRuleContext.EMPTY);
if (fe != null)
return fe;
outerClassInstanceExpr = this.getOuterClassInstanceExpr(outerClassInstanceExpr);
}
String resolvedTypeName = this.typeNameResolver.resolve(name, topClass, thisClazz);
if (resolvedTypeName != null) {
ClassReference clsRef = new ClassReference(requireAst(resolvedTypeName, token));
if (token != null)
mapAst(clsRef, token);
return clsRef;
}
return null;
}
use of kalang.ast.ClassReference in project kalang by kasonyang.
the class AstBuilder method parseLiteral.
public ConstExpr parseLiteral(LiteralContext ctx, @Nullable Type exceptedType) {
String t = ctx.getText();
Object v;
if (ctx.IntegerLiteral() != null) {
// NOTE should show tip for autocast?
if (t.toUpperCase().endsWith("L")) {
t = t.substring(0, t.length() - 1);
exceptedType = Types.LONG_TYPE;
} else if (t.toLowerCase().endsWith("i")) {
t = t.substring(0, t.length() - 1);
exceptedType = Types.INT_TYPE;
}
long longValue;
try {
longValue = (int) StringLiteralUtil.parseLong(t);
} catch (NumberFormatException ex) {
this.handleSyntaxError("invalid number", ctx);
return null;
}
if (Types.BYTE_TYPE.equals(exceptedType)) {
// TODO check range
v = (byte) longValue;
} else if (Types.LONG_TYPE.equals(exceptedType)) {
v = longValue;
} else {
// TODO check range
v = (int) longValue;
}
} else if (ctx.FloatingPointLiteral() != null) {
double doubleValue;
try {
doubleValue = Double.parseDouble(t);
} catch (NumberFormatException ex) {
this.handleSyntaxError("invalid float value", ctx);
return null;
}
if (Types.FLOAT_TYPE.equals(exceptedType)) {
v = (float) doubleValue;
} else {
v = doubleValue;
}
} else if (ctx.BooleanLiteral() != null) {
v = (Boolean.parseBoolean(t));
} else if (ctx.CharacterLiteral() != null) {
char[] chars = t.toCharArray();
v = (chars[1]);
} else if (ctx.StringLiteral() != null) {
v = (StringLiteralUtil.parse(t.substring(1, t.length() - 1)));
} else if (ctx.MultiLineStringLiteral() != null) {
v = StringLiteralUtil.parse(t.substring(3, t.length() - 3));
} else if (ctx.Identifier() != null) {
ClassReference cr = requireClassReference(ctx.Identifier().getSymbol());
v = (cr);
} else if (ctx.getText().equals("null")) {
v = null;
} else {
throw Exceptions.unexceptedValue(ctx.getText());
}
ConstExpr ce = new ConstExpr(v);
mapAst(ce, ctx);
return ce;
}
use of kalang.ast.ClassReference 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.ClassReference 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;
}
Aggregations