make GetStructs collect the complete struct definitions
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
package de.hsrm.compiler.Klang;
|
package de.hsrm.compiler.Klang;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import de.hsrm.compiler.Klang.helper.FunctionInformation;
|
import de.hsrm.compiler.Klang.helper.FunctionInformation;
|
||||||
@@ -12,13 +11,12 @@ import de.hsrm.compiler.Klang.nodes.loops.DoWhileLoop;
|
|||||||
import de.hsrm.compiler.Klang.nodes.loops.ForLoop;
|
import de.hsrm.compiler.Klang.nodes.loops.ForLoop;
|
||||||
import de.hsrm.compiler.Klang.nodes.loops.WhileLoop;
|
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.StructType;
|
|
||||||
import de.hsrm.compiler.Klang.types.Type;
|
import de.hsrm.compiler.Klang.types.Type;
|
||||||
|
|
||||||
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> funcs;
|
Map<String, FunctionInformation> funcs;
|
||||||
Set<String> structs;
|
Map<String, StructDefinition> structs;
|
||||||
Type currentDeclaredReturnType;
|
Type currentDeclaredReturnType;
|
||||||
|
|
||||||
private void checkNumeric(Node lhs, Node rhs, int line, int col) {
|
private void checkNumeric(Node lhs, Node rhs, int line, int col) {
|
||||||
@@ -28,7 +26,7 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContextAnalysis(Map<String, FunctionInformation> funcs, Set<String> structs) {
|
public ContextAnalysis(Map<String, FunctionInformation> funcs, Map<String, StructDefinition> structs) {
|
||||||
this.funcs = funcs;
|
this.funcs = funcs;
|
||||||
this.structs = structs;
|
this.structs = structs;
|
||||||
}
|
}
|
||||||
@@ -36,18 +34,13 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
|||||||
@Override
|
@Override
|
||||||
public Node visitProgram(KlangParser.ProgramContext ctx) {
|
public Node visitProgram(KlangParser.ProgramContext ctx) {
|
||||||
FunctionDefinition[] funcs = new FunctionDefinition[ctx.functionDef().size()];
|
FunctionDefinition[] funcs = new FunctionDefinition[ctx.functionDef().size()];
|
||||||
StructDefinition[] structs = new StructDefinition[ctx.structDef().size()];
|
|
||||||
|
|
||||||
for (int i = 0; i < ctx.functionDef().size(); i++) {
|
for (int i = 0; i < ctx.functionDef().size(); i++) {
|
||||||
funcs[i] = (FunctionDefinition) this.visit(ctx.functionDef(i));
|
funcs[i] = (FunctionDefinition) this.visit(ctx.functionDef(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < ctx.structDef().size(); i++) {
|
|
||||||
structs[i] = (StructDefinition) this.visit(ctx.structDef(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
Expression expression = (Expression) this.visit(ctx.expression());
|
Expression expression = (Expression) this.visit(ctx.expression());
|
||||||
Program result = new Program(funcs, structs, expression);
|
Program result = new Program(funcs, this.structs, expression);
|
||||||
result.type = expression.type;
|
result.type = expression.type;
|
||||||
result.line = ctx.start.getLine();
|
result.line = ctx.start.getLine();
|
||||||
result.col = ctx.start.getCharPositionInLine();
|
result.col = ctx.start.getCharPositionInLine();
|
||||||
@@ -195,7 +188,7 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
|||||||
int col = ctx.start.getCharPositionInLine();
|
int col = ctx.start.getCharPositionInLine();
|
||||||
Type declaredType = Type.getByName(ctx.type_annotation().type().getText());
|
Type declaredType = Type.getByName(ctx.type_annotation().type().getText());
|
||||||
|
|
||||||
if (!declaredType.isPrimitiveType() && !this.structs.contains(declaredType.getName())) {
|
if (!declaredType.isPrimitiveType() && this.structs.get(declaredType.getName()) == null) {
|
||||||
String error = "Type " + declaredType.getName() + " not defined.";
|
String error = "Type " + declaredType.getName() + " not defined.";
|
||||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
||||||
}
|
}
|
||||||
@@ -636,44 +629,6 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node visitStructDef(KlangParser.StructDefContext ctx) {
|
|
||||||
String name = ctx.structName.getText();
|
|
||||||
int line = ctx.start.getLine();
|
|
||||||
int col = ctx.start.getCharPositionInLine();
|
|
||||||
StructField[] fields = new StructField[ctx.structField().size()];
|
|
||||||
|
|
||||||
for (int i = 0; i < ctx.structField().size(); i++) {
|
|
||||||
StructField field = (StructField) this.visit(ctx.structField(i));
|
|
||||||
fields[i] = field;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node result = new StructDefinition(name, fields);
|
|
||||||
result.line = line;
|
|
||||||
result.col = col;
|
|
||||||
result.type = new StructType(name);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node visitStructField(KlangParser.StructFieldContext ctx) {
|
|
||||||
String name = ctx.IDENT().getText();
|
|
||||||
int line = ctx.start.getLine();
|
|
||||||
int col = ctx.start.getCharPositionInLine();
|
|
||||||
Type type = Type.getByName(ctx.type_annotation().type().getText());
|
|
||||||
|
|
||||||
if (!type.isPrimitiveType() && !this.structs.contains(type.getName())) {
|
|
||||||
String error = "Type " + type.getName() + " not defined.";
|
|
||||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node result = new StructField(name);
|
|
||||||
result.type = type;
|
|
||||||
result.line = line;
|
|
||||||
result.col = col;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node visitFunctionDef(KlangParser.FunctionDefContext ctx) {
|
public Node visitFunctionDef(KlangParser.FunctionDefContext ctx) {
|
||||||
String name = ctx.funcName.getText();
|
String name = ctx.funcName.getText();
|
||||||
@@ -682,7 +637,7 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
|||||||
Type returnType = Type.getByName(ctx.returnType.type().getText());
|
Type returnType = Type.getByName(ctx.returnType.type().getText());
|
||||||
this.currentDeclaredReturnType = returnType;
|
this.currentDeclaredReturnType = returnType;
|
||||||
|
|
||||||
if (!returnType.isPrimitiveType() && !this.structs.contains(returnType.getName())) {
|
if (!returnType.isPrimitiveType() && this.structs.get(returnType.getName()) == null) {
|
||||||
String error = "Type " + returnType.getName() + " not defined.";
|
String error = "Type " + returnType.getName() + " not defined.";
|
||||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
||||||
}
|
}
|
||||||
@@ -728,7 +683,7 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
|||||||
int col = ctx.start.getCharPositionInLine();
|
int col = ctx.start.getCharPositionInLine();
|
||||||
Type type = Type.getByName(ctx.type_annotation().type().getText());
|
Type type = Type.getByName(ctx.type_annotation().type().getText());
|
||||||
|
|
||||||
if (!type.isPrimitiveType() && !this.structs.contains(type.getName())) {
|
if (!type.isPrimitiveType() && this.structs.get(type.getName()) == null) {
|
||||||
String error = "Type " + type.getName() + " not defined.";
|
String error = "Type " + type.getName() + " not defined.";
|
||||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,28 @@
|
|||||||
package de.hsrm.compiler.Klang;
|
package de.hsrm.compiler.Klang;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
import de.hsrm.compiler.Klang.helper.Helper;
|
import de.hsrm.compiler.Klang.helper.Helper;
|
||||||
|
import de.hsrm.compiler.Klang.nodes.Node;
|
||||||
|
import de.hsrm.compiler.Klang.nodes.StructDefinition;
|
||||||
|
import de.hsrm.compiler.Klang.nodes.StructField;
|
||||||
|
import de.hsrm.compiler.Klang.types.StructType;
|
||||||
|
import de.hsrm.compiler.Klang.types.Type;
|
||||||
|
|
||||||
public class GetStructs extends KlangBaseVisitor<Void> {
|
public class GetStructs extends KlangBaseVisitor<Node> {
|
||||||
|
|
||||||
private Set<String> structs;
|
private Set<String> structNames;
|
||||||
|
private Map<String, StructDefinition> structs;
|
||||||
|
|
||||||
public GetStructs(Set<String> structs) {
|
public GetStructs(Map<String, StructDefinition> structs) {
|
||||||
this.structs = structs;
|
this.structs = structs;
|
||||||
|
this.structNames = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitProgram(KlangParser.ProgramContext ctx) {
|
public Node visitProgram(KlangParser.ProgramContext ctx) {
|
||||||
for (int i = 0; i < ctx.structDef().size(); i++) {
|
for (int i = 0; i < ctx.structDef().size(); i++) {
|
||||||
this.visit(ctx.structDef(i));
|
this.visit(ctx.structDef(i));
|
||||||
}
|
}
|
||||||
@@ -22,17 +31,48 @@ public class GetStructs extends KlangBaseVisitor<Void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitStructDef(KlangParser.StructDefContext ctx) {
|
public Node visitStructDef(KlangParser.StructDefContext ctx) {
|
||||||
String name = ctx.structName.getText();
|
String name = ctx.structName.getText();
|
||||||
int line = ctx.start.getLine();
|
int line = ctx.start.getLine();
|
||||||
int col = ctx.start.getCharPositionInLine();
|
int col = ctx.start.getCharPositionInLine();
|
||||||
|
StructField[] fields = new StructField[ctx.structField().size()];
|
||||||
|
|
||||||
if (this.structs.contains(name)) {
|
if (this.structNames.contains(name)) {
|
||||||
String error = "Struct " + name + " defined multiple times.";
|
String error = "Struct " + name + " defined multiple times.";
|
||||||
throw new Error(Helper.getErrorPrefix(line, col) + error);
|
throw new Error(Helper.getErrorPrefix(line, col) + error);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.structs.add(name);
|
this.structNames.add(name);
|
||||||
|
|
||||||
|
for (int i = 0; i < ctx.structField().size(); i++) {
|
||||||
|
StructField field = (StructField) this.visit(ctx.structField(i));
|
||||||
|
fields[i] = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
StructDefinition result = new StructDefinition(name, fields);
|
||||||
|
result.line = line;
|
||||||
|
result.col = col;
|
||||||
|
result.type = new StructType(name);
|
||||||
|
this.structs.put(name, result);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node visitStructField(KlangParser.StructFieldContext ctx) {
|
||||||
|
String name = ctx.IDENT().getText();
|
||||||
|
int line = ctx.start.getLine();
|
||||||
|
int col = ctx.start.getCharPositionInLine();
|
||||||
|
Type type = Type.getByName(ctx.type_annotation().type().getText());
|
||||||
|
|
||||||
|
if (!type.isPrimitiveType() && !this.structNames.contains(type.getName())) {
|
||||||
|
String error = "Type " + type.getName() + " not defined.";
|
||||||
|
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node result = new StructField(name);
|
||||||
|
result.type = type;
|
||||||
|
result.line = line;
|
||||||
|
result.col = col;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -8,9 +8,9 @@ import java.io.*;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
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.visitors.*;
|
import de.hsrm.compiler.Klang.visitors.*;
|
||||||
import de.hsrm.compiler.Klang.helper.*;
|
import de.hsrm.compiler.Klang.helper.*;
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ public class Klang {
|
|||||||
new GetFunctions(functionDefinitions).visit(tree);
|
new GetFunctions(functionDefinitions).visit(tree);
|
||||||
|
|
||||||
// Extract information about all structs
|
// Extract information about all structs
|
||||||
var structs = new HashSet<String>();
|
var structs = new HashMap<String, StructDefinition>();
|
||||||
new GetStructs(structs).visit(tree);
|
new GetStructs(structs).visit(tree);
|
||||||
|
|
||||||
// Create the DAST
|
// Create the DAST
|
||||||
|
|||||||
Reference in New Issue
Block a user