diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index fc64eaf53..07347128b 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -1207,26 +1207,30 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { @Override public Object visitEnumDef(KickCParser.EnumDefContext ctx) { - String enumDefName; - if(ctx.NAME() != null) { - enumDefName = ctx.NAME().getText(); - } else { - enumDefName = getCurrentScope().allocateIntermediateVariableName(); + try { + String enumDefName; + if(ctx.NAME() != null) { + enumDefName = ctx.NAME().getText(); + } else { + enumDefName = getCurrentScope().allocateIntermediateVariableName(); + } + EnumDefinition enumDefinition = new EnumDefinition(enumDefName, getCurrentScope()); + getCurrentScope().add(enumDefinition); + this.currentEnum = enumDefinition; + scopeStack.push(currentEnum); + visit(ctx.enumMemberList()); + scopeStack.pop(); + this.currentEnum = null; + // Copy all members to upper-level scope + Scope parentScope = getCurrentScope(); + while(parentScope instanceof StructDefinition) parentScope = parentScope.getScope(); + for(ConstantVar member : enumDefinition.getAllConstants(false)) { + parentScope.add(new ConstantVar(member.getLocalName(), parentScope, SymbolType.BYTE, member.getValue())); + } + return SymbolType.BYTE; + } catch (CompileError e) { + throw new CompileError(e.getMessage(), new StatementSource(ctx)); } - EnumDefinition enumDefinition = new EnumDefinition(enumDefName, getCurrentScope()); - getCurrentScope().add(enumDefinition); - this.currentEnum = enumDefinition; - scopeStack.push(currentEnum); - visit(ctx.enumMemberList()); - scopeStack.pop(); - this.currentEnum = null; - // Copy all members to upper-level scope - Scope parentScope = getCurrentScope(); - while(parentScope instanceof StructDefinition) parentScope = parentScope.getScope(); - for(ConstantVar member : enumDefinition.getAllConstants(false)) { - parentScope.add(new ConstantVar(member.getLocalName(), parentScope, SymbolType.BYTE, member.getValue())); - } - return SymbolType.BYTE; } @Override diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 1eaa6b5f7..9a17b7e6b 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -35,6 +35,21 @@ public class TestPrograms { public TestPrograms() { } + @Test + public void testEnumErr2() throws IOException, URISyntaxException { + assertError("enum-err-2", "Enum value not constant"); + } + + @Test + public void testEnumErr1() throws IOException, URISyntaxException { + assertError("enum-err-1", "Symbol already declared"); + } + + @Test + public void testEnumErr0() throws IOException, URISyntaxException { + assertError("enum-err-0", "Symbol already declared"); + } + @Test public void testEnum8() throws IOException, URISyntaxException { compileAndCompare("enum-8"); diff --git a/src/test/kc/enum-err-0.kc b/src/test/kc/enum-err-0.kc new file mode 100644 index 000000000..229d0c122 --- /dev/null +++ b/src/test/kc/enum-err-0.kc @@ -0,0 +1,15 @@ +// Test of simple enum error - name already used + +byte ON = 17; + +enum State { + OFF, + ON + }; + +void main() { + enum State state = ON; + const byte* SCREEN = 0x0400; + *SCREEN = state; +} + diff --git a/src/test/kc/enum-err-1.kc b/src/test/kc/enum-err-1.kc new file mode 100644 index 000000000..05c97198c --- /dev/null +++ b/src/test/kc/enum-err-1.kc @@ -0,0 +1,14 @@ +// Test of simple enum error - name already used + +enum State { + OFF, + ON, + OFF +}; + +void main() { + enum State state = ON; + const byte* SCREEN = 0x0400; + *SCREEN = state; +} + diff --git a/src/test/kc/enum-err-2.kc b/src/test/kc/enum-err-2.kc new file mode 100644 index 000000000..c395b0e12 --- /dev/null +++ b/src/test/kc/enum-err-2.kc @@ -0,0 +1,15 @@ +// Test of simple enum error - name already used + +byte val; + +enum State { + OFF, + ON = val +}; + +void main() { + enum State state = ON; + const byte* SCREEN = 0x0400; + *SCREEN = state; +} +