public static class SDeclare extends Statement {
final DType type;
- final String name;
- final Optional<Expression> value;
+ final List<DInitialiser> list;
- public SDeclare(int lineNo, DType type, String id, Optional<Expression> value) {
+ public SDeclare(int lineNo, DType type, List<DInitialiser> list) {
super(lineNo);
this.type = type;
- this.name = id;
- this.value = value;
+ this.list = list;
}
@Override
@Override
public void visitChildren(ASTVisitor av) {
- value.ifPresent(x -> x.accept(av));
+ accept(list, av);
}
}
public static class SAssign extends Statement {
- final XReference ref;
+ final Expression ref;
final Expression value;
- public SAssign(int lineNo, AST.XReference ref, AST.Expression value) {
+ public SAssign(int lineNo, AST.Expression ref, AST.Expression value) {
super(lineNo);
this.ref = ref;
this.value = value;
/* **** metadata */
public static class DType extends AST {
final XType type;
- final Optional<XReference> typeName;
+ final Optional<XReference> name;
+
+ public DType(int lineNo, XType type, Optional<XReference> name) {
+ super(lineNo);
+ this.type = type;
+ this.name = name;
+ }
+
+ @Override
+ public void accept(ASTVisitor av) {
+ av.visit(this);
+ }
+
+ @Override
+ public String toString() {
+ return name.orElse(new XReference(lineNo, type.name())).name();
+ }
+ }
+
+ public static class DInitialiser extends AST {
+ final String name;
+ final Optional<Expression> value;
+
+ public DInitialiser(int lineNo, String name, Optional<Expression> value) {
+ super(lineNo);
+ this.name = name;
+ this.value = value;
+ }
+
+ @Override
+ public void accept(ASTVisitor av) {
+ av.visit(this);
+ }
+
+ @Override
+ public void visitChildren(ASTVisitor av) {
+ value.ifPresent(x -> x.accept(av));
+ }
- public DType(int lineNo, XType type, Optional<XReference> typeName) {
+ @Override
+ public String toString() {
+ return name + (value.isPresent() ? (" = " + value.get().toString()) : "");
+ }
+ }
+
+ public static class DParameter extends AST {
+ DType type;
+ DInitialiser param;
+
+ public DParameter(int lineNo, DType type, DInitialiser param) {
super(lineNo);
this.type = type;
- this.typeName = typeName;
+ this.param = param;
}
@Override
av.visit(this);
}
+ @Override
+ public void visitChildren(ASTVisitor av) {
+ type.accept(av);
+ param.accept(av);
+ }
+
@Override
public String toString() {
- return typeName.orElse(new XReference(lineNo, type.name())).name();
+ return type.toString() + " " + param.toString();
}
}
}
}
+ public static class XField extends Expression {
+ Expression ref;
+ String field;
+
+ public XField(int lineNo, Expression ref, String field) {
+ super(lineNo);
+ this.ref = ref;
+ this.field = field;
+ }
+
+ @Override
+ public void accept(ASTVisitor av) {
+ av.visit(this);
+ }
+
+ @Override
+ public void visitChildren(ASTVisitor av) {
+ ref.accept(av);
+ }
+ }
+
public static class XCall extends Expression {
boolean constructor;
- XReference ref;
- List<Expression> params;
+ Optional<Expression> ref;
+ String name;
+ List<Expression> args;
- public XCall(int lineNo, boolean constructor, XReference ref, List<Expression> params) {
+ public XCall(int lineNo, boolean constructor, Optional<Expression> ref, String name, List<Expression> args) {
super(lineNo);
this.constructor = constructor;
this.ref = ref;
- this.params = params;
-
- System.out.printf("call: %s%s ", constructor ? "new " : "", ref.name());
- params.forEach(p -> System.out.printf(" %s", p));
- System.out.println();
+ this.name = name;
+ this.args = args;
}
@Override
@Override
public void visitChildren(ASTVisitor av) {
- ref.accept(av);
- accept(params, av);
+ ref.ifPresent(r -> r.accept(av));
+ accept(args, av);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[call ");
sb.append(ref);
- sb.append(" ");
- sb.append(String.join(", ", params.stream().map(x -> x.toString()).toArray(String[]::new)));
- sb.append("]");
+ sb.append("(");
+ sb.append(String.join(", ", args.stream().map(x -> x.toString()).toArray(String[]::new)));
+ sb.append(")]");
return sb.toString();
}
}
- // return type?
+ // how do i know the return type?
public static class XFunction extends Expression {
final DType rval;
- final List<DType> types;
- final List<String> params;
+ final List<DParameter> params;
final Statements statements;
- public XFunction(int lineNo, DType rval, List<DType> types, List<String> params, Statements statements) {
+ public XFunction(int lineNo, DType rval, List<DParameter> params, Statements statements) {
super(lineNo);
- this.params = params;
this.rval = rval;
- this.types = types;
+ this.params = params;
this.statements = statements;
}
@Override
public AST.Statements visitStatements(StatementsContext ctx) {
- return new AST.Statements(ctx.start.getLine(), ctx.statement().stream().map(this::visitStatement).toList());
+ return ctx != null
+ ? new AST.Statements(ctx.start.getLine(), ctx.statement().stream().map(this::visitStatement).toList())
+ : new AST.Statements(0, List.of());
}
public AST.Statement visitStatement(StatementContext ctx) {
return label != null ? Optional.of(label.getText()) : Optional.empty();
}
+ Optional<Expression> expression(ValueExprContext expr) {
+ return expr != null ? Optional.of(visitValueExpr(expr)) : Optional.empty();
+ }
+
@Override
public AST.SIf visitIfStatement(IfStatementContext ctx) {
ValueExprContext valX = ctx.valueExpr();
type == XType.OBJECT ? Optional.of(visitReference(ctx.reference())) : Optional.empty());
}
+ List<DInitialiser> visitInitialisers(DeclExprContext ctx, List<DInitialiser> list) {
+ if (ctx.declExpr() != null)
+ list = visitInitialisers(ctx.declExpr(), list);
+ list.add(new DInitialiser(ctx.id.getLine(), ctx.id.getText(), expression(ctx.val)));
+ return list;
+ }
+
@Override
public AST visitDeclStatement(DeclStatementContext ctx) {
- System.out.printf("type\n");
- Compiler.dump("", ctx.type());
- if (ctx.valueExpr() == null) {
- return new SDeclare(
- ctx.start.getLine(),
- visitType(ctx.type()),
- ctx.ID().getText(),
- Optional.empty());
- } else {
- return new SDeclare(
- ctx.start.getLine(),
- visitType(ctx.type()),
- ctx.ID().getText(),
- Optional.of(visitValueExpr(ctx.valueExpr())));
- }
+ return new SDeclare(
+ ctx.start.getLine(),
+ visitType(ctx.type()),
+ visitInitialisers(ctx.declExpr(), new ArrayList<>()));
}
@Override
public AST.SAssign visitAssignStatement(AssignStatementContext ctx) {
- return new AST.SAssign(ctx.start.getLine(), visitReference(ctx.reference()), visitValueExpr(ctx.valueExpr()));
+ return new AST.SAssign(ctx.start.getLine(), visitValueExpr(ctx.valueExpr(0)), visitValueExpr(ctx.valueExpr(1)));
}
public AST.Expression visitValueExpr(ValueExprContext ctx) {
@Override
public AST visitCallStatement(CallStatementContext ctx) {
- return new SCall(ctx.start.getLine(), visitCallExpr(ctx.callExpr()));
+ return new SCall(ctx.start.getLine(),
+ new XCall(
+ ctx.start.getLine(),
+ false,
+ expression(ctx.left),
+ ctx.ID().getText(),
+ ctx.args.valueExpr().stream().map(v -> (AST.Expression)v.accept(this)).toList()));
+ }
+
+ List<DParameter> visitParams(ParamExprContext ctx, List<DParameter> list) {
+ if (ctx.paramExpr() != null)
+ list = visitParams(ctx.paramExpr(), list);
+ list.add(new DParameter(ctx.id.getLine(), visitType(ctx.type()), new DInitialiser(ctx.id.getLine(), ctx.id.getText(), expression(ctx.val))));
+ return list;
}
@Override
return new XFunction(
ctx.start.getLine(),
visitType(ctx.rval),
- ctx.type().stream().map(a -> visitType(a)).toList(),
- ctx.ID().stream().map(a -> a.getText()).toList(),
+ visitParams(ctx.paramExpr(), new ArrayList<>()),
ctx.statements() != null
? visitStatements(ctx.statements())
: AST.Statements.EMPTY
);
}
- @Override
- public AST.XCall visitCallExpr(CallExprContext ctx) {
- return new XCall(
- ctx.start.getLine(),
- ctx.NEW() != null,
- visitReference(ctx.reference()),
- ctx.valueExpr().stream().map(v -> (AST.Expression)v.accept(this)).toList());
- }
-
private SBreakType breakType(Token tok) {
switch (tok.getType()) {
case BREAK:
return visitValueExpr(ctx.valueExpr());
}
+ @Override
+ public AST.XField visitValueFieldExpr(ValueFieldExprContext ctx) {
+ return new AST.XField(
+ ctx.start.getLine(),
+ visitValueExpr(ctx.left),
+ ctx.ID().getText());
+ }
+
+ @Override
+ public AST visitValueCallExpr(ValueCallExprContext ctx) {
+ return new XCall(
+ ctx.start.getLine(),
+ false,
+ expression(ctx.left),
+ ctx.ID().getText(),
+ ctx.args.valueExpr().stream().map(v -> (AST.Expression)v.accept(this)).toList());
+ }
+
+ @Override
+ public AST visitValueNewExpr(ValueNewExprContext ctx) {
+ return new XCall(
+ ctx.start.getLine(),
+ true,
+ Optional.of(visitReference(ctx.ref)),
+ "<init>",
+ ctx.args.valueExpr().stream().map(v -> (AST.Expression)v.accept(this)).toList());
+ }
+
XUnaryOp valueUnaryOp(Token op) {
switch (op.getType()) {
case ADD:
return new AST.XUnary(
ctx.start.getLine(),
valueUnaryOp(ctx.op),
- (Expression)visit(ctx.rightValue));
+ (Expression)visit(ctx.right));
}
XBinaryOp valueBinaryOp(Token op) {
XBinary xb = new XBinary(
ctx.op.getLine(),
valueBinaryOp(ctx.op),
- (Expression)visit(ctx.leftValue),
- (Expression)visit(ctx.rightValue));
+ (Expression)visit(ctx.left),
+ (Expression)visit(ctx.right));
System.out.printf("visit binary %s %s %s\n", xb.left, xb.op, xb.right);
return new XBinary(
ctx.op.getLine(),
valueBinaryOp(ctx.op),
- (Expression)visit(ctx.leftValue),
- (Expression)visit(ctx.rightValue));
+ (Expression)visit(ctx.left),
+ (Expression)visit(ctx.right));
}
@Override
switch (ctx.start.getType()) {
case INTEGER: {
try {
- if (ctx.size != null && ctx.size.getText().equals("L"))
- return new XLong(ctx.start.getLine(), Long.parseLong(ctx.start.getText()));
+ String txt = ctx.start.getText();
+ //if (ctx.size != null && ctx.size.getText().equals("L"))
+ if (txt.endsWith("L"))
+ return new XLong(ctx.start.getLine(), Long.parseLong(txt.substring(0, txt.length() - 1)));
else
- return new XInteger(ctx.start.getLine(), Integer.parseInt(ctx.start.getText()));
+ return new XInteger(ctx.start.getLine(), Integer.parseInt(txt));
} catch (NumberFormatException x) {
errors.add("Invalid INTEGER: " + ctx.start.getText());
return new XInteger(ctx.start.getLine(), Integer.MAX_VALUE);
}
case FLOAT: {
try {
- if (ctx.size != null && ctx.size.getText().equals("f"))
- return new XFloat(ctx.start.getLine(), Float.parseFloat(ctx.start.getText()));
+ String txt = ctx.start.getText();
+ //if (ctx.size != null && ctx.size.getText().equals("f"))
+ if (txt.endsWith("f"))
+ return new XFloat(ctx.start.getLine(), Float.parseFloat(txt));
else
- return new XDouble(ctx.start.getLine(), Double.parseDouble(ctx.start.getText()));
+ return new XDouble(ctx.start.getLine(), Double.parseDouble(txt));
} catch (NumberFormatException x) {
errors.add("Invalid REAL: " + ctx.start.getText());
return new XFloat(ctx.start.getLine(), Float.NaN);
@Override
public void visitDecl(AST.SDeclare s) {
- String type = s.type.typeName.orElse(new AST.XReference(s.lineNo, s.type.type.name())).name();
- s.value.ifPresentOrElse(
- v -> {
- System.out.printf("%s%s %s = ", d, type, s.name);
- v.accept(this);
- System.out.println();
- },
- ()
- -> System.out.printf("%s%s %s\n", d, type, s.name));
+ String type = s.type.name.orElse(new AST.XReference(s.lineNo, s.type.type.name())).name();
+
+ System.out.print(d);
+ System.out.print(type);
+
+ for (int i = 0; i < s.list.size(); i++) {
+ var v = s.list.get(i);
+
+ if (i != 0)
+ System.out.print(", ");
+
+ System.out.print(v.name);
+ v.value.ifPresent(x -> x.accept(this));
+ }
+ System.out.println();
}
@Override
public void visitAssign(AST.SAssign s) {
- System.out.printf("%s%s = ", d, s.ref.name());
+ System.out.print(d);
+ s.ref.accept(this);
+ System.out.print(" = ");
s.value.accept(this);
System.out.println();
}
}
@Override
- public void visit(AST.XCall e) {
+ public void visit(AST.XField e) {
e.ref.accept(this);
+ System.out.print("[" + e.ref.getClass().getSimpleName() + "]");
+ System.out.println();
+ System.out.print(d);
+ System.out.print(".[!");
+ System.out.print(e.field);
+ System.out.print("]");
+ }
+
+ @Override
+ public void visit(AST.XCall e) {
+ e.ref.ifPresent(x -> {
+ System.out.print("{");
+ x.accept(this);
+ System.out.print("}.");
+ });
+ System.out.print(e.name);
System.out.print("(");
- Iterator<AST.Expression> it = e.params.iterator();
+ Iterator<AST.Expression> it = e.args.iterator();
if (it.hasNext())
it.next().accept(this);
while (it.hasNext()) {
@Override
public void visit(AST.XFunction e) {
System.out.print("function (");
- Iterator<String> ip = e.params.iterator();
- Iterator<AST.DType> it = e.types.iterator();
+ Iterator<AST.DParameter> ip = e.params.iterator();
if (ip.hasNext()) {
- System.out.print(it.next().toString());
+ AST.DParameter p = ip.next();
+ System.out.print(p.type.toString());
System.out.print(" ");
- System.out.print(ip.next());
+ System.out.print(p.param.toString());
}
while (ip.hasNext()) {
+ AST.DParameter p = ip.next();
System.out.print(", ");
- System.out.print(it.next().toString());
+ System.out.print(p.type.toString());
System.out.print(" ");
- System.out.print(ip.next());
+ System.out.print(p.param.toString());
}
System.out.print(") = {\n");
down();
@Override
public void visit(AST.XReference e) {
+ System.out.print("<");
System.out.print(e.name());
+ System.out.print(">");
}
@Override
public default void visit(DType d) {
}
+ public default void visit(DInitialiser d) {
+ }
+
+ public default void visit(DParameter d) {
+ }
+
// expressions
public default void visit(Expression e) {
e.visitChildren(this);
e.visitChildren(this);
}
+ public default void visit(XField e) {
+ e.visitChildren(this);
+ }
+
public default void visit(XCall e) {
e.visitChildren(this);
}
AST.ScriptA script = new ASTBuilder().visitScript(cst);
+ System.out.println("printed -->");
new ASTPrinter().visitScript(script);
Generator gen = new Generator(name);
gen.visitScript(script);
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.function.Consumer;
import org.objectweb.asm.ClassWriter;
*
*/
public class Generator implements ASTVisitor {
- boolean valid = true;
+ boolean valid = false;
ClassWriter cw;
MethodVisitor mw;
int variableID = 1;
return this;
} else {
switch (type.getSort()) {
+ case Type.BOOLEAN:
+ return then(mv -> mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "toString", "(Z)Ljava/lang/String;", false));
case Type.INT:
return then(mv -> mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "toString", "(I)Ljava/lang/String;", false));
case Type.LONG:
case Type.FLOAT:
return then(mv -> mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "toString", "(F)Ljava/lang/String;", false));
case Type.DOUBLE:
- return then(mv -> mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "toString", "(Z)Ljava/lang/String;", false));
+ return then(mv -> mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "toString", "(D)Ljava/lang/String;", false));
case Type.OBJECT:
default:
return then(mv -> mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "(Ljava/lang/Object;)Ljava/lang/String;", false));
public Generator(String file) {
this.file = file;
+ imports.importClass(String.class, f -> false, m -> true);
imports.importClass(System.class, f -> f.getName().matches("out|error"), m -> false);
- imports.importClass(PrintStream.class, f -> false, m -> m.getName().matches("^print.*"));
+ imports.importClass(PrintStream.class, f -> false, m -> m.getName().matches("^(print|append).*"));
imports.importClass(Math.class, f -> true, m -> true);
List<Imports.Import> list = imports.importInstance[Imports.IMPORT_METHODS].getOrDefault(Type.getType(PrintStream.class), Map.of()).entrySet().stream()
.filter(e -> e.getKey().matches("^print.*"))
mv.visitMethodInsn(INVOKEVIRTUAL, m.recv().getInternalName(), m.name(), m.type().getDescriptor(), false);
}));
}
+
}
@Override
@Override
public void visitDecl(AST.SDeclare s) {
- System.out.printf("define var %s%s\n", d, s.name);
- Variable var;
- Optional<Value> val;
+ for (AST.DInitialiser i: s.list) {
+ System.out.printf("define var %s%s\n", d, i.name);
+ Variable var;
+ Optional<Value> val;
- if (variables.containsKey(s.name)) {
- throw new java.lang.IllegalArgumentException(s.lineNo + ": Variable redefined: " + s.name);
- }
+ if (variables.containsKey(i.name)) {
+ throw new java.lang.IllegalArgumentException(s.lineNo + ": Variable redefined: " + i.name);
+ }
- val = s.value.map(x -> visitExpression(x));
+ val = i.value.map(x -> visitExpression(x));
- if (s.type.type == AST.XType.OBJECT) {
- var = addVariable(s.name, Type.getObjectType(s.type.typeName.get().name()));
- val.ifPresent(v -> {
- v.insert.accept(mw);
- mw.visitVarInsn(ASTORE, var.id);
- });
- } else {
- var = addVariable(s.name, typeMap[s.type.type.ordinal()]);
- val = val.map(v -> v.promote(var.type));
- System.out.printf(" var: %s = %s\n", var, val);
- val.ifPresent(v -> {
- v.insert.accept(mw);
- mw.visitVarInsn(var.type().getOpcode(ISTORE), var.id);
- });
+ if (s.type.type == AST.XType.OBJECT) {
+ var = addVariable(i.name, Type.getObjectType(s.type.name.get().name()));
+ val.ifPresent(v -> {
+ v.insert.accept(mw);
+ mw.visitVarInsn(ASTORE, var.id);
+ });
+ } else {
+ var = addVariable(i.name, typeMap[s.type.type.ordinal()]);
+ val = val.map(v -> v.promote(var.type));
+ System.out.printf(" var: %s = %s\n", var, val);
+ val.ifPresent(v -> {
+ v.insert.accept(mw);
+ mw.visitVarInsn(var.type().getOpcode(ISTORE), var.id);
+ });
+ }
+ variables.put(var.name, var);
}
- variables.put(var.name, var);
}
@Override
public void visitAssign(AST.SAssign s) {
- System.out.printf("%s%s = ", d, s.ref.name());
+ //System.out.printf("%s%s = ", d, s.ref.name());
- Variable var = variables.get(s.ref.name());
+ Value var = visitExpression(s.ref);
+ // Variable var = variables.get(s.ref.name());
Value val = visitExpression(s.value);
val = val.promote(var.type);
val.insert.accept(mw);
- mw.visitVarInsn(var.type.getOpcode(ISTORE), var.id);
+ //mw.visitVarInsn(var.type.getOpcode(ISTORE), var.id);
}
@Override
stack.addFirst(new Value(STRING_TYPE, mv -> {
a.promoteString().insert.accept(mv);
b.promoteString().insert.accept(mv);
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "concat", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", false);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "concat", "(Ljava/lang/String;)Ljava/lang/String;", false);
}));
return;
}
@Override
public void visit(AST.XCall e) {
- System.out.println(e);
- // TODO: how to resolve parts of expression
- List<Value> args = e.params.stream().map(this::visitExpression).toList();
+ List<Value> args = e.args.stream().map(this::visitExpression).toList();
+
+ //imports.dump();
+ if (e.ref.isPresent()) {
+ Value recv = visitExpression(e.ref.get());
+
+ System.out.printf("receiver: %s\n", recv);
+ Optional<Value> im = imports.findImport(recv.type(), e.name, args);
- if (e.ref.part.length == 1) {
- stack.push(imports.findImport(e.ref.name(), args).orElseThrow());
- // or func variable
+ if (im.isPresent()) {
+ Value call = im.get();
+ stack.push(new Value(call.type(), mv -> {
+ recv.insert.accept(mv);
+ call.insert.accept(mv);
+ }));
+ } else {
+ throw new NoSuchElementException();
+ }
} else {
- throw new UnsupportedOperationException("namespace dereferencing unimplemented");
+ stack.push(imports.findImport(e.name, args).orElseThrow());
}
}
public void visit(AST.XFunction e) {
// unimplemented
System.out.print("function (");
- Iterator<String> it = e.params.iterator();
+ Iterator<AST.DParameter> it = e.params.iterator();
if (it.hasNext())
System.out.print(it.next());
while (it.hasNext()) {
System.out.printf("%s}\n", d);
}
+ @Override
+ public void visit(AST.XField e) {
+ System.exit(2);
+ }
+
@Override
public void visit(AST.XReference e) {
Variable var = variables.get(e.name());
static final int IMPORT_FIELDS = 0;
static final int IMPORT_METHODS = 1;
static final int IMPORT_CONSTRUCTORS = 2;
+ /**
+ * Link types to their parents.
+ */
+ Map<Type, Type> parentClass = new HashMap<>();
Map<Type, Map<String, List<Import>>> importInstance[] = IntStream.range(0, 3).mapToObj(i -> new HashMap<>()).toArray(Map[]::new);
Map<Type, Map<String, List<Import>>> importStatic[] = IntStream.range(0, 3).mapToObj(i -> new LinkedHashMap<>()).toArray(Map[]::new);
// TODO: primitive constants are fully resolved at compile time in java, without the GETSTATIC
public void importClass(Class<?> itype, Predicate<Field> fields, Predicate<Method> methods) {
Type irecv = Type.getType(itype);
+
+ Class<?> ptype = itype;
+ while (ptype != Object.class) {
+ Class<?> ntype = ptype.getSuperclass();
+ parentClass.put(Type.getType(ptype), Type.getType(ntype));
+ ptype = ntype;
+ }
+
for (Field f: itype.getFields()) {
if (fields.test(f)) {
Type recv = Type.getType(f.getDeclaringClass());
Type[] argb = im.type.getArgumentTypes();
int score = 0;
- System.out.printf("match arguments:\n %s\n %s\n",
- String.join(", ", Stream.of(arga).map(Object::toString).toArray(String[]::new)),
- String.join(", ", Stream.of(argb).map(Object::toString).toArray(String[]::new)));
+ //System.out.printf("match arguments:\n %s\n %s\n",
+ // String.join(", ", Stream.of(arga).map(Object::toString).toArray(String[]::new)),
+ // String.join(", ", Stream.of(argb).map(Object::toString).toArray(String[]::new)));
if (arga.length == argb.length) {
for (int i = 0; i < arga.length; i++) {
// anything can be converted to string
score += 6;
} else {
- System.out.printf(" -> no match\n");
+ //System.out.printf(" -> no match\n");
return new Match(im, -1);
}
}
}
- System.out.printf(" -> score %d\n", score);
+ //System.out.printf(" -> score %d\n", score);
return new Match(im, score);
};
}
System.out.printf("find method: %s", name);
args.stream().forEach(a -> System.out.printf(" %s", a.type()));
System.out.println();
- for (var map: importStatic[IMPORT_METHODS].entrySet()) {
- System.out.println(map.getKey());
- for (var im: map.getValue().getOrDefault(name, List.of())) {
- System.out.printf(" ? %s\n", im);
- }
- }
+ // for (var map: importInstance[IMPORT_METHODS].entrySet()) {
+ // System.out.println(map.getKey());
+ // for (var im: map.getValue().getOrDefault(name, List.of())) {
+ // System.out.printf(" ? %s\n", im);
+ // }
+ // }
- return importStatic[IMPORT_METHODS].values().stream()
+ var table = importInstance[IMPORT_METHODS];
+ List<Type> list = new ArrayList<>();
+ Type ptype = recv;
+ do {
+ list.add(ptype);
+ ptype = parentClass.get(ptype);
+ } while (ptype != null);
+
+ return list.stream()
+ .peek(m-> System.out.println("c " + m))
+ .map(m -> table.getOrDefault(m, Map.of()))
+ .flatMap(m -> m.getOrDefault(name, List.of()).stream())
+ .peek(m -> System.out.println("? " + m))
+ .map(match(arga))
+ .filter(m -> m.score >= 0)
+ .sorted()
+ .findFirst()
+ .map(m -> {
+ System.out.println("> " + m);
+ return m;
+ })
+ .map(m -> m.im.value(args));
+ /*
+ return importInstance[IMPORT_METHODS].values().stream()
.flatMap(m -> m.getOrDefault(name, List.of()).stream())
.peek(m -> System.out.println("? " + m))
.map(match(arga))
return m;
})
.map(m -> m.im.value(args));
+*/
}
void dump() {
( ELSE '{' rest=statements? '}' )? # ifStatement
| (label=ID ':')? WHILE '(' valueExpr ')' '{' when=statements? '}' # whileStatement
| (label=ID ':')? '{' when=statements '}' # blockStatement
- | type ID ( '=' valueExpr ) ? # declStatement
- | reference '=' valueExpr # assignStatement
- | callExpr # callStatement
+ | type declExpr # declStatement
+ | valueExpr '=' valueExpr # assignStatement
+ | left=valueExpr '.' ID args=argsExpr # callStatement
+ | ID args=argsExpr # callStatement
| CONTINUE (label=ID) ? # breakStatement
| BREAK (label=ID) ? # breakStatement
| RETURN valueExpr ? # returnStatement
// This more or less follows c operator precedence
valueExpr
: '(' valueExpr ')' # valueGroupExpr
- | op=('!'|'-'|'+'|'~') rightValue=valueExpr # valueUnaryExpr
- | leftValue=valueExpr op=('*'|'/'|'%') rightValue=valueExpr # valueBinaryExpr
- | leftValue=valueExpr op=('+'|'-') rightValue=valueExpr # valueBinaryExpr
- | leftValue=valueExpr op=('<<'|'<<<'|'>>') rightValue=valueExpr # valueBinaryExpr
- | leftValue=valueExpr op=('&'|'|') rightValue=valueExpr # valueBinaryExpr
- | leftValue=valueExpr op=('&&'|'||'|'^^') rightValue=valueExpr # valueBinaryExpr
- | leftValue=valueExpr op=(LT|LE|GT|GE|EQ|NE) rightValue=valueExpr # valueBinaryExpr
+ | func=funcExpr # valueFunctionExpr
+ | left=valueExpr '.' ID args=argsExpr # valueCallExpr
+ | ID args=argsExpr # valueCallExpr
+ | NEW ref=reference args=argsExpr # valueNewExpr
+ | left=valueExpr '.' ID # valueFieldExpr
+ | op=('!'|'-'|'+'|'~') right=valueExpr # valueUnaryExpr
+ | left=valueExpr op=('*'|'/'|'%') right=valueExpr # valueBinaryExpr
+ | left=valueExpr op=('+'|'-') right=valueExpr # valueBinaryExpr
+ | left=valueExpr op=('<<'|'<<<'|'>>') right=valueExpr # valueBinaryExpr
+ | left=valueExpr op=('&'|'|') right=valueExpr # valueBinaryExpr
+ | left=valueExpr op=(LT|LE|GT|GE|EQ|NE) right=valueExpr # valueBinaryExpr
+ | left=valueExpr op=('&&'|'||'|'^^') right=valueExpr # valueBinaryExpr
| lit=literal # valueLiteralExpr
| ref=reference # valueReferenceExpr
- | call=callExpr # valueCallExpr
- | func=funcExpr # valueFunctionExpr
;
-callExpr : NEW ? reference '(' (valueExpr (',' valueExpr)*)? ')';
-funcExpr : FUNC rval=type '(' (type ID (',' type ID) *) ? ')' '{' statements? '}';
+funcExpr : FUNC rval=type '(' paramExpr? ')' '{' statements? '}';
+
+argsExpr
+ : '(' (valueExpr (',' valueExpr)*)? ')'
+ ;
+
+declExpr
+ : id=ID ('=' val=valueExpr)?
+ | declExpr ',' id=ID ('=' val=valueExpr)?
+ ;
+
+paramExpr
+ : type id=ID ('=' val=valueExpr) ?
+ | paramExpr ',' type id=ID ('=' val=valueExpr) ?
+ ;
IF : 'if';
ELSE : 'else';
LNG : 'long';
type : INT | LNG | FLT | DBL | STR | BLN | reference;
-literal : INTEGER size='L'? | FLOAT size='f'? | STRING | TRUE | FALSE;
+literal : INTEGER | FLOAT | STRING | TRUE | FALSE;
reference : ID ('.' ID)*;
TRUE : 'true';
OOR : '||';
XXOR : '^^';
-INTEGER : [0-9]+;
-FLOAT : [0-9]+ '.' ([0-9]+)? ([eE] [+-]? [0-9]+)?;
-STRING : '"' (~[\\"] | '\\' [\\"])* '"'
- | '\'' (~[\\'] | '\\' [\\'])* '\'';
ID : [a-zA-Z_][0-9a-zA-Z_$]*;
+INTEGER : [0-9]+ 'L'?;
+FLOAT : [0-9]+ '.' ([0-9]+)? ([eE] [+-]? [0-9]+)? ('f'|'d')?;
+STRING : '"' (~[\\"] | '\\' [\\"])* '"'
+ | '\'' (~[\\'] | '\\' [\\'])* '\'';
NL : ( '\n' | '\r\n' | '\r' ) -> channel(HIDDEN);
COMMENT : '#' ~[\r\n]* -> channel(HIDDEN);