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.
This commit is contained in:
2023-03-20 19:30:07 +01:00
parent 77fe360ffa
commit 0594542167
9 changed files with 57 additions and 11 deletions

View File

@@ -355,7 +355,7 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
}
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);
}

View File

@@ -107,20 +107,26 @@ public class GetDefinitions extends KlangBaseVisitor<Node> {
}
// IDENT() includes the enumName as the first entry, which we skip
var enumFields = new LinkedHashSet<String>();
var enumValues = new LinkedHashMap<String, EnumValue>();
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();
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);

View File

@@ -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;
}

View File

@@ -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> R welcome(Visitor<R> v) {
return v.visit(this);
}
}

View File

@@ -457,6 +457,11 @@ public class EvalVisitor implements Visitor<Value> {
return null;
}
@Override
public Value visit(EnumValue e) {
return null;
}
@Override
public Value visit(StructDefinition e) {
// We get these from a previous visitor

View File

@@ -779,6 +779,11 @@ public class GenASM implements Visitor<Void> {
return null;
}
@Override
public Void visit(EnumValue e) {
return null;
}
@Override
public Void visit(StructDefinition e) {
// We get these from a previous visitor

View File

@@ -239,6 +239,11 @@ class GetVars implements Visitor<Void> {
return null;
}
@Override
public Void visit(EnumValue e) {
return null;
}
@Override
public Void visit(StructDefinition e) {
return null;

View File

@@ -387,18 +387,24 @@ public class PrettyPrintVisitor implements Visitor<Void> {
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 + " {");

View File

@@ -38,6 +38,7 @@ public interface Visitor<R> {
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);