mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-03-13 19:33:12 +00:00
Added printable error context to statements
This commit is contained in:
parent
21478bd5b6
commit
808b60d06a
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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<>();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user