diff --git a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java index d326bff..5091dc1 100644 --- a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java +++ b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java @@ -4,6 +4,7 @@ import java.util.Map; import java.util.HashMap; import de.hsrm.compiler.Klang.helper.FunctionInformation; +import de.hsrm.compiler.Klang.helper.Helper; import de.hsrm.compiler.Klang.nodes.*; import de.hsrm.compiler.Klang.nodes.expressions.*; import de.hsrm.compiler.Klang.nodes.loops.DoWhileLoop; @@ -28,8 +29,10 @@ public class ContextAnalysis extends KlangBaseVisitor { funcs[i] = (FunctionDefinition) this.visit(ctx.functionDef(i)); } Expression expression = (Expression) this.visit(ctx.expression()); - Program result = new Program(funcs, expression); + Program result = new Program(funcs, expression); result.type = expression.type; + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); return result; } @@ -52,13 +55,19 @@ public class ContextAnalysis extends KlangBaseVisitor { statements[i] = (Statement) currentStatement; actualStatementCount += 1; - // We use the existance of a type to indicate that this statement returns something - // for which the VariableDeclaration is an exception + // We use the existance of a type to indicate that this statement returns + // something for which the VariableDeclaration is an exception if (currentStatement.type != null && !(currentStatement instanceof VariableDeclaration)) { // check whether the type matches - this.currentDeclaredReturnType.combine(currentStatement.type); + try { + this.currentDeclaredReturnType.combine(currentStatement.type); + } catch (Exception e) { + throw new RuntimeException( + Helper.getErrorPrefix(currentStatement.line, currentStatement.col) + e.getMessage()); + } - // since we have a return guaranteed, every statement after this one is unreachable code + // since we have a return guaranteed, every statement + // after this one is unreachable code hasReturn = true; break; } @@ -81,14 +90,20 @@ public class ContextAnalysis extends KlangBaseVisitor { result.type = this.currentDeclaredReturnType; } + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); return result; } @Override public Node visitPrint(KlangParser.PrintContext ctx) { + ctx.start.getLine(); + ctx.start.getCharPositionInLine(); Node expression = this.visit(ctx.expression()); - PrintStatement result = new PrintStatement((Expression) expression); + PrintStatement result = new PrintStatement((Expression) expression); result.type = null; + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); return result; } @@ -112,9 +127,14 @@ public class ContextAnalysis extends KlangBaseVisitor { } if (thenBlock.type != null && type != null) { - result.type = thenBlock.type.combine(type); + // Since a block verifies that it can combine with the return type of the + // function it is defined in, we do not have check whether the then and + // alt block return types match + result.type = thenBlock.type; } + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); return result; } @@ -122,14 +142,20 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitWhileLoop(KlangParser.WhileLoopContext ctx) { Node condition = this.visit(ctx.cond); Node block = this.visit(ctx.braced_block()); - return new WhileLoop((Expression) condition, (Block) block); + Node result = new WhileLoop((Expression) condition, (Block) block); + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); + return result; } @Override public Node visitDoWhileLoop(KlangParser.DoWhileLoopContext ctx) { Node condition = this.visit(ctx.cond); Node block = this.visit(ctx.braced_block()); - return new DoWhileLoop((Expression) condition, (Block) block); + Node result = new DoWhileLoop((Expression) condition, (Block) block); + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); + return result; } @Override @@ -138,23 +164,33 @@ public class ContextAnalysis extends KlangBaseVisitor { Node condition = this.visit(ctx.cond); Node step = this.visit(ctx.step); Node block = this.visit(ctx.braced_block()); - return new ForLoop((Statement) init, (Expression) condition, (VariableAssignment) step, (Block) block); + Node result = new ForLoop((Statement) init, (Expression) condition, (VariableAssignment) step, (Block) block); + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); + return result; } @Override public Node visitVariable_declaration(KlangParser.Variable_declarationContext ctx) { String name = ctx.IDENT().getText(); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); Type declaredType = Type.getByName(ctx.type_annotation().type().getText()); if (this.vars.get(name) != null) { - throw new RuntimeException("Redeclaration of variable with name \"" + name + "\"."); + String error = "Redeclaration of variable with name \"" + name + "\"."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } // Create the appropriate instance VariableDeclaration result; if (ctx.expression() != null) { Node expression = this.visit(ctx.expression()); - declaredType = declaredType.combine(expression.type); + try { + declaredType = declaredType.combine(expression.type); + } catch (Exception e) { + throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage()); + } result = new VariableDeclaration(name, (Expression) expression); result.type = declaredType; // add the type only if there is an expression } else { @@ -164,26 +200,38 @@ public class ContextAnalysis extends KlangBaseVisitor { // Add it to the global map of variable declarations this.vars.put(name, result); + result.line = line; + result.col = col; return result; } @Override public Node visitVariable_assignment(KlangParser.Variable_assignmentContext ctx) { String name = ctx.IDENT().getText(); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); VariableDeclaration var = this.vars.get(name); if (var == null) { - throw new RuntimeException("Variable with name \"" + name + "\" not defined."); + String error = "Variable with name \"" + name + "\" not defined."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } // Evaluate the expression Expression expression = (Expression) this.visit(ctx.expression()); // Make sure expression can be assigned to the variable - expression.type.combine(var.type); + try { + expression.type.combine(var.type); + } catch (Exception e) { + throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage()); + } // Create a new node and add the type of the expression to it - return new VariableAssignment(name, expression); + Node result = new VariableAssignment(name, expression); + result.line = line; + result.col = col; + return result; } @Override @@ -191,6 +239,8 @@ public class ContextAnalysis extends KlangBaseVisitor { Expression expression = (Expression) this.visit(ctx.expression()); ReturnStatement result = new ReturnStatement(expression); result.type = expression.type; + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); return result; } @@ -199,7 +249,9 @@ public class ContextAnalysis extends KlangBaseVisitor { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); OrExpression result = new OrExpression((Expression) lhs, (Expression) rhs); - result.type = lhs.type.combine(rhs.type); + result.type = Type.getBooleanType(); + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); return result; } @@ -208,7 +260,9 @@ public class ContextAnalysis extends KlangBaseVisitor { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); AndExpression result = new AndExpression((Expression) lhs, (Expression) rhs); - result.type = lhs.type.combine(rhs.type); + result.type = Type.getBooleanType(); + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); return result; } @@ -216,8 +270,16 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitAdditionExpression(KlangParser.AdditionExpressionContext ctx) { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); AdditionExpression result = new AdditionExpression((Expression) lhs, (Expression) rhs); - result.type = lhs.type.combine(rhs.type); + try { + result.type = lhs.type.combine(rhs.type); + } catch (Exception e) { + throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage()); + } + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); return result; } @@ -230,13 +292,19 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitEqualityExpression(KlangParser.EqualityExpressionContext ctx) { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); - if (lhs.type != Type.getIntegerType() || rhs.type != Type.getIntegerType()) { - throw new RuntimeException("Both operants of this expression have to be a number"); + try { + lhs.type.combine(rhs.type); + } catch (Exception e) { + throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage()); } EqualityExpression result = new EqualityExpression((Expression) lhs, (Expression) rhs); result.type = Type.getBooleanType(); + result.line = line; + result.col = col; return result; } @@ -244,13 +312,18 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitNotEqualityExpression(KlangParser.NotEqualityExpressionContext ctx) { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); if (lhs.type != Type.getIntegerType() || rhs.type != Type.getIntegerType()) { - throw new RuntimeException("Both operants of this expression have to be a number"); + String error = "Both operants of this expression have to be a number."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } NotEqualityExpression result = new NotEqualityExpression((Expression) lhs, (Expression) rhs); result.type = Type.getBooleanType(); + result.line = line; + result.col = col; return result; } @@ -258,13 +331,18 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitLessThanExpression(KlangParser.LessThanExpressionContext ctx) { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); if (lhs.type != Type.getIntegerType() || rhs.type != Type.getIntegerType()) { - throw new RuntimeException("Both operants of this expression have to be a number"); + String error = "Both operants of this expression have to be a number."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } LTExpression result = new LTExpression((Expression) lhs, (Expression) rhs); result.type = Type.getBooleanType(); + result.line = line; + result.col = col; return result; } @@ -272,13 +350,18 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitGreaterThanExpression(KlangParser.GreaterThanExpressionContext ctx) { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); if (lhs.type != Type.getIntegerType() || rhs.type != Type.getIntegerType()) { - throw new RuntimeException("Both operants of this expression have to be a number"); + String error = "Both operants of this expression have to be a number."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } GTExpression result = new GTExpression((Expression) lhs, (Expression) rhs); result.type = Type.getBooleanType(); + result.line = line; + result.col = col; return result; } @@ -286,13 +369,18 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitLessThanOrEqualToExpression(KlangParser.LessThanOrEqualToExpressionContext ctx) { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); if (lhs.type != Type.getIntegerType() || rhs.type != Type.getIntegerType()) { - throw new RuntimeException("Both operants of this expression have to be a number"); + String error = "Both operants of this expression have to be a number."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } LTEExpression result = new LTEExpression((Expression) lhs, (Expression) rhs); result.type = Type.getBooleanType(); + result.line = line; + result.col = col; return result; } @@ -300,13 +388,18 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitGreaterThanOrEqualToExpression(KlangParser.GreaterThanOrEqualToExpressionContext ctx) { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); if (lhs.type != Type.getIntegerType() || rhs.type != Type.getIntegerType()) { - throw new RuntimeException("Both operants of this expression have to be a number"); + String error = "Both operants of this expression have to be a number."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } GTEExpression result = new GTEExpression((Expression) lhs, (Expression) rhs); result.type = Type.getBooleanType(); + result.line = line; + result.col = col; return result; } @@ -314,8 +407,16 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitSubstractionExpression(KlangParser.SubstractionExpressionContext ctx) { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); SubstractionExpression result = new SubstractionExpression((Expression) lhs, (Expression) rhs); - result.type = lhs.type.combine(rhs.type); + try { + result.type = lhs.type.combine(rhs.type); + } catch (Exception e) { + throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage()); + } + result.line = line; + result.col = col; return result; } @@ -323,8 +424,16 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitMultiplicationExpression(KlangParser.MultiplicationExpressionContext ctx) { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); MultiplicationExpression result = new MultiplicationExpression((Expression) lhs, (Expression) rhs); - result.type = lhs.type.combine(rhs.type); + try { + result.type = lhs.type.combine(rhs.type); + } catch (Exception e) { + throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage()); + } + result.line = line; + result.col = col; return result; } @@ -332,8 +441,16 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitDivisionExpression(KlangParser.DivisionExpressionContext ctx) { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); DivisionExpression result = new DivisionExpression((Expression) lhs, (Expression) rhs); - result.type = lhs.type.combine(rhs.type); + try { + result.type = lhs.type.combine(rhs.type); + } catch (Exception e) { + throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage()); + } + result.line = line; + result.col = col; return result; } @@ -341,8 +458,16 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitModuloExpression(KlangParser.ModuloExpressionContext ctx) { Node lhs = this.visit(ctx.lhs); Node rhs = this.visit(ctx.rhs); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); ModuloExpression result = new ModuloExpression((Expression) lhs, (Expression) rhs); - result.type = lhs.type.combine(rhs.type); + try { + result.type = lhs.type.combine(rhs.type); + } catch (Exception e) { + throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage()); + } + result.line = line; + result.col = col; return result; } @@ -351,6 +476,8 @@ public class ContextAnalysis extends KlangBaseVisitor { Node expression = this.visit(ctx.expression()); NegateExpression result = new NegateExpression((Expression) expression); result.type = expression.type; + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); return result; } @@ -359,20 +486,27 @@ public class ContextAnalysis extends KlangBaseVisitor { Node expression = this.visit(ctx.expression()); NotExpression result = new NotExpression((Expression) expression); result.type = expression.type; + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); return result; } @Override public Node visitVariable(KlangParser.VariableContext ctx) { String name = ctx.IDENT().getText(); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); VariableDeclaration var = this.vars.get(name); if (var == null) { - throw new RuntimeException("Variable with name \"" + name + "\" not defined."); + String error = "Variable with name \"" + name + "\" not defined."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } Variable result = new Variable(ctx.IDENT().getText()); result.type = var.type; + result.line = line; + result.col = col; return result; } @@ -385,6 +519,8 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitIntAtom(KlangParser.IntAtomContext ctx) { Node n = new IntegerExpression(Integer.parseInt(ctx.getText())); n.type = Type.getIntegerType(); + n.line = ctx.start.getLine(); + n.col = ctx.start.getCharPositionInLine(); return n; } @@ -392,12 +528,16 @@ public class ContextAnalysis extends KlangBaseVisitor { public Node visitBoolAtom(KlangParser.BoolAtomContext ctx) { Node n = new BooleanExpression(ctx.getText().equals("true") ? true : false); n.type = Type.getBooleanType(); + n.line = ctx.start.getLine(); + n.col = ctx.start.getCharPositionInLine(); return n; } @Override public Node visitFunctionDef(KlangParser.FunctionDefContext ctx) { String name = ctx.funcName.getText(); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); Type returnType = Type.getByName(ctx.returnType.type().getText()); this.currentDeclaredReturnType = returnType; @@ -419,13 +559,18 @@ public class ContextAnalysis extends KlangBaseVisitor { this.vars.put(param.name, var); } - // Visit the block, make sure the types are matching + // Visit the block, make sure that a return value is guaranteed Node block = this.visit(ctx.braced_block()); - block.type.combine(returnType); + if (block.type == null) { + String error = "Function " + name + " has to return something of type " + returnType.getName() + "."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); + } FunctionDefinition result = new FunctionDefinition(name, params, (Block) block); result.type = returnType; + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); return result; } @@ -435,35 +580,47 @@ public class ContextAnalysis extends KlangBaseVisitor { Type type = Type.getByName(ctx.type_annotation().type().getText()); Parameter result = new Parameter(name); result.type = type; + result.line = ctx.start.getLine(); + result.col = ctx.start.getCharPositionInLine(); return result; } @Override public Node visitFunctionCallExpression(KlangParser.FunctionCallExpressionContext ctx) { String name = ctx.functionCall().IDENT().getText(); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); FunctionInformation func = this.funcs.get(name); if (func == null) { - throw new RuntimeException("Function with name \"" + name + "\" not defined."); + String error = "Function with name \"" + name + "\" not defined."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } // Make sure the number of arguments matches the number of parameters int argCount = ctx.functionCall().arguments().expression().size(); int paramCount = func.parameters.size(); if (argCount != paramCount) { - throw new RuntimeException("Function \"" + name + "\" expects " + paramCount + " parameters, but got " + argCount + "."); + String error = "Function \"" + name + "\" expects " + paramCount + " parameters, but got " + argCount + "."; + throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } // Evaluate every argument Expression[] args = new Expression[argCount]; for (int i = 0; i < argCount; i++) { - Expression expression = (Expression) this.visit(ctx.functionCall().arguments().expression(i)); - expression.type.combine(func.signature[i]); // Make sure the types are matching + Expression expression = (Expression) this.visit(ctx.functionCall().arguments().expression(i)); + try { + expression.type.combine(func.signature[i]); // Make sure the types are matching + } catch (Exception e) { + throw new RuntimeException(Helper.getErrorPrefix(line, col) + "argument " + i + " " + e.getMessage()); + } args[i] = expression; } FunctionCall result = new FunctionCall(name, args); result.type = func.returnType; + result.line = line; + result.col = col; return result; } } \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/GetFunctions.java b/src/main/java/de/hsrm/compiler/Klang/GetFunctions.java index 9250ad9..f9faa5c 100644 --- a/src/main/java/de/hsrm/compiler/Klang/GetFunctions.java +++ b/src/main/java/de/hsrm/compiler/Klang/GetFunctions.java @@ -25,9 +25,12 @@ public class GetFunctions extends KlangBaseVisitor { @Override public Void visitFunctionDef(KlangParser.FunctionDefContext ctx) { String name = ctx.funcName.getText(); + int line = ctx.start.getLine(); + int col = ctx.start.getCharPositionInLine(); if (this.funcs.containsKey(name)) { - throw new Error("Function " + name + " defined multiple times"); + String error = "Function " + name + " defined multiple times."; + throw new Error(Helper.getErrorPrefix(line, col) + error); } Type returnType = Type.getByName(ctx.returnType.type().getText()); diff --git a/src/main/java/de/hsrm/compiler/Klang/Klang.java b/src/main/java/de/hsrm/compiler/Klang/Klang.java index 6142a18..389e8bf 100644 --- a/src/main/java/de/hsrm/compiler/Klang/Klang.java +++ b/src/main/java/de/hsrm/compiler/Klang/Klang.java @@ -83,29 +83,35 @@ public class Klang { // Parse tokens to AST ParseTree tree = parser.parse(); // begin parsing at init rule - // Extract information about all functions - var functionDefinitions = new HashMap(); - new GetFunctions(functionDefinitions).visit(tree); - // Context Analysis and DAST generation - ContextAnalysis ctxAnal = new ContextAnalysis(functionDefinitions); - Node node = ctxAnal.visit(tree); // this gets us the DAST + Node root; + try { + // Extract information about all functions + var functionDefinitions = new HashMap(); + new GetFunctions(functionDefinitions).visit(tree); + + // Create the DAST + ContextAnalysis ctxAnal = new ContextAnalysis(functionDefinitions); + root = ctxAnal.visit(tree); + } catch (Exception e) { + System.err.println(e.getMessage()); + return; + } if (prettyPrint) { // Pretty Print the sourcecode StringWriter w = new StringWriter(); PrettyPrintVisitor.ExWriter ex = new PrettyPrintVisitor.ExWriter(w); PrettyPrintVisitor printVisitor = new PrettyPrintVisitor(ex); - node.welcome(printVisitor); - generateOutput(out, w.toString()); - return; + root.welcome(printVisitor); + System.out.println(w.toString()); } if (evaluate) { // Evaluate the sourcecode and print the result System.out.println("\nEvaluating the source code:"); EvalVisitor evalVisitor = new EvalVisitor(); - Value result = node.welcome(evalVisitor); + Value result = root.welcome(evalVisitor); if (result != null) { generateOutput(out, "Result was: TODO"); } else { @@ -119,7 +125,7 @@ public class Klang { StringWriter wAsm = new StringWriter(); GenASM.ExWriter exAsm = new GenASM.ExWriter(wAsm); GenASM genasm = new GenASM(exAsm, mainName); - node.welcome(genasm); + root.welcome(genasm); generateOutput(out, wAsm.toString()); } } diff --git a/src/main/java/de/hsrm/compiler/Klang/helper/Helper.java b/src/main/java/de/hsrm/compiler/Klang/helper/Helper.java new file mode 100644 index 0000000..2788a28 --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/helper/Helper.java @@ -0,0 +1,7 @@ +package de.hsrm.compiler.Klang.helper; + +public class Helper { + public static String getErrorPrefix(int line, int col) { + return "Error in line " + line + ":" + col + " "; + } +} \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/nodes/Node.java b/src/main/java/de/hsrm/compiler/Klang/nodes/Node.java index b26e247..a8f033a 100644 --- a/src/main/java/de/hsrm/compiler/Klang/nodes/Node.java +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/Node.java @@ -5,5 +5,8 @@ import de.hsrm.compiler.Klang.visitors.*; public abstract class Node { public Type type; + public int line; + public int col; + public abstract R welcome(Visitor v); } \ 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 a999389..29649ee 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java @@ -152,13 +152,7 @@ public class EvalVisitor implements Visitor { @Override public Value visit(Variable e) { - Value result = this.env.get(e.name); - - if (result == null) { - throw new RuntimeException("Variable with name " + e.name + " not found."); - } - - return result; + return this.env.get(e.name); } @Override @@ -271,11 +265,6 @@ public class EvalVisitor implements Visitor { // Die funktionsdefinition speichern FunctionDefinition func = this.funcs.get(e.name); - // Stelle sicher, dass die Länge der argumente und parameter übereinstimmen - if (e.arguments.length != func.parameters.length) { - throw new RuntimeException("Error with function call " + e.name + ": Number of parameters wrong"); - } - // Baue ein neues environment Map newEnv = new HashMap<>(); for (int i = 0; i < func.parameters.length; i++) {