Added functionality to analyze AST for all defined functions
This commit is contained in:
@@ -3,6 +3,7 @@ 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.nodes.*;
|
||||
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
||||
import de.hsrm.compiler.Klang.nodes.loops.DoWhileLoop;
|
||||
@@ -13,9 +14,13 @@ import de.hsrm.compiler.Klang.types.Type;
|
||||
|
||||
public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
Map<String, VariableDeclaration> vars = new HashMap<>();
|
||||
Map<String, FunctionDefinition> funcs = new HashMap<>();
|
||||
Map<String, FunctionInformation> funcs;
|
||||
Type currentDeclaredReturnType;
|
||||
|
||||
public ContextAnalysis(Map<String, FunctionInformation> funcs) {
|
||||
this.funcs = funcs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node visitProgram(KlangParser.ProgramContext ctx) {
|
||||
FunctionDefinition[] funcs = new FunctionDefinition[ctx.functionDef().size()];
|
||||
@@ -383,14 +388,6 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
FunctionDefinition result = new FunctionDefinition(name, params, (Block) block);
|
||||
result.type = returnType;
|
||||
|
||||
// Add this function to our environment
|
||||
|
||||
// TODO
|
||||
// Geht nicht weil das bei ner Rekursion um die ohren fliegt,
|
||||
// der funktionsprototyp muss in die funcs geschrieben werden,
|
||||
// bevor der block gevisited wird
|
||||
this.funcs.put(name, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -407,15 +404,14 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
public Node visitFunctionCallExpression(KlangParser.FunctionCallExpressionContext ctx) {
|
||||
String name = ctx.functionCall().IDENT().getText();
|
||||
|
||||
// Make sure the function that is called is defined
|
||||
FunctionDefinition func = this.funcs.get(name);
|
||||
FunctionInformation func = this.funcs.get(name);
|
||||
if (func == null) {
|
||||
throw new RuntimeException("Function with name \"" + name + "\" not defined.");
|
||||
}
|
||||
|
||||
// Make sure the number of arguments matches the number of parameters
|
||||
int argCount = ctx.functionCall().arguments().expression().size();
|
||||
int paramCount = func.parameters.length;
|
||||
int paramCount = func.parameters.size();
|
||||
if (argCount != paramCount) {
|
||||
throw new RuntimeException("Function \"" + name + "\" expects " + paramCount + " parameters, but got " + argCount + ".");
|
||||
}
|
||||
@@ -424,12 +420,12 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
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.parameters[i].type); // Make sure the types are matching
|
||||
expression.type.combine(func.signature[i]); // Make sure the types are matching
|
||||
args[i] = expression;
|
||||
}
|
||||
|
||||
FunctionCall result = new FunctionCall(name, args);
|
||||
result.type = func.type;
|
||||
result.type = func.returnType;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
51
src/main/java/de/hsrm/compiler/Klang/GetFunctions.java
Normal file
51
src/main/java/de/hsrm/compiler/Klang/GetFunctions.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package de.hsrm.compiler.Klang;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import de.hsrm.compiler.Klang.types.*;
|
||||
import de.hsrm.compiler.Klang.helper.*;
|
||||
|
||||
public class GetFunctions extends KlangBaseVisitor<Void> {
|
||||
|
||||
private Map<String, FunctionInformation> funcs;
|
||||
|
||||
public GetFunctions(Map<String, FunctionInformation> funcs) {
|
||||
this.funcs = funcs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitProgram(KlangParser.ProgramContext ctx) {
|
||||
for (int i = 0; i < ctx.functionDef().size(); i++) {
|
||||
this.visit(ctx.functionDef(i));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitFunctionDef(KlangParser.FunctionDefContext ctx) {
|
||||
String name = ctx.funcName.getText();
|
||||
|
||||
if (this.funcs.containsKey(name)) {
|
||||
throw new Error("Function " + name + " defined multiple times");
|
||||
}
|
||||
|
||||
Type returnType = Type.getByName(ctx.returnType.type().getText());
|
||||
|
||||
TreeMap<String, Type> parameters = new TreeMap<String, Type>();
|
||||
|
||||
// Process the paremter list by visiting every paremter in it
|
||||
int paramCount = ctx.params.parameter().size();
|
||||
Type[] signature = new Type[paramCount];
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
Type paramType = Type.getByName(ctx.params.parameter(i).type_annotation().getText());
|
||||
String paramName = ctx.params.parameter(i).IDENT().getText();
|
||||
parameters.put(paramName, paramType);
|
||||
signature[i] = paramType;
|
||||
}
|
||||
|
||||
FunctionInformation information = new FunctionInformation(name, returnType, parameters, signature);
|
||||
this.funcs.put(name, information);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,11 @@ import org.antlr.v4.runtime.tree.*;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
|
||||
import de.hsrm.compiler.Klang.nodes.Node;
|
||||
import de.hsrm.compiler.Klang.visitors.*;
|
||||
import de.hsrm.compiler.Klang.helper.*;
|
||||
|
||||
public class Klang {
|
||||
|
||||
@@ -58,8 +60,15 @@ public class Klang {
|
||||
// create a parser that feeds off the tokens buffer
|
||||
KlangParser parser = new KlangParser(tokens);
|
||||
|
||||
// Parse tokens to AST
|
||||
ParseTree tree = parser.parse(); // begin parsing at init rule
|
||||
ContextAnalysis ctxAnal = new ContextAnalysis();
|
||||
|
||||
// Extract information about all functions
|
||||
var functionDefinitions = new HashMap<String, FunctionInformation>();
|
||||
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
|
||||
|
||||
if (prettyPrint) {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user