1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-02 09:29:35 +00:00

Added printable error context to statements

This commit is contained in:
jespergravgaard 2018-05-05 21:34:24 +02:00
parent 21478bd5b6
commit 808b60d06a
36 changed files with 190 additions and 134 deletions

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.statements.StatementCall;
import dk.camelot64.kickc.model.statements.StatementSource;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.parser.KickCLexer;
import dk.camelot64.kickc.parser.KickCParser;
@ -88,7 +89,7 @@ public class Compiler {
Pass0GenerateStatementSequence pass0GenerateStatementSequence = new Pass0GenerateStatementSequence(program);
loadAndParseFile(fileName, program, pass0GenerateStatementSequence);
StatementSequence sequence = pass0GenerateStatementSequence.getSequence();
sequence.addStatement(new StatementCall(null, "main", new ArrayList<>()));
sequence.addStatement(new StatementCall(null, "main", new ArrayList<>(), new StatementSource(RuleContext.EMPTY)));
program.setStatementSequence(sequence);
pass1GenerateSSA();

View File

@ -1,5 +1,8 @@
package dk.camelot64.kickc.model;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementSource;
/** Signals some error in the code (or compilation) */
public class CompileError extends RuntimeException {
@ -7,6 +10,14 @@ public class CompileError extends RuntimeException {
super(message);
}
public CompileError(String message, StatementSource source) {
super(message+"\n"+source.toString());
}
public CompileError(String message, Statement statement) {
this(message, statement.getSource());
}
public CompileError(String message, Throwable cause) {
super(message, cause);
}

View File

@ -142,7 +142,7 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
RValue rValue1 = origAssignment.getrValue1();
Operator operator = origAssignment.getOperator();
RValue rValue2 = origAssignment.getrValue2();
return new StatementAssignment(lValue, rValue1, operator, rValue2);
return new StatementAssignment(lValue, rValue1, operator, rValue2, origAssignment.getSource());
}
@Override
@ -151,19 +151,19 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
Operator operator = origConditionalJump.getOperator();
RValue rValue2 = origConditionalJump.getrValue2();
LabelRef destination = origConditionalJump.getDestination();
return new StatementConditionalJump(rValue1, operator, rValue2, destination);
return new StatementConditionalJump(rValue1, operator, rValue2, destination, origConditionalJump.getSource());
}
@Override
public StatementJump visitJump(StatementJump origJump) {
LabelRef destination = origJump.getDestination();
return new StatementJump(destination);
return new StatementJump(destination, origJump.getSource());
}
@Override
public StatementLabel visitJumpTarget(StatementLabel origJump) {
LabelRef label = origJump.getLabel();
return new StatementLabel(label);
return new StatementLabel(label, origJump.getSource());
}
@Override
@ -171,26 +171,26 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
LValue lValue = origCall.getlValue();
String procedureName = origCall.getProcedureName();
List<RValue> parameters = origCall.getParameters();
return new StatementCall(lValue, procedureName, parameters);
return new StatementCall(lValue, procedureName, parameters, origCall.getSource());
}
@Override
public StatementProcedureBegin visitProcedureBegin(StatementProcedureBegin origProcedureBegin) {
return new StatementProcedureBegin(origProcedureBegin.getProcedure());
return new StatementProcedureBegin(origProcedureBegin.getProcedure(), origProcedureBegin.getSource());
}
@Override
public StatementProcedureEnd visitProcedureEnd(StatementProcedureEnd origProcedureEnd) {
return new StatementProcedureEnd(origProcedureEnd.getProcedure());
return new StatementProcedureEnd(origProcedureEnd.getProcedure(), origProcedureEnd.getSource());
}
@Override
public StatementReturn visitReturn(StatementReturn origReturn) {
return new StatementReturn(origReturn.getValue());
return new StatementReturn(origReturn.getValue(), origReturn.getSource());
}
@Override
public Object visitAsm(StatementAsm asm) {
return new StatementAsm(asm.getAsmLines());
return new StatementAsm(asm.getAsmLines(), asm.getSource());
}
}

View File

@ -16,4 +16,10 @@ public interface Statement {
/** Set the index of the statement. Indexes are used during live range analysis. */
void setIndex(Integer idx);
/**
* Get the source for the statement*
*/
StatementSource getSource();
}

View File

@ -9,8 +9,9 @@ public class StatementAsm extends StatementBase {
/** ASM Fragment code. */
private KickCParser.AsmLinesContext asmLines;
public StatementAsm(KickCParser.AsmLinesContext asmLines) {
super(null);
public StatementAsm(KickCParser.AsmLinesContext asmLines,
StatementSource source) {
super(null, source);
this.asmLines = asmLines;
}

View File

@ -22,24 +22,16 @@ public class StatementAssignment extends StatementBase implements StatementLValu
private Operator operator;
private RValue rValue2;
public StatementAssignment(LValue lValue, RValue rValue2) {
this(lValue, null, null, rValue2, null);
public StatementAssignment(LValue lValue, RValue rValue2, StatementSource source) {
this(lValue, null, null, rValue2, null, source);
}
public StatementAssignment(LValue lValue, Operator operator, RValue rValue2) {
this(lValue, null, operator, rValue2, null);
public StatementAssignment(LValue lValue, Operator operator, RValue rValue2,StatementSource source) {
this(lValue, null, operator, rValue2, null, source);
}
public StatementAssignment(LValue lValue, RValue rValue1, Operator operator, RValue rValue2) {
this(lValue, rValue1, operator, rValue2, null);
}
public StatementAssignment(Variable lValue, Variable rValue2) {
this(lValue.getRef(), rValue2.getRef());
}
public StatementAssignment(Variable lValue, RValue rValue2) {
this(lValue.getRef(), rValue2);
public StatementAssignment(LValue lValue, RValue rValue1, Operator operator, RValue rValue2, StatementSource source) {
this(lValue, rValue1, operator, rValue2, null, source);
}
public StatementAssignment(
@ -47,8 +39,9 @@ public class StatementAssignment extends StatementBase implements StatementLValu
RValue rValue1,
Operator operator,
RValue rValue2,
Integer index) {
super(index);
Integer index,
StatementSource source) {
super(index, source);
this.lValue = lValue;
this.rValue1 = rValue1;
this.operator = operator;

View File

@ -12,10 +12,18 @@ import java.util.List;
/** Statement base class implementing shared properties and logic */
public abstract class StatementBase implements Statement {
private StatementSource source;
private Integer index;
public StatementBase(Integer index) {
public StatementBase(Integer index, StatementSource source) {
this.index = index;
this.source = source;
}
@Override
public StatementSource getSource() {
return source;
}
@Override

View File

@ -22,8 +22,8 @@ public class StatementCall extends StatementBase implements StatementLValue {
private ProcedureRef procedure;
private List<RValue> parameters;
public StatementCall(LValue lValue, String procedureName, List<RValue> parameters) {
super(null);
public StatementCall(LValue lValue, String procedureName, List<RValue> parameters, StatementSource source) {
super(null, source);
this.lValue = lValue;
this.procedureName = procedureName;
this.parameters = parameters;

View File

@ -20,8 +20,8 @@ public class StatementConditionalJump extends StatementBase {
private RValue rValue2;
private LabelRef destination;
public StatementConditionalJump(RValue condition, LabelRef destination) {
super(null);
public StatementConditionalJump(RValue condition, LabelRef destination,StatementSource source) {
super(null, source);
this.rValue1 = null;
this.operator = null;
this.rValue2 = condition;
@ -32,8 +32,9 @@ public class StatementConditionalJump extends StatementBase {
RValue rValue1,
Operator operator,
RValue rValue2,
LabelRef destination) {
this(rValue1, operator, rValue2, destination, null);
LabelRef destination,
StatementSource source) {
this(rValue1, operator, rValue2, destination, null, source);
}
public StatementConditionalJump(
@ -41,8 +42,9 @@ public class StatementConditionalJump extends StatementBase {
Operator operator,
RValue rValue2,
LabelRef destination,
Integer index) {
super(index);
Integer index,
StatementSource source) {
super(index, source);
this.rValue1 = rValue1;
this.operator = operator;
this.rValue2 = rValue2;

View File

@ -13,8 +13,9 @@ public class StatementJump extends StatementBase {
private LabelRef destination;
public StatementJump(LabelRef destination) {
super(null);
public StatementJump(LabelRef destination,
StatementSource source) {
super(null, source);
this.destination = destination;
}

View File

@ -10,8 +10,9 @@ public class StatementLabel extends StatementBase {
private LabelRef label;
public StatementLabel(LabelRef label) {
super(null);
public StatementLabel(LabelRef label,
StatementSource source) {
super(null, source);
this.label = label;
}

View File

@ -4,6 +4,7 @@ import dk.camelot64.kickc.model.values.LabelRef;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.VariableRef;
import org.antlr.v4.runtime.RuleContext;
import java.util.ArrayList;
import java.util.Collections;
@ -22,13 +23,14 @@ public class StatementPhiBlock extends StatementBase {
public StatementPhiBlock(
List<PhiVariable> phiVariables,
Integer index) {
super(index);
Integer index,
StatementSource source) {
super(index, source);
this.phiVariables = phiVariables;
}
public StatementPhiBlock() {
super(null);
super(null, new StatementSource(RuleContext.EMPTY));
this.phiVariables = new ArrayList<>();
}

View File

@ -10,8 +10,8 @@ public class StatementProcedureBegin extends StatementBase {
private Strategy strategy;
public StatementProcedureBegin(ProcedureRef procedure) {
super(null);
public StatementProcedureBegin(ProcedureRef procedure,StatementSource source) {
super(null, source);
this.procedure = procedure;
}

View File

@ -10,8 +10,8 @@ public class StatementProcedureEnd extends StatementBase {
private ProcedureRef procedure;
public StatementProcedureEnd(ProcedureRef procedure) {
super(null);
public StatementProcedureEnd(ProcedureRef procedure, StatementSource source) {
super(null, source);
this.procedure = procedure;
}

View File

@ -13,8 +13,8 @@ public class StatementReturn extends StatementBase {
*/
private RValue value;
public StatementReturn(RValue value) {
super(null);
public StatementReturn(RValue value, StatementSource source) {
super(null, source);
this.value = value;
}

View File

@ -0,0 +1,23 @@
package dk.camelot64.kickc.model.statements;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.misc.Interval;
/** Contains information about the source of a program statement */
public class StatementSource {
private ParserRuleContext context;
public StatementSource(ParserRuleContext context) {
this.context = context;
}
@Override
public String toString() {
CharStream stream = context.getStart().getInputStream();
Interval interval = new Interval(context.getStart().getStartIndex(), context.getStop().getStopIndex());
String sourceMessage = "File "+stream.getSourceName()+"\nLine "+context.getStart().getLine()+ "\n" +stream.getText(interval);
return sourceMessage;
}
}

View File

@ -102,21 +102,21 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
parameterList = (List<Variable>) this.visit(ctx.parameterListDecl());
}
procedure.setParameters(parameterList);
sequence.addStatement(new StatementProcedureBegin(procedure.getRef()));
sequence.addStatement(new StatementProcedureBegin(procedure.getRef(), new StatementSource(ctx)));
if(ctx.stmtSeq() != null) {
this.visit(ctx.stmtSeq());
}
sequence.addStatement(new StatementLabel(procExit.getRef()));
sequence.addStatement(new StatementLabel(procExit.getRef(), new StatementSource(ctx)));
if(returnVar != null) {
sequence.addStatement(new StatementAssignment(returnVar, returnVar));
sequence.addStatement(new StatementAssignment(returnVar.getRef(), returnVar.getRef(), new StatementSource(ctx)));
}
VariableRef returnVarRef = null;
if(returnVar != null) {
returnVarRef = returnVar.getRef();
}
sequence.addStatement(new StatementReturn(returnVarRef));
sequence.addStatement(new StatementReturn(returnVarRef, new StatementSource(ctx)));
scopeStack.pop();
sequence.addStatement(new StatementProcedureEnd(procedure.getRef()));
sequence.addStatement(new StatementProcedureEnd(procedure.getRef(), new StatementSource(ctx)));
return null;
}
@ -158,9 +158,9 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
SymbolTypeArray typeArray = (SymbolTypeArray) type;
Integer size = typeArray.getSize();
if(size == null) {
throw new CompileError("Error! Cannot determine array size. " + lValue.toString(program));
throw new CompileError("Error! Cannot determine array size. " + lValue.toString(program), new StatementSource(ctx));
}
Statement stmt = new StatementAssignment(lValue, new ConstantArrayFilled(typeArray.getElementType(), size));
Statement stmt = new StatementAssignment(lValue.getRef(), new ConstantArrayFilled(typeArray.getElementType(), size), new StatementSource(ctx));
sequence.addStatement(stmt);
}
return null;
@ -181,23 +181,24 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
directives.add((Directive) this.visit(directiveContext));
}
for(Directive directive : directives) {
StatementSource source = new StatementSource(directivesCtx.get(0));
if(directive instanceof DirectiveConst) {
lValue.setDeclaredConstant(true);
} else if(directive instanceof DirectiveAlign) {
if(type instanceof SymbolTypeArray || type.equals(SymbolType.STRING)) {
lValue.setDeclaredAlignment(((DirectiveAlign) directive).getAlignment());
} else {
throw new CompileError("Error! Cannot align variable that is not a string or an array " + lValue.toString(program));
throw new CompileError("Error! Cannot align variable that is not a string or an array " + lValue.toString(program), source);
}
} else if(directive instanceof DirectiveRegister) {
DirectiveRegister directiveRegister = (DirectiveRegister) directive;
Registers.Register register = Registers.getRegister(directiveRegister.getName());
if(register == null) {
throw new CompileError("Error! Unknown register " + directiveRegister.getName());
throw new CompileError("Error! Unknown register " + directiveRegister.getName(), source);
}
lValue.setDeclaredRegister(register);
} else {
throw new CompileError("Unsupported variable directive " + directive);
throw new CompileError("Unsupported variable directive " + directive, source);
}
}
}
@ -214,10 +215,11 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
directives.add((Directive) this.visit(directiveContext));
}
for(Directive directive : directives) {
StatementSource source = new StatementSource(directivesCtx.get(0));
if(directive instanceof DirectiveInline) {
procedure.setDeclaredInline(true);
} else {
throw new CompileError("Unsupported function directive " + directive);
throw new CompileError("Unsupported function directive " + directive, source);
}
}
}
@ -280,26 +282,26 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
if(elseStmt==null) {
// If without else - skip the entire section if condition not met
VariableRef notExprVar = getCurrentSymbols().addVariableIntermediate().getRef();
sequence.addStatement(new StatementAssignment(notExprVar, null, Operators.LOGIC_NOT, rValue));
sequence.addStatement(new StatementAssignment(notExprVar, null, Operators.LOGIC_NOT, rValue, new StatementSource(ctx)));
PrePostModifierHandler.addPostModifiers(this, ctx.expr());
Label endJumpLabel = getCurrentSymbols().addLabelIntermediate();
sequence.addStatement(new StatementConditionalJump(notExprVar, endJumpLabel.getRef()));
sequence.addStatement(new StatementConditionalJump(notExprVar, endJumpLabel.getRef(), new StatementSource(ctx)));
this.visit(ifStmt);
// No else statement - just add the label
sequence.addStatement(new StatementLabel(endJumpLabel.getRef()));
sequence.addStatement(new StatementLabel(endJumpLabel.getRef(), new StatementSource(ctx)));
} else {
// If with else - jump to if section if condition met - fall into else otherwise.
PrePostModifierHandler.addPostModifiers(this, ctx.expr());
Label ifJumpLabel = getCurrentSymbols().addLabelIntermediate();
sequence.addStatement(new StatementConditionalJump(rValue, ifJumpLabel.getRef()));
sequence.addStatement(new StatementConditionalJump(rValue, ifJumpLabel.getRef(), new StatementSource(ctx)));
// Add else body
this.visit(elseStmt);
// There is an else statement - add the if part and any needed labels/jumps
Label endJumpLabel = getCurrentSymbols().addLabelIntermediate();
sequence.addStatement(new StatementJump(endJumpLabel.getRef()));
sequence.addStatement(new StatementLabel(ifJumpLabel.getRef()));
sequence.addStatement(new StatementJump(endJumpLabel.getRef(), new StatementSource(ctx)));
sequence.addStatement(new StatementLabel(ifJumpLabel.getRef(), new StatementSource(ctx)));
this.visit(ifStmt);
StatementLabel endJumpTarget = new StatementLabel(endJumpLabel.getRef());
StatementLabel endJumpTarget = new StatementLabel(endJumpLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(endJumpTarget);
}
return null;
@ -310,21 +312,21 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
Label beginJumpLabel = getCurrentSymbols().addLabelIntermediate();
Label doJumpLabel = getCurrentSymbols().addLabelIntermediate();
Label endJumpLabel = getCurrentSymbols().addLabelIntermediate();
StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel.getRef());
StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(beginJumpTarget);
PrePostModifierHandler.addPreModifiers(this, ctx.expr());
RValue rValue = (RValue) this.visit(ctx.expr());
PrePostModifierHandler.addPostModifiers(this, ctx.expr());
Statement doJmpStmt = new StatementConditionalJump(rValue, doJumpLabel.getRef());
Statement doJmpStmt = new StatementConditionalJump(rValue, doJumpLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(doJmpStmt);
Statement endJmpStmt = new StatementJump(endJumpLabel.getRef());
Statement endJmpStmt = new StatementJump(endJumpLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(endJmpStmt);
StatementLabel doJumpTarget = new StatementLabel(doJumpLabel.getRef());
StatementLabel doJumpTarget = new StatementLabel(doJumpLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(doJumpTarget);
this.visit(ctx.stmt());
Statement beginJmpStmt = new StatementJump(beginJumpLabel.getRef());
Statement beginJmpStmt = new StatementJump(beginJumpLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(beginJmpStmt);
StatementLabel endJumpTarget = new StatementLabel(endJumpLabel.getRef());
StatementLabel endJumpTarget = new StatementLabel(endJumpLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(endJumpTarget);
return null;
}
@ -332,7 +334,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
@Override
public Void visitStmtDoWhile(KickCParser.StmtDoWhileContext ctx) {
Label beginJumpLabel = getCurrentSymbols().addLabelIntermediate();
StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel.getRef());
StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(beginJumpTarget);
if(ctx.stmt() != null) {
this.visit(ctx.stmt());
@ -340,7 +342,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
PrePostModifierHandler.addPreModifiers(this, ctx.expr());
RValue rValue = (RValue) this.visit(ctx.expr());
PrePostModifierHandler.addPostModifiers(this, ctx.expr());
Statement doJmpStmt = new StatementConditionalJump(rValue, beginJumpLabel.getRef());
Statement doJmpStmt = new StatementConditionalJump(rValue, beginJumpLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(doJmpStmt);
return null;
}
@ -379,7 +381,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
}
// Add label
Label repeatLabel = getCurrentSymbols().addLabelIntermediate();
StatementLabel repeatTarget = new StatementLabel(repeatLabel.getRef());
StatementLabel repeatTarget = new StatementLabel(repeatLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(repeatTarget);
// Add body
if(stmtForCtx.stmt() != null) {
@ -396,7 +398,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
RValue rValue = (RValue) this.visit(ctx.expr(0));
PrePostModifierHandler.addPostModifiers(this, ctx.expr(0));
// Add jump if condition was met
Statement doJmpStmt = new StatementConditionalJump(rValue, repeatLabel.getRef());
Statement doJmpStmt = new StatementConditionalJump(rValue, repeatLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(doJmpStmt);
return null;
}
@ -417,7 +419,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
lValue = getCurrentSymbols().getVariable(varName);
}
if(lValue == null) {
throw new CompileError("Unknown variable! " + varName);
throw new CompileError("Unknown variable! " + varName, new StatementSource(ctx));
}
KickCParser.ExprContext rangeFirstCtx = ctx.expr(0);
KickCParser.ExprContext rangeLastCtx = ctx.expr(1);
@ -426,11 +428,11 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
ConstantInteger rangeLast = (ConstantInteger) ParseTreeConstantEvaluator.evaluate(rangeLastCtx);
// Assign loop variable with first value
RValue rValue = (RValue) visit(rangeFirstCtx);
Statement stmtInit = new StatementAssignment(lValue, rValue);
Statement stmtInit = new StatementAssignment(lValue.getRef(), rValue, new StatementSource(ctx));
sequence.addStatement(stmtInit);
// Add label
Label repeatLabel = getCurrentSymbols().addLabelIntermediate();
StatementLabel repeatTarget = new StatementLabel(repeatLabel.getRef());
StatementLabel repeatTarget = new StatementLabel(repeatLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(repeatTarget);
// Add body
if(stmtForCtx.stmt() != null) {
@ -439,7 +441,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
// Add increment
ConstantInteger beyondLastVal;
if(rangeFirst.getValue() > rangeLast.getValue()) {
Statement stmtInc = new StatementAssignment(lValue.getRef(), Operators.DECREMENT, lValue.getRef());
Statement stmtInc = new StatementAssignment(lValue.getRef(), Operators.DECREMENT, lValue.getRef(), new StatementSource(ctx));
sequence.addStatement(stmtInc);
if(rangeLast.getValue() == 0) {
beyondLastVal = new ConstantInteger(255L);
@ -447,7 +449,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
beyondLastVal = new ConstantInteger(rangeLast.getValue() - 1);
}
} else {
Statement stmtInc = new StatementAssignment(lValue.getRef(), Operators.INCREMENT, lValue.getRef());
Statement stmtInc = new StatementAssignment(lValue.getRef(), Operators.INCREMENT, lValue.getRef(), new StatementSource(ctx));
sequence.addStatement(stmtInc);
if(rangeLast.getValue() == 255) {
beyondLastVal = new ConstantInteger(0L);
@ -459,17 +461,17 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
// Add condition i<last+1 or i<last-1
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
VariableRef tmpVarRef = tmpVar.getRef();
Statement stmtTmpVar = new StatementAssignment(tmpVarRef, lValue.getRef(), Operators.NEQ, beyondLastVal);
Statement stmtTmpVar = new StatementAssignment(tmpVarRef, lValue.getRef(), Operators.NEQ, beyondLastVal, new StatementSource(ctx));
sequence.addStatement(stmtTmpVar);
// Add jump if condition was met
Statement doJmpStmt = new StatementConditionalJump(tmpVarRef, repeatLabel.getRef());
Statement doJmpStmt = new StatementConditionalJump(tmpVarRef, repeatLabel.getRef(), new StatementSource(ctx));
sequence.addStatement(doJmpStmt);
return null;
}
@Override
public Object visitStmtAsm(KickCParser.StmtAsmContext ctx) {
sequence.addStatement(new StatementAsm(ctx.asmLines()));
sequence.addStatement(new StatementAsm(ctx.asmLines(), new StatementSource(ctx)));
return null;
}
@ -482,18 +484,18 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
PrePostModifierHandler.addPreModifiers(this, exprCtx);
rValue = (RValue) this.visit(exprCtx);
Variable returnVar = procedure.getVariable("return");
sequence.addStatement(new StatementAssignment(returnVar, rValue));
sequence.addStatement(new StatementAssignment(returnVar.getRef(), rValue, new StatementSource(ctx)));
PrePostModifierHandler.addPostModifiers(this, exprCtx);
}
Label returnLabel = procedure.getLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
sequence.addStatement(new StatementJump(returnLabel.getRef()));
sequence.addStatement(new StatementJump(returnLabel.getRef(), new StatementSource(ctx)));
return null;
}
private void addInitialAssignment(KickCParser.ExprContext initializer, Variable lValue) {
PrePostModifierHandler.addPreModifiers(this, initializer);
RValue rValue = (RValue) visit(initializer);
Statement stmt = new StatementAssignment(lValue, rValue);
Statement stmt = new StatementAssignment(lValue.getRef(), rValue, new StatementSource(initializer));
sequence.addStatement(stmt);
PrePostModifierHandler.addPostModifiers(this, initializer);
}
@ -547,7 +549,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
lValue = new LvalueIntermediate((VariableRef) lValue);
}
RValue rValue = (RValue) this.visit(ctx.expr(1));
Statement stmt = new StatementAssignment(lValue, rValue);
Statement stmt = new StatementAssignment(lValue, rValue, new StatementSource(ctx));
sequence.addStatement(stmt);
return lValue;
}
@ -565,7 +567,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
String op = ((TerminalNode) ctx.getChild(1)).getSymbol().getText();
Operator operator = Operators.getBinaryCompound(op);
// Assignment with operator
Statement stmt = new StatementAssignment(lValue, lValue, operator, rValue);
Statement stmt = new StatementAssignment(lValue, lValue, operator, rValue, new StatementSource(ctx));
sequence.addStatement(stmt);
return lValue;
}
@ -577,7 +579,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
Operator operator = Operators.getCastUnary(castType);
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
VariableRef tmpVarRef = tmpVar.getRef();
Statement stmt = new StatementAssignment(tmpVarRef, operator, child);
Statement stmt = new StatementAssignment(tmpVarRef, operator, child, new StatementSource(ctx));
sequence.addStatement(stmt);
return tmpVarRef;
}
@ -593,7 +595,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
}
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
VariableRef tmpVarRef = tmpVar.getRef();
sequence.addStatement(new StatementCall(tmpVarRef, ctx.NAME().getText(), parameters));
sequence.addStatement(new StatementCall(tmpVarRef, ctx.NAME().getText(), parameters, new StatementSource(ctx)));
return tmpVarRef;
}
@ -649,7 +651,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
Operator operator = Operators.getBinary(op);
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
VariableRef tmpVarRef = tmpVar.getRef();
Statement stmt = new StatementAssignment(tmpVarRef, left, operator, right);
Statement stmt = new StatementAssignment(tmpVarRef, left, operator, right, new StatementSource(ctx));
sequence.addStatement(stmt);
return tmpVarRef;
}
@ -667,7 +669,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
Operator operator = Operators.getUnary(op);
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
VariableRef tmpVarRef = tmpVar.getRef();
Statement stmt = new StatementAssignment(tmpVarRef, operator, child);
Statement stmt = new StatementAssignment(tmpVarRef, operator, child, new StatementSource(ctx));
sequence.addStatement(stmt);
return tmpVarRef;
}
@ -763,21 +765,22 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
PrePostModifierHandler prePostModifierHandler = new PrePostModifierHandler(parser);
prePostModifierHandler.visit(ctx);
List<PrePostModifier> modifiers = prePostModifierHandler.getPostMods();
addModifierStatements(parser, modifiers);
addModifierStatements(parser, modifiers, new StatementSource(ctx));
}
public static void addPreModifiers(Pass0GenerateStatementSequence parser, ParserRuleContext ctx) {
PrePostModifierHandler modifierHandler = new PrePostModifierHandler(parser);
modifierHandler.visit(ctx);
List<PrePostModifier> modifiers = modifierHandler.getPreMods();
addModifierStatements(parser, modifiers);
addModifierStatements(parser, modifiers, new StatementSource(ctx));
}
private static void addModifierStatements(
Pass0GenerateStatementSequence parser,
List<PrePostModifier> modifiers) {
List<PrePostModifier> modifiers,
StatementSource source) {
for(PrePostModifier mod : modifiers) {
Statement stmt = new StatementAssignment((LValue) mod.child, mod.operator, mod.child);
Statement stmt = new StatementAssignment((LValue) mod.child, mod.operator, mod.child, source);
parser.sequence.addStatement(stmt);
parser.program.getLog().append("Adding pre/post-modifier " + stmt.toString(parser.program, true));
}

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.StatementSource;
import dk.camelot64.kickc.model.values.LValue;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
@ -67,7 +68,7 @@ public class Pass1AddTypePromotions extends Pass1Base {
String msg = "ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). " +
"In " + assignment.toString(getProgram(), false);
getProgram().getLog().append(msg);
throw new CompileError(msg);
throw new CompileError(msg, assignment.getSource());
}
}

View File

@ -32,11 +32,11 @@ public class Pass1AssertArrayLengths extends Pass1Base {
RValue value = assignment.getrValue2();
if(value instanceof ValueList) {
if(((ValueList) value).getList().size() != declaredSize) {
throw new CompileError("Error! Array length mismatch " + statement.toString(getProgram(), false));
throw new CompileError("Error! Array length mismatch " + statement.toString(getProgram(), false), statement.getSource());
}
} else if(value instanceof ConstantString) {
if(((ConstantString) value).getValue().length() != declaredSize) {
throw new CompileError("Error! Array length mismatch " + statement.toString(getProgram(), false));
throw new CompileError("Error! Array length mismatch " + statement.toString(getProgram(), false), statement.getSource());
}
}
}

View File

@ -26,7 +26,7 @@ public class Pass1AssertNoLValueIntermediate extends Pass1Base {
if(lValue instanceof LvalueIntermediate) {
VariableRef intermediateVar = ((LvalueIntermediate) lValue).getVariable();
StatementAssignment assignment = getGraph().getAssignment(intermediateVar);
throw new CompileError("Error! LValue is illegal. " + statement + " - definition of lValue " + assignment);
throw new CompileError("Error! LValue is illegal. " + statement + " - definition of lValue " + assignment, assignment.getSource());
}
}
}

View File

@ -55,7 +55,7 @@ public class Pass1AssertUsedVars extends Pass1Base {
Collection<VariableRef> used = referenceInfos.getUsedVars(statement);
for(VariableRef usedRef : used) {
if(!defined.contains(usedRef)) {
throw new CompileError("Error! Variable used before being defined " + usedRef.toString(getProgram()) + " in " + statement.toString(getProgram(), false));
throw new CompileError("Error! Variable used before being defined " + usedRef.toString(getProgram()) + " in " + statement.toString(getProgram(), false), statement.getSource());
}
}
Collection<VariableRef> defd = referenceInfos.getDefinedVars(statement);

View File

@ -69,7 +69,7 @@ public class Pass1FixLValuesLoHi extends Pass1Base {
statementLValue.setlValue(tmpVarRef);
SymbolTypeInference.inferLValue(getProgram(), statementLValue, false);
// Insert an extra "set low" assignment statement
Statement setLoHiAssignment = new StatementAssignment(loHiVar, loHiVar, loHiOperator, tmpVarRef);
Statement setLoHiAssignment = new StatementAssignment(loHiVar, loHiVar, loHiOperator, tmpVarRef, statementLValue.getSource());
statementsIt.add(setLoHiAssignment);
getLog().append("Fixing lo/hi-lvalue with new tmpVar " + tmpVarRef + " " + statementLValue.toString());
}

View File

@ -10,6 +10,7 @@ import dk.camelot64.kickc.model.values.LabelRef;
import dk.camelot64.kickc.model.values.ProcedureRef;
import dk.camelot64.kickc.model.values.ScopeRef;
import dk.camelot64.kickc.model.values.SymbolRef;
import org.antlr.v4.runtime.RuleContext;
import java.util.ArrayList;
import java.util.List;
@ -32,7 +33,7 @@ public class Pass1GenerateControlFlowGraph extends Pass1Base {
ControlFlowBlock firstBlock = getOrCreateBlock(scope.addLabel(SymbolRef.BEGIN_BLOCK_NAME).getRef(), ScopeRef.ROOT);
Stack<ControlFlowBlock> blockStack = new Stack<>();
blockStack.push(firstBlock);
sequence.addStatement(new StatementLabel(scope.addLabel(SymbolRef.END_BLOCK_NAME).getRef()));
sequence.addStatement(new StatementLabel(scope.addLabel(SymbolRef.END_BLOCK_NAME).getRef(), new StatementSource(RuleContext.EMPTY)));
for(Statement statement : sequence.getStatements()) {
ControlFlowBlock currentBlock = blockStack.peek();
Symbol currentBlockLabel = scope.getSymbol(currentBlock.getLabel());

View File

@ -58,7 +58,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
if(assignedSymbol.isDeclaredConstant()) {
Collection<VariableVersion> versions = assignedVar.getScope().getVersions(assignedSymbol);
if(versions.size() != 0) {
throw new CompileError("Error! Constants can not be modified " + statement);
throw new CompileError("Error! Constants can not be modified " + statement, statement.getSource());
}
version = assignedSymbol.createVersion();
version.setDeclaredConstant(true);

View File

@ -43,7 +43,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
for(int i = 0; i < parameterDecls.size(); i++) {
Variable parameterDecl = parameterDecls.get(i);
RValue parameterValue = parameterValues.get(i);
addStatementToCurrentBlock(new StatementAssignment(parameterDecl.getRef(), parameterValue));
addStatementToCurrentBlock(new StatementAssignment(parameterDecl.getRef(), parameterValue, origCall.getSource()));
}
String procedureName = origCall.getProcedureName();
Variable procReturnVar = procedure.getVariable("return");
@ -51,7 +51,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
if(procReturnVar != null) {
procReturnVarRef = procReturnVar.getRef();
}
StatementCall copyCall = new StatementCall(procReturnVarRef, procedureName, null);
StatementCall copyCall = new StatementCall(procReturnVarRef, procedureName, null, origCall.getSource());
copyCall.setProcedure(procedureRef);
addStatementToCurrentBlock(copyCall);
getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
@ -64,7 +64,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
}
splitCurrentBlock(currentBlockScope.addLabelIntermediate().getRef());
if(!SymbolType.VOID.equals(procedure.getReturnType()) && origCall.getlValue() != null) {
addStatementToCurrentBlock(new StatementAssignment(origCall.getlValue(), procReturnVarRef));
addStatementToCurrentBlock(new StatementAssignment(origCall.getlValue(), procReturnVarRef, origCall.getSource()));
} else {
// No return type. Remove variable receiving the result.
LValue lValue = origCall.getlValue();
@ -77,7 +77,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
// Add self-assignments for all variables modified in the procedure
Set<VariableRef> modifiedVars = program.getProcedureModifiedVars().getModifiedVars(procedure.getRef());
for(VariableRef modifiedVar : modifiedVars) {
addStatementToCurrentBlock(new StatementAssignment(modifiedVar, modifiedVar));
addStatementToCurrentBlock(new StatementAssignment(modifiedVar, modifiedVar, origCall.getSource()));
}
return null;
}
@ -90,7 +90,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
// Add self-assignments for all variables modified in the procedure
Set<VariableRef> modifiedVars = program.getProcedureModifiedVars().getModifiedVars(procedure.getRef());
for(VariableRef modifiedVar : modifiedVars) {
addStatementToCurrentBlock(new StatementAssignment(modifiedVar, modifiedVar));
addStatementToCurrentBlock(new StatementAssignment(modifiedVar, modifiedVar, origReturn.getSource()));
}
return super.visitReturn(origReturn);
}

View File

@ -6,6 +6,7 @@ import dk.camelot64.kickc.model.statements.*;
import dk.camelot64.kickc.model.symbols.Label;
import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.types.SymbolType;
import org.antlr.v4.runtime.RuleContext;
import java.util.Set;
@ -32,7 +33,7 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
ProcedureRef procedureRef = origCall.getProcedure();
Procedure procedure = program.getScope().getProcedure(procedureRef);
String procedureName = origCall.getProcedureName();
StatementCall copyCall = new StatementCall(null, procedureName, null);
StatementCall copyCall = new StatementCall(null, procedureName, null, origCall.getSource());
copyCall.setProcedure(procedureRef);
addStatementToCurrentBlock(copyCall);
getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
@ -53,7 +54,7 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
if(returnVarFinal == null) {
throw new RuntimeException("Error! Cannot find final return variable for " + procedure.getFullName());
}
StatementAssignment returnAssignment = new StatementAssignment(origCall.getlValue(), returnVarFinal);
StatementAssignment returnAssignment = new StatementAssignment(origCall.getlValue(), returnVarFinal, origCall.getSource());
addStatementToCurrentBlock(returnAssignment);
}
@ -102,7 +103,7 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
@Override
public StatementReturn visitReturn(StatementReturn origReturn) {
addStatementToCurrentBlock(new StatementReturn(null));
addStatementToCurrentBlock(new StatementReturn(null, origReturn.getSource()));
return null;
}
}

View File

@ -85,7 +85,7 @@ public class Pass1ProcedureInline extends Pass1Base {
Variable procReturnVar = procedure.getVariable("return");
String inlinedReturnVarName = getInlineSymbolName(procedure, procReturnVar, serial);
Variable inlinedReturnVar = callScope.getVariable(inlinedReturnVarName);
restBlock.addStatement(new StatementAssignment(call.getlValue(), inlinedReturnVar.getRef()));
restBlock.addStatement(new StatementAssignment(call.getlValue(), inlinedReturnVar.getRef(), call.getSource()));
} else {
// Remove the tmp var receiving the result
LValue lValue = call.getlValue();
@ -165,10 +165,10 @@ public class Pass1ProcedureInline extends Pass1Base {
Statement inlinedStatement;
if(procStatement instanceof StatementAssignment) {
StatementAssignment procAssignment = (StatementAssignment) procStatement;
inlinedStatement = new StatementAssignment(procAssignment.getlValue(), procAssignment.getrValue1(), procAssignment.getOperator(), procAssignment.getrValue2());
inlinedStatement = new StatementAssignment(procAssignment.getlValue(), procAssignment.getrValue1(), procAssignment.getOperator(), procAssignment.getrValue2(), procAssignment.getSource());
} else if(procStatement instanceof StatementCall) {
StatementCall procCall = (StatementCall) procStatement;
StatementCall inlinedCall = new StatementCall(procCall.getlValue(), procCall.getProcedureName(), new ArrayList<>(procCall.getParameters()));
StatementCall inlinedCall = new StatementCall(procCall.getlValue(), procCall.getProcedureName(), new ArrayList<>(procCall.getParameters()), procCall.getSource());
inlinedCall.setProcedure(procCall.getProcedure());
inlinedStatement = inlinedCall;
} else if(procStatement instanceof StatementConditionalJump) {
@ -180,12 +180,12 @@ public class Pass1ProcedureInline extends Pass1Base {
String inlineSymbolName = getInlineSymbolName(procedure, procDestination, serial);
inlinedDest = callScope.getLabel(inlineSymbolName);
}
inlinedStatement = new StatementConditionalJump(procConditional.getrValue1(), procConditional.getOperator(), procConditional.getrValue2(), inlinedDest.getRef());
inlinedStatement = new StatementConditionalJump(procConditional.getrValue1(), procConditional.getOperator(), procConditional.getrValue2(), inlinedDest.getRef(), procConditional.getSource());
} else if(procStatement instanceof StatementReturn) {
// No statement needed
return null;
} else {
throw new CompileError("Statement type of Inline function not handled " + procStatement);
throw new CompileError("Statement type of Inline function not handled " + procStatement, procStatement.getSource());
}
if(inlinedStatement!=null) {
ValueReplacer.executeAll(inlinedStatement, new RValueInliner(procedure, serial, callScope), null, null);
@ -252,7 +252,7 @@ public class Pass1ProcedureInline extends Pass1Base {
String inlineParameterVarName = getInlineSymbolName(procedure, parameterDecl, serial);
Variable inlineParameterVar = callScope.getVariable(inlineParameterVarName);
RValue parameterValue = parameterValues.get(i);
statementsIt.add(new StatementAssignment(inlineParameterVar.getRef(), parameterValue));
statementsIt.add(new StatementAssignment(inlineParameterVar.getRef(), parameterValue, call.getSource()));
}
}

View File

@ -27,7 +27,7 @@ public class Pass1ResolveForwardReferences extends Pass1Base {
replaceable.set(variable.getRef());
} else {
getLog().append("ERROR! Unknown variable " + varName);
throw new CompileError("ERROR! Unknown variable " + varName);
throw new CompileError("ERROR! Unknown variable " + varName, currentStmt.getSource());
}
}
});

View File

@ -33,11 +33,11 @@ public class Pass1TypeInference extends Pass1Base {
Scope currentScope = getScope().getScope(block.getScope());
Procedure procedure = currentScope.getProcedure(procedureName);
if(procedure == null) {
throw new CompileError("Called procedure not found. " + call.toString(getProgram(), false));
throw new CompileError("Called procedure not found. " + call.toString(getProgram(), false), statement.getSource());
}
call.setProcedure(procedure.getRef());
if(procedure.getParameters().size() != call.getParameters().size()) {
throw new CompileError("Wrong number of parameters in call. Expected " + procedure.getParameters().size() + ". " + statement.toString());
throw new CompileError("Wrong number of parameters in call. Expected " + procedure.getParameters().size() + ". " + statement.toString(), statement.getSource());
}
SymbolTypeInference.inferCallLValue(getProgram(), (StatementCall) statement, false);
}

View File

@ -24,12 +24,12 @@ public class Pass2AssertRValues extends Pass2SsaAssertion {
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));
throw new CompileError("No forward references allowed "+currentStmt.toString(getProgram(), false), currentStmt.getSource());
}
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));
throw new CompileError("No unversioned variable references allowed "+currentStmt.toString(getProgram(), false), currentStmt.getSource());
}
}
});

View File

@ -41,7 +41,7 @@ public class Pass2AssertTypeMatch extends Pass2SsaAssertion {
}
// Types do not match
getLog().append("ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). In " + statement.toString(getProgram(), false));
throw new CompileError("ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). In " + statement.toString(getProgram(), false));
throw new CompileError("ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). In " + statement.toString(getProgram(), false), statement.getSource());
}
}

View File

@ -91,7 +91,7 @@ public class Pass2ConditionalAndOrRewriting extends Pass2SsaOptimization {
Label newBlockLabel = currentScope.addLabelIntermediate();
ControlFlowBlock newBlock = new ControlFlowBlock(newBlockLabel.getRef(), currentScopeRef);
getGraph().addBlock(newBlock);
newBlock.getStatements().add(new StatementConditionalJump(conditionAssignment.getrValue2(), conditional.getDestination()));
newBlock.getStatements().add(new StatementConditionalJump(conditionAssignment.getrValue2(), conditional.getDestination(), conditional.getSource()));
newBlock.setDefaultSuccessor(block.getDefaultSuccessor());
newBlock.setConditionalSuccessor(conditional.getDestination());
// Rewrite the conditional to use only the first part of the && condition expression
@ -114,7 +114,7 @@ public class Pass2ConditionalAndOrRewriting extends Pass2SsaOptimization {
Label newBlockLabel = currentScope.addLabelIntermediate();
ControlFlowBlock newBlock = new ControlFlowBlock(newBlockLabel.getRef(), currentScopeRef);
getGraph().addBlock(newBlock);
newBlock.getStatements().add(new StatementConditionalJump(conditionAssignment.getrValue2(), conditional.getDestination()));
newBlock.getStatements().add(new StatementConditionalJump(conditionAssignment.getrValue2(), conditional.getDestination(), conditional.getSource()));
newBlock.setConditionalSuccessor(conditional.getDestination());
newBlock.setDefaultSuccessor(block.getDefaultSuccessor());
// Rewrite the conditional to use only the first part of the && condition expression

View File

@ -109,7 +109,7 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization {
// Move backward - to insert before the current statement
stmtIt.previous();
// Add assignment of the new tmpVar
StatementAssignment assignment = new StatementAssignment(tmpVar.getRef(), list.getList().get(0), constructOperator, list.getList().get(1));
StatementAssignment assignment = new StatementAssignment(tmpVar.getRef(), list.getList().get(0), constructOperator, list.getList().get(1), currentStmt.getSource());
stmtIt.add(assignment);
// Move back before the current statement
stmtIt.next();

View File

@ -23,13 +23,13 @@ public class Pass3AssertNoMulDivMod extends Pass2SsaAssertion {
if(statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;
if(Operators.MULTIPLY.equals(assignment.getOperator())) {
throw new CompileError("ERROR! Runtime multiplication not supported. "+statement.toString(getProgram(), false));
throw new CompileError("ERROR! Runtime multiplication not supported. "+statement.toString(getProgram(), false), statement.getSource());
}
if(Operators.DIVIDE.equals(assignment.getOperator())) {
throw new CompileError("ERROR! Runtime division not supported. "+statement.toString(getProgram(), false));
throw new CompileError("ERROR! Runtime division not supported. "+statement.toString(getProgram(), false), statement.getSource());
}
if(Operators.MODULO.equals(assignment.getOperator())) {
throw new CompileError("ERROR! Runtime modulo not supported. "+statement.toString(getProgram(), false));
throw new CompileError("ERROR! Runtime modulo not supported. "+statement.toString(getProgram(), false), statement.getSource());
}
}

View File

@ -23,6 +23,7 @@ public class Pass3AssertNoValueLists extends Pass2SsaAssertion {
"Error! Value list not resolved to word constructor or array initializer" +
"\n value list: " + value.toString(getProgram()) +
"\n statement: " + currentStmt.toString(getProgram(), false)
, currentStmt.getSource()
);
}
});

View File

@ -61,7 +61,7 @@ public class Pass3PhiLifting {
if(predecessorStatements.size() > 0) {
lastPredecessorStatement = predecessorStatements.get(predecessorStatements.size() - 1);
}
StatementAssignment newAssignment = new StatementAssignment(newVar, phiRValue.getrValue());
StatementAssignment newAssignment = new StatementAssignment(newVar.getRef(), phiRValue.getrValue(), phiBlock.getSource());
if(lastPredecessorStatement instanceof StatementConditionalJump) {
// Use or Create a new block between the predecessor and this one - getReplacement labels where appropriate
ControlFlowBlock newBlock;