From 5c0459c5a2643f86c981941726a8bb92c099c438 Mon Sep 17 00:00:00 2001 From: nitrix Date: Fri, 14 Feb 2020 13:06:20 +0100 Subject: [PATCH] implement constructor call, eval and genasm are still stubs --- .../hsrm/compiler/Klang/ContextAnalysis.java | 40 +++++++++++++++++++ .../java/de/hsrm/compiler/Klang/Klang.java | 30 +++++++------- .../nodes/expressions/ConstructorCall.java | 19 +++++++++ .../compiler/Klang/visitors/EvalVisitor.java | 6 +++ .../hsrm/compiler/Klang/visitors/GenASM.java | 6 +++ .../hsrm/compiler/Klang/visitors/GetVars.java | 5 +++ .../Klang/visitors/PrettyPrintVisitor.java | 17 ++++++++ .../hsrm/compiler/Klang/visitors/Visitor.java | 1 + 8 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 src/main/java/de/hsrm/compiler/Klang/nodes/expressions/ConstructorCall.java diff --git a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java index f16cb03..2741db7 100644 --- a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java +++ b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java @@ -770,4 +770,44 @@ public class ContextAnalysis extends KlangBaseVisitor { result.col = col; return result; } + + @Override + public Node visitConstructorCallExpression(KlangParser.ConstructorCallExpressionContext ctx) { + String name = ctx.IDENT().getText(); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); + + // Get the corresponding struct definition + var struct = this.structs.get(name); + if (struct == null) { + String error = "Struct with name \"" + name + "\" not defined."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); + } + + // Make sure the number of arguments match the number of struct fields + int fieldCount = struct.fields.length; + int argCount = ctx.arguments().expression().size(); + if (argCount != fieldCount) { + String error = "Struct \"" + name + "\" defined " + fieldCount + " fields, but got " + argCount + " constructor parameters."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); + } + + // Evaluate each expression + Expression[] args = new Expression[argCount]; + for (int i = 0; i < argCount; i++) { + Expression expr = (Expression) this.visit(ctx.arguments().expression(i)); + try { + expr.type.combine(struct.fields[i].type); // Make sure the types are matching + } catch (Exception e) { + throw new RuntimeException(Helper.getErrorPrefix(expr.line, expr.col) + "argument " + i + " " + e.getMessage()); + } + args[i] = expr; + } + + ConstructorCall result = new ConstructorCall(name, args); + result.type = struct.type; + result.line = line; + result.col = col; + return result; + } } \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/Klang.java b/src/main/java/de/hsrm/compiler/Klang/Klang.java index 8b63cd1..041042d 100644 --- a/src/main/java/de/hsrm/compiler/Klang/Klang.java +++ b/src/main/java/de/hsrm/compiler/Klang/Klang.java @@ -39,20 +39,20 @@ public class Klang { String out = null; List arguments = Arrays.asList(args); - if (arguments.size() <= 0 || arguments.contains("-h") || arguments.contains("--help") || arguments.contains("?")) { - System.out.println("\nKaiser Lang Compiler"); - System.out.println("Authors: Dennis Kaiser and Marvin Kaiser"); - System.out.println(""); - System.out.println("Last argument must be file"); - System.out.println(""); - System.out.println("Arguments:"); - System.out.println("--out :\t File to write to"); - System.out.println("--evaluate:\t Evaluates the given source code"); - System.out.println("--pretty:\t Pretty print the given source code"); - System.out - .println("--no-main:\t Do not generate main function, will be generated as 'start'. Useful for testing"); - return; - } + // if (arguments.size() <= 0 || arguments.contains("-h") || arguments.contains("--help") || arguments.contains("?")) { + // System.out.println("\nKaiser Lang Compiler"); + // System.out.println("Authors: Dennis Kaiser and Marvin Kaiser"); + // System.out.println(""); + // System.out.println("Last argument must be file"); + // System.out.println(""); + // System.out.println("Arguments:"); + // System.out.println("--out :\t File to write to"); + // System.out.println("--evaluate:\t Evaluates the given source code"); + // System.out.println("--pretty:\t Pretty print the given source code"); + // System.out + // .println("--no-main:\t Do not generate main function, will be generated as 'start'. Useful for testing"); + // return; + // } if (arguments.contains("--evaluate")) { evaluate = true; } @@ -71,7 +71,7 @@ public class Klang { } // create a CharStream that reads from standard input - CharStream input = CharStreams.fromFileName(arguments.get(arguments.size() - 1)); + CharStream input = CharStreams.fromFileName("code.k"); // create a lexer that feeds off of input CharStream KlangLexer lexer = new KlangLexer(input); diff --git a/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/ConstructorCall.java b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/ConstructorCall.java new file mode 100644 index 0000000..ef36b09 --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/expressions/ConstructorCall.java @@ -0,0 +1,19 @@ +package de.hsrm.compiler.Klang.nodes.expressions; + +import de.hsrm.compiler.Klang.visitors.Visitor; + +public class ConstructorCall extends Expression { + + public String structName; + public Expression[] args; + + public ConstructorCall(String structName, Expression[] args) { + this.structName = structName; + this.args = args; + } + + @Override + public R welcome(Visitor v) { + return v.visit(this); + } +} \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java index 9e62256..3a99399 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java @@ -490,4 +490,10 @@ public class EvalVisitor implements Visitor { return null; } + @Override + public Value visit(ConstructorCall e) { + // TODO Auto-generated method stub + return null; + } + } \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java b/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java index a32657a..cdf9ac7 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java @@ -813,4 +813,10 @@ public class GenASM implements Visitor { return null; } + @Override + public Void visit(ConstructorCall e) { + // TODO Auto-generated method stub + return null; + } + } \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java b/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java index 7e923ad..eb728fb 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java @@ -255,4 +255,9 @@ class GetVars implements Visitor { return null; } + @Override + public Void visit(ConstructorCall e) { + return null; + } + } \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java index 5311de9..58d9679 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java @@ -415,4 +415,21 @@ public class PrettyPrintVisitor implements Visitor { return null; } + @Override + public Void visit(ConstructorCall e) { + ex.write("create " + e.structName + "("); + boolean first = true; + for (Expression arg : e.args) { + if (!first) { + ex.write(", "); + } else { + first = false; + } + arg.welcome(this); + } + ex.write(")"); + + return null; + } + } \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java index fdbaf54..ece0bd7 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java @@ -46,4 +46,5 @@ public interface Visitor { R visit(StructDefinition e); R visit(StructField e); R visit(StructFieldAccessExpression e); + R visit(ConstructorCall e); } \ No newline at end of file