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