From a969aa895fcda7c64ecbac1182384023d6c308a0 Mon Sep 17 00:00:00 2001 From: nitrix Date: Tue, 4 Feb 2020 21:28:52 +0100 Subject: [PATCH] make GetStructs collect the complete struct definitions --- .../hsrm/compiler/Klang/ContextAnalysis.java | 57 ++----------------- .../de/hsrm/compiler/Klang/GetStructs.java | 54 +++++++++++++++--- .../java/de/hsrm/compiler/Klang/Klang.java | 4 +- 3 files changed, 55 insertions(+), 60 deletions(-) diff --git a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java index 5ba308d..0e5b3df 100644 --- a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java +++ b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java @@ -1,7 +1,6 @@ package de.hsrm.compiler.Klang; import java.util.Map; -import java.util.Set; import java.util.HashMap; 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.WhileLoop; import de.hsrm.compiler.Klang.nodes.statements.*; -import de.hsrm.compiler.Klang.types.StructType; import de.hsrm.compiler.Klang.types.Type; public class ContextAnalysis extends KlangBaseVisitor { Map vars = new HashMap<>(); Map funcs; - Set structs; + Map structs; Type currentDeclaredReturnType; private void checkNumeric(Node lhs, Node rhs, int line, int col) { @@ -28,7 +26,7 @@ public class ContextAnalysis extends KlangBaseVisitor { } } - public ContextAnalysis(Map funcs, Set structs) { + public ContextAnalysis(Map funcs, Map structs) { this.funcs = funcs; this.structs = structs; } @@ -36,18 +34,13 @@ public class ContextAnalysis extends KlangBaseVisitor { @Override public Node visitProgram(KlangParser.ProgramContext ctx) { FunctionDefinition[] funcs = new FunctionDefinition[ctx.functionDef().size()]; - StructDefinition[] structs = new StructDefinition[ctx.structDef().size()]; for (int i = 0; i < ctx.functionDef().size(); 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()); - Program result = new Program(funcs, structs, expression); + Program result = new Program(funcs, this.structs, expression); result.type = expression.type; result.line = ctx.start.getLine(); result.col = ctx.start.getCharPositionInLine(); @@ -195,7 +188,7 @@ public class ContextAnalysis extends KlangBaseVisitor { int col = ctx.start.getCharPositionInLine(); 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."; throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } @@ -636,44 +629,6 @@ public class ContextAnalysis extends KlangBaseVisitor { 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 public Node visitFunctionDef(KlangParser.FunctionDefContext ctx) { String name = ctx.funcName.getText(); @@ -682,7 +637,7 @@ public class ContextAnalysis extends KlangBaseVisitor { Type returnType = Type.getByName(ctx.returnType.type().getText()); 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."; throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } @@ -728,7 +683,7 @@ public class ContextAnalysis extends KlangBaseVisitor { int col = ctx.start.getCharPositionInLine(); 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."; throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } diff --git a/src/main/java/de/hsrm/compiler/Klang/GetStructs.java b/src/main/java/de/hsrm/compiler/Klang/GetStructs.java index b18c497..878c8a3 100644 --- a/src/main/java/de/hsrm/compiler/Klang/GetStructs.java +++ b/src/main/java/de/hsrm/compiler/Klang/GetStructs.java @@ -1,19 +1,28 @@ package de.hsrm.compiler.Klang; +import java.util.Map; import java.util.Set; +import java.util.HashSet; 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 { +public class GetStructs extends KlangBaseVisitor { - private Set structs; + private Set structNames; + private Map structs; - public GetStructs(Set structs) { + public GetStructs(Map structs) { this.structs = structs; + this.structNames = new HashSet<>(); } @Override - public Void visitProgram(KlangParser.ProgramContext ctx) { + public Node visitProgram(KlangParser.ProgramContext ctx) { for (int i = 0; i < ctx.structDef().size(); i++) { this.visit(ctx.structDef(i)); } @@ -22,17 +31,48 @@ public class GetStructs extends KlangBaseVisitor { } @Override - public Void visitStructDef(KlangParser.StructDefContext ctx) { + 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()]; - if (this.structs.contains(name)) { + if (this.structNames.contains(name)) { String error = "Struct " + name + " defined multiple times."; 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; } + + @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; + } } \ No newline at end of file diff --git a/src/main/java/de/hsrm/compiler/Klang/Klang.java b/src/main/java/de/hsrm/compiler/Klang/Klang.java index 289c0b2..a321c29 100644 --- a/src/main/java/de/hsrm/compiler/Klang/Klang.java +++ b/src/main/java/de/hsrm/compiler/Klang/Klang.java @@ -8,9 +8,9 @@ import java.io.*; import java.util.Arrays; import java.util.List; import java.util.HashMap; -import java.util.HashSet; 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.helper.*; @@ -92,7 +92,7 @@ public class Klang { new GetFunctions(functionDefinitions).visit(tree); // Extract information about all structs - var structs = new HashSet(); + var structs = new HashMap(); new GetStructs(structs).visit(tree); // Create the DAST