diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 9c6d59f3a..a0a4cee11 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -170,6 +170,7 @@ public class Compiler { assertions.add(new Pass2AssertNoProcs(program)); assertions.add(new Pass2AssertNoLabels(program)); assertions.add(new Pass2AssertSingleAssignment(program)); + assertions.add(new Pass2AssertRValues(program)); for(Pass2SsaAssertion assertion : assertions) { assertion.check(); } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2AssertRValues.java b/src/main/java/dk/camelot64/kickc/passes/Pass2AssertRValues.java new file mode 100644 index 000000000..c234d72b7 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2AssertRValues.java @@ -0,0 +1,38 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.ControlFlowGraphBaseVisitor; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementCall; +import dk.camelot64.kickc.model.values.ForwardVariableRef; +import dk.camelot64.kickc.model.values.RValue; +import dk.camelot64.kickc.model.values.VariableRef; + +import java.util.ListIterator; + +/** Asserts that the program does not contain any RValues that are forward-reference or unversioned */ +public class Pass2AssertRValues extends Pass2SsaAssertion { + + public Pass2AssertRValues(Program program) { + super(program); + } + + @Override + public void check() throws AssertionFailed { + ValueReplacer.executeAll(getGraph(), (replaceable, currentStmt, stmtIt, currentBlock) -> { + RValue rValue = replaceable.get(); + if(rValue instanceof ForwardVariableRef) { + throw new CompileError("No forward references allowed "+currentStmt.toString(getProgram(), false)); + } + if(rValue instanceof VariableRef) { + VariableRef variableRef = (VariableRef) rValue; + if(!variableRef.isIntermediate() && !variableRef.isVersion()) { + throw new CompileError("No unversioned variable references allowed "+currentStmt.toString(getProgram(), false)); + } + } + }); + } + +}