diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index cfb6c743c..b283a0ac8 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -206,7 +206,6 @@ public class Compiler { ssaOptimized = true; getLog().append("CONTROL FLOW GRAPH"); getLog().append(program.getGraph().toString(program)); - //pass2AssertSSA(program); } } } @@ -215,6 +214,8 @@ public class Compiler { private void pass3Analysis() { + new Pass3AssertNoValueLists(program).check(); + new Pass3BlockSequencePlanner(program).plan(); // Phi lifting ensures that all variables in phi-blocks are in different live range equivalence classes diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoValueLists.java b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoValueLists.java new file mode 100644 index 000000000..71c09eedd --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoValueLists.java @@ -0,0 +1,31 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.RValue; +import dk.camelot64.kickc.model.ValueList; + +/** + * Assert that no value lists still exist inside the code. + */ +public class Pass3AssertNoValueLists extends Pass2SsaAssertion { + + public Pass3AssertNoValueLists(Program program) { + super(program); + } + + @Override + public void check() throws AssertionFailed { + ValueReplacer.executeAll(getGraph(), (replaceable, currentStmt, stmtIt, currentBlock) -> { + RValue value = replaceable.get(); + if(value instanceof ValueList) { + throw new CompileError( + "Error! Value list not resolved to word constructor or array initializer" + + "\n value list: " + value.toString(getProgram()) + + "\n statement: " + currentStmt.toString(getProgram(), false) + ); + } + }); + + } +} diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNVariableReferenceInfos.java b/src/main/java/dk/camelot64/kickc/passes/PassNVariableReferenceInfos.java index 304158bc8..17adbaac7 100644 --- a/src/main/java/dk/camelot64/kickc/passes/PassNVariableReferenceInfos.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNVariableReferenceInfos.java @@ -323,7 +323,7 @@ public class PassNVariableReferenceInfos extends Pass2Base { } else if (rValue instanceof ValueList) { LinkedHashSet used = new LinkedHashSet<>(); for (RValue value : ((ValueList) rValue).getList()) { - used.addAll(getReferencedVars(value)); + used.addAll(getReferenced(value)); } return used; } else { diff --git a/src/main/java/dk/camelot64/kickc/test/TestPrograms.java b/src/main/java/dk/camelot64/kickc/test/TestPrograms.java index 6a34e1ae7..a4c0d6100 100644 --- a/src/main/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/main/java/dk/camelot64/kickc/test/TestPrograms.java @@ -339,6 +339,10 @@ public class TestPrograms extends TestCase { assertError("invalid-consttype", "Constant variable has a non-matching type"); } + public void testValueListError() throws IOException, URISyntaxException { + assertError("valuelist-error", "Value list not resolved to word constructor"); + } + private void assertError(String kcFile, String expectError) throws IOException, URISyntaxException { try { compileAndCompare(kcFile); diff --git a/src/main/java/dk/camelot64/kickc/test/valuelist-error.kc b/src/main/java/dk/camelot64/kickc/test/valuelist-error.kc new file mode 100644 index 000000000..4463c8ebd --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/valuelist-error.kc @@ -0,0 +1,5 @@ +void main() { + word w = { -1, -1}; + byte* screen = $400; + *screen =