diff --git a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java index 53dd7fd..ced5fc1 100644 --- a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java +++ b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java @@ -1,9 +1,5 @@ package de.hsrm.compiler.Klang; -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.*; @@ -13,9 +9,12 @@ import de.hsrm.compiler.Klang.nodes.loops.WhileLoop; import de.hsrm.compiler.Klang.nodes.statements.*; import de.hsrm.compiler.Klang.types.Type; +import java.util.HashMap; +import java.util.Map; + public class ContextAnalysis extends KlangBaseVisitor { Map vars = new HashMap<>(); - Map functionDefs; + Map functionDefs; Map structDefs; Map enumDefs; Type currentDeclaredReturnType; @@ -29,7 +28,7 @@ public class ContextAnalysis extends KlangBaseVisitor { } public ContextAnalysis( - Map functionDefs, + Map functionDefs, Map structDefs, Map enumDefs ) { @@ -801,15 +800,15 @@ public class ContextAnalysis extends KlangBaseVisitor { int line = ctx.start.getLine(); int col = ctx.start.getCharPositionInLine(); - FunctionInformation func = this.functionDefs.get(name); - if (func == null) { + var functionDef = this.functionDefs.get(name); + if (functionDef == null) { 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(); + int paramCount = functionDef.parameters.length; if (argCount != paramCount) { String error = "Function \"" + name + "\" expects " + paramCount + " parameters, but got " + argCount + "."; throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); @@ -819,14 +818,14 @@ public class ContextAnalysis extends KlangBaseVisitor { Expression[] args = new Expression[argCount]; for (int i = 0; i < argCount; i++) { Expression expression = (Expression) this.visit(ctx.functionCall().arguments().expression(i)); - if (!expression.type.equals(func.signature[i])) { - throw new RuntimeException(Helper.getErrorPrefix(line, col) + "argument " + i + " Expected " + func.signature[i].getName() + " but got: " + expression.type.getName()); + if (!expression.type.equals(functionDef.parameters[i].type)) { + throw new RuntimeException(Helper.getErrorPrefix(line, col) + "argument " + i + " Expected " + functionDef.parameters[i].type.getName() + " but got: " + expression.type.getName()); } args[i] = expression; } FunctionCall result = new FunctionCall(name, args); - result.type = func.returnType; + result.type = functionDef.type; result.line = line; result.col = col; return result; diff --git a/src/main/java/de/hsrm/compiler/Klang/GetDefinitions.java b/src/main/java/de/hsrm/compiler/Klang/GetDefinitions.java index 405cf97..7ce8cee 100644 --- a/src/main/java/de/hsrm/compiler/Klang/GetDefinitions.java +++ b/src/main/java/de/hsrm/compiler/Klang/GetDefinitions.java @@ -1,19 +1,18 @@ package de.hsrm.compiler.Klang; -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.types.EnumType; import de.hsrm.compiler.Klang.types.StructType; import de.hsrm.compiler.Klang.types.Type; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.TreeMap; public class GetDefinitions extends KlangBaseVisitor { - private final Map functionDefs; + private final Map functionDefs; private final Map structDefs; private final Map enumDefs; @@ -22,7 +21,7 @@ public class GetDefinitions extends KlangBaseVisitor { private Set enumNames; public GetDefinitions( - Map functionDefs, + Map functionDefs, Map structDefs, Map enumDefs ) { @@ -138,8 +137,7 @@ public class GetDefinitions extends KlangBaseVisitor { public Node visitStructDef(KlangParser.StructDefContext ctx) { var structName = ctx.structName.getText(); var structFieldCount = ctx.structField().size(); - var structFields = new StructField[structFieldCount]; - var structFieldNames = new HashSet(); + var structFields = new HashMap(); var line = ctx.start.getLine(); var col = ctx.start.getCharPositionInLine(); @@ -152,25 +150,23 @@ public class GetDefinitions extends KlangBaseVisitor { for (int i = 0; i < structFieldCount; i++) { var currentStructField = ctx.structField(i); var structFieldName = currentStructField.IDENT().getText(); - var structFieldTypeName = currentStructField.type_annotation().type().getText(); var structFieldLine = currentStructField.start.getLine(); var structFieldCol = currentStructField.start.getCharPositionInLine(); - if (structFieldNames.contains(structFieldName)) { + if (structFields.containsKey(structFieldName)) { var error = "Duplicate struct field " + structFieldName + " in struct " + structName + "."; throw new RuntimeException(Helper.getErrorPrefix(structFieldLine, structFieldCol) + error); } var structField = new StructField(structFieldName); - structField.type = Type.getByName(structFieldTypeName); + structField.type = Type.getByName(currentStructField.type_annotation().type().getText()); structField.line = structFieldLine; structField.col = structFieldCol; - structFieldNames.add(structFieldName); - structFields[i] = structField; + structFields.put(structFieldName, structField); } - var structDef = new StructDefinition(structName, structFields); + var structDef = new StructDefinition(structName, structFields.values().toArray(new StructField[0])); structDef.line = line; structDef.col = col; structDef.type = new StructType(structName); @@ -182,37 +178,41 @@ public class GetDefinitions extends KlangBaseVisitor { @Override public Node visitFunctionDef(KlangParser.FunctionDefContext ctx) { var funcName = ctx.funcName.getText(); - var returnType = Type.getByName(ctx.returnType.getText()); - var parameters = new TreeMap(); var paramCount = ctx.params.parameter().size(); - var signature = new Type[paramCount]; + var parameters = new HashMap(); + var line = ctx.start.getLine(); + var col = ctx.start.getCharPositionInLine(); // Check that there isn't a struct or enum with the same name if (structNames.contains(funcName) || enumNames.contains(funcName)) { - var line = ctx.start.getLine(); - var col = ctx.start.getCharPositionInLine(); var error = "Duplicate use of name " + funcName + "."; throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } for (int i = 0; i < paramCount; i++) { var currentParam = ctx.params.parameter(i); - var paramType = Type.getByName(currentParam.type_annotation().type().getText()); var paramName = currentParam.IDENT().getText(); + var paramLine = currentParam.start.getLine(); + var paramCol = currentParam.start.getCharPositionInLine(); if (parameters.containsKey(paramName)) { - var paramLine = currentParam.start.getLine(); - var paramCol = currentParam.start.getCharPositionInLine(); var error = "Duplicate parameter name " + paramName + " in function " + funcName + "."; throw new RuntimeException(Helper.getErrorPrefix(paramLine, paramCol) + error); } - parameters.put(paramName, paramType); - signature[i] = paramType; + var parameter = new Parameter(paramName); + parameter.type = Type.getByName(currentParam.type_annotation().type().getText()); + parameter.line = paramLine; + parameter.col = paramCol; + + parameters.put(paramName, parameter); } - var information = new FunctionInformation(funcName, returnType, parameters, signature); - functionDefs.put(funcName, information); + var functionDef = new FunctionDefinition(funcName, parameters.values().toArray(new Parameter[0]), null); + functionDef.type = Type.getByName(ctx.returnType.getText()); + functionDef.line = line; + functionDef.col = col; + functionDefs.put(funcName, functionDef); return null; } } diff --git a/src/main/java/de/hsrm/compiler/Klang/Klang.java b/src/main/java/de/hsrm/compiler/Klang/Klang.java index 136630b..ca8094c 100644 --- a/src/main/java/de/hsrm/compiler/Klang/Klang.java +++ b/src/main/java/de/hsrm/compiler/Klang/Klang.java @@ -1,7 +1,7 @@ package de.hsrm.compiler.Klang; -import de.hsrm.compiler.Klang.helper.FunctionInformation; import de.hsrm.compiler.Klang.nodes.EnumDefinition; +import de.hsrm.compiler.Klang.nodes.FunctionDefinition; import de.hsrm.compiler.Klang.nodes.Node; import de.hsrm.compiler.Klang.nodes.StructDefinition; import de.hsrm.compiler.Klang.visitors.EvalVisitor; @@ -90,7 +90,7 @@ public class Klang { // Context Analysis and DAST generation Node root; - var functionDefs = new HashMap(); + var functionDefs = new HashMap(); var structDefs = new HashMap(); var enumDefs = new HashMap(); try { diff --git a/src/main/java/de/hsrm/compiler/Klang/helper/FunctionInformation.java b/src/main/java/de/hsrm/compiler/Klang/helper/FunctionInformation.java deleted file mode 100644 index 97508f0..0000000 --- a/src/main/java/de/hsrm/compiler/Klang/helper/FunctionInformation.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.hsrm.compiler.Klang.helper; - -import java.util.Map; - -import de.hsrm.compiler.Klang.types.Type; - -public class FunctionInformation { - public String name; - public Type returnType; - public Map parameters; - public Type[] signature; - - public FunctionInformation(String name, Type returnType, Map parameters, Type[] signature) { - this.name = name; - this.returnType = returnType; - this.parameters = parameters; - this.signature = signature; - } -} \ No newline at end of file diff --git a/src/test/java/Helper.java b/src/test/java/Helper.java index e364ac1..eef2a8c 100644 --- a/src/test/java/Helper.java +++ b/src/test/java/Helper.java @@ -16,8 +16,8 @@ public class Helper { return parser.parse(); } - public static Map getFuncs(ParseTree tree) { - var functionDefinitions = new HashMap(); + public static Map getFuncs(ParseTree tree) { + var functionDefinitions = new HashMap(); new GetDefinitions(functionDefinitions, new HashMap<>(), new HashMap<>()).visit(tree); return functionDefinitions; }