From 05945421677138e89be9f96297e0e5dc2ddf7be8 Mon Sep 17 00:00:00 2001 From: nitrix Date: Mon, 20 Mar 2023 19:30:07 +0100 Subject: [PATCH] Enums: Make EnumDefinition use EnumValues instead of Strings as children. This allows us to store the index of the enum value along the name. The index can be used to compare two enum values in assembler. Later on this might be used to enable users of KLang to set arbitrary values as the index of an enum value. --- .../hsrm/compiler/Klang/ContextAnalysis.java | 2 +- .../de/hsrm/compiler/Klang/GetDefinitions.java | 18 ++++++++++++------ .../compiler/Klang/nodes/EnumDefinition.java | 4 ++-- .../hsrm/compiler/Klang/nodes/EnumValue.java | 18 ++++++++++++++++++ .../compiler/Klang/visitors/EvalVisitor.java | 5 +++++ .../hsrm/compiler/Klang/visitors/GenASM.java | 5 +++++ .../hsrm/compiler/Klang/visitors/GetVars.java | 5 +++++ .../Klang/visitors/PrettyPrintVisitor.java | 10 ++++++++-- .../hsrm/compiler/Klang/visitors/Visitor.java | 1 + 9 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 src/main/java/de/hsrm/compiler/Klang/nodes/EnumValue.java diff --git a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java index 9cf7dec..b3c62fe 100644 --- a/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java +++ b/src/main/java/de/hsrm/compiler/Klang/ContextAnalysis.java @@ -355,7 +355,7 @@ public class ContextAnalysis extends KlangBaseVisitor { } var enumValueName = path.get(0); - if (Arrays.stream(enumDef.enums).noneMatch(e -> e.equals(enumValueName))) { + if (Arrays.stream(enumDef.enums).noneMatch(e -> e.value.equals(enumValueName))) { var error = "Unknown enum value " + enumValueName + " of enum " + enumDef.name + "."; throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } diff --git a/src/main/java/de/hsrm/compiler/Klang/GetDefinitions.java b/src/main/java/de/hsrm/compiler/Klang/GetDefinitions.java index fd7ccf6..d5cf9e4 100644 --- a/src/main/java/de/hsrm/compiler/Klang/GetDefinitions.java +++ b/src/main/java/de/hsrm/compiler/Klang/GetDefinitions.java @@ -107,20 +107,26 @@ public class GetDefinitions extends KlangBaseVisitor { } // IDENT() includes the enumName as the first entry, which we skip - var enumFields = new LinkedHashSet(); + var enumValues = new LinkedHashMap(); for (int i = 1; i < ctx.IDENT().size(); i++) { var currentEnumField = ctx.IDENT(i); var currentEnumFieldName = currentEnumField.getText(); - if (enumFields.contains(currentEnumFieldName)) { - var line = currentEnumField.getSymbol().getLine(); - var col = currentEnumField.getSymbol().getCharPositionInLine(); + var line = currentEnumField.getSymbol().getLine(); + var col = currentEnumField.getSymbol().getCharPositionInLine(); + + if (enumValues.containsKey(currentEnumFieldName)) { var error = " Duplicate enum value " + currentEnumFieldName + " in enum " + enumName + "."; throw new RuntimeException(Helper.getErrorPrefix(line, col) + error); } - enumFields.add(currentEnumFieldName); + + var enumValue = new EnumValue(currentEnumFieldName, i - 1); + enumValue.line = line; + enumValue.col = col; + + enumValues.put(currentEnumFieldName, enumValue); } - var enumDef = new EnumDefinition(enumName, enumFields.toArray(new String[0])); + var enumDef = new EnumDefinition(enumName, enumValues.values().toArray(new EnumValue[0])); enumDef.line = ctx.start.getLine(); enumDef.col = ctx.start.getCharPositionInLine(); enumDef.type = new NamedType(enumName); diff --git a/src/main/java/de/hsrm/compiler/Klang/nodes/EnumDefinition.java b/src/main/java/de/hsrm/compiler/Klang/nodes/EnumDefinition.java index 7631ef1..4971b2d 100644 --- a/src/main/java/de/hsrm/compiler/Klang/nodes/EnumDefinition.java +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/EnumDefinition.java @@ -5,9 +5,9 @@ import de.hsrm.compiler.Klang.visitors.Visitor; public class EnumDefinition extends Node { public String name; - public String[] enums; + public EnumValue[] enums; - public EnumDefinition(String name, String[] enums) { + public EnumDefinition(String name, EnumValue[] enums) { this.name = name; this.enums = enums; } diff --git a/src/main/java/de/hsrm/compiler/Klang/nodes/EnumValue.java b/src/main/java/de/hsrm/compiler/Klang/nodes/EnumValue.java new file mode 100644 index 0000000..2a20bc7 --- /dev/null +++ b/src/main/java/de/hsrm/compiler/Klang/nodes/EnumValue.java @@ -0,0 +1,18 @@ +package de.hsrm.compiler.Klang.nodes; + +import de.hsrm.compiler.Klang.visitors.Visitor; + +public class EnumValue extends Node { + public String value; + public int index; + + public EnumValue(String value, int index) { + this.value = value; + this.index = index; + } + + @Override + public R welcome(Visitor v) { + return v.visit(this); + } +} diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java index 55af3ad..ed24dbc 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/EvalVisitor.java @@ -457,6 +457,11 @@ public class EvalVisitor implements Visitor { return null; } + @Override + public Value visit(EnumValue e) { + return null; + } + @Override public Value visit(StructDefinition e) { // We get these from a previous visitor diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java b/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java index d824e56..e9572c6 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GenASM.java @@ -779,6 +779,11 @@ public class GenASM implements Visitor { return null; } + @Override + public Void visit(EnumValue e) { + return null; + } + @Override public Void visit(StructDefinition e) { // We get these from a previous visitor diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java b/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java index 15f94ca..33e6b6b 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/GetVars.java @@ -239,6 +239,11 @@ class GetVars implements Visitor { return null; } + @Override + public Void visit(EnumValue e) { + return null; + } + @Override public Void visit(StructDefinition e) { return null; diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java index fdd89be..252797b 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/PrettyPrintVisitor.java @@ -387,18 +387,24 @@ public class PrettyPrintVisitor implements Visitor { public Void visit(EnumDefinition e) { ex.write("enum " + e.name + " { "); var first = true; - for(var enumName: e.enums) { + for(var enumValue: e.enums) { if (!first) { ex.write(", "); } else { first = false; } - ex.write(enumName); + enumValue.welcome(this); } ex.write(" }"); return null; } + @Override + public Void visit(EnumValue e) { + ex.write(e.value); + return null; + } + @Override public Void visit(StructDefinition e) { ex.write("struct " + e.name + " {"); diff --git a/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java b/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java index 4337ee5..f56e8b6 100644 --- a/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java +++ b/src/main/java/de/hsrm/compiler/Klang/visitors/Visitor.java @@ -38,6 +38,7 @@ public interface Visitor { R visit(Program e); R visit(Parameter e); R visit(EnumDefinition e); + R visit(EnumValue e); R visit(StructDefinition e); R visit(StructField e); R visit(MemberAccessExpression e);