mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-09-08 17:54:40 +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.*;
|
||||||
import dk.camelot64.kickc.model.statements.StatementCall;
|
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.model.symbols.Variable;
|
||||||
import dk.camelot64.kickc.parser.KickCLexer;
|
import dk.camelot64.kickc.parser.KickCLexer;
|
||||||
import dk.camelot64.kickc.parser.KickCParser;
|
import dk.camelot64.kickc.parser.KickCParser;
|
||||||
@ -88,7 +89,7 @@ public class Compiler {
|
|||||||
Pass0GenerateStatementSequence pass0GenerateStatementSequence = new Pass0GenerateStatementSequence(program);
|
Pass0GenerateStatementSequence pass0GenerateStatementSequence = new Pass0GenerateStatementSequence(program);
|
||||||
loadAndParseFile(fileName, program, pass0GenerateStatementSequence);
|
loadAndParseFile(fileName, program, pass0GenerateStatementSequence);
|
||||||
StatementSequence sequence = pass0GenerateStatementSequence.getSequence();
|
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);
|
program.setStatementSequence(sequence);
|
||||||
|
|
||||||
pass1GenerateSSA();
|
pass1GenerateSSA();
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package dk.camelot64.kickc.model;
|
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) */
|
/** Signals some error in the code (or compilation) */
|
||||||
public class CompileError extends RuntimeException {
|
public class CompileError extends RuntimeException {
|
||||||
|
|
||||||
@ -7,6 +10,14 @@ public class CompileError extends RuntimeException {
|
|||||||
super(message);
|
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) {
|
public CompileError(String message, Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
|
|||||||
RValue rValue1 = origAssignment.getrValue1();
|
RValue rValue1 = origAssignment.getrValue1();
|
||||||
Operator operator = origAssignment.getOperator();
|
Operator operator = origAssignment.getOperator();
|
||||||
RValue rValue2 = origAssignment.getrValue2();
|
RValue rValue2 = origAssignment.getrValue2();
|
||||||
return new StatementAssignment(lValue, rValue1, operator, rValue2);
|
return new StatementAssignment(lValue, rValue1, operator, rValue2, origAssignment.getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -151,19 +151,19 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
|
|||||||
Operator operator = origConditionalJump.getOperator();
|
Operator operator = origConditionalJump.getOperator();
|
||||||
RValue rValue2 = origConditionalJump.getrValue2();
|
RValue rValue2 = origConditionalJump.getrValue2();
|
||||||
LabelRef destination = origConditionalJump.getDestination();
|
LabelRef destination = origConditionalJump.getDestination();
|
||||||
return new StatementConditionalJump(rValue1, operator, rValue2, destination);
|
return new StatementConditionalJump(rValue1, operator, rValue2, destination, origConditionalJump.getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatementJump visitJump(StatementJump origJump) {
|
public StatementJump visitJump(StatementJump origJump) {
|
||||||
LabelRef destination = origJump.getDestination();
|
LabelRef destination = origJump.getDestination();
|
||||||
return new StatementJump(destination);
|
return new StatementJump(destination, origJump.getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatementLabel visitJumpTarget(StatementLabel origJump) {
|
public StatementLabel visitJumpTarget(StatementLabel origJump) {
|
||||||
LabelRef label = origJump.getLabel();
|
LabelRef label = origJump.getLabel();
|
||||||
return new StatementLabel(label);
|
return new StatementLabel(label, origJump.getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -171,26 +171,26 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
|
|||||||
LValue lValue = origCall.getlValue();
|
LValue lValue = origCall.getlValue();
|
||||||
String procedureName = origCall.getProcedureName();
|
String procedureName = origCall.getProcedureName();
|
||||||
List<RValue> parameters = origCall.getParameters();
|
List<RValue> parameters = origCall.getParameters();
|
||||||
return new StatementCall(lValue, procedureName, parameters);
|
return new StatementCall(lValue, procedureName, parameters, origCall.getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatementProcedureBegin visitProcedureBegin(StatementProcedureBegin origProcedureBegin) {
|
public StatementProcedureBegin visitProcedureBegin(StatementProcedureBegin origProcedureBegin) {
|
||||||
return new StatementProcedureBegin(origProcedureBegin.getProcedure());
|
return new StatementProcedureBegin(origProcedureBegin.getProcedure(), origProcedureBegin.getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatementProcedureEnd visitProcedureEnd(StatementProcedureEnd origProcedureEnd) {
|
public StatementProcedureEnd visitProcedureEnd(StatementProcedureEnd origProcedureEnd) {
|
||||||
return new StatementProcedureEnd(origProcedureEnd.getProcedure());
|
return new StatementProcedureEnd(origProcedureEnd.getProcedure(), origProcedureEnd.getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatementReturn visitReturn(StatementReturn origReturn) {
|
public StatementReturn visitReturn(StatementReturn origReturn) {
|
||||||
return new StatementReturn(origReturn.getValue());
|
return new StatementReturn(origReturn.getValue(), origReturn.getSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitAsm(StatementAsm asm) {
|
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. */
|
/** Set the index of the statement. Indexes are used during live range analysis. */
|
||||||
void setIndex(Integer idx);
|
void setIndex(Integer idx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the source for the statement*
|
||||||
|
*/
|
||||||
|
StatementSource getSource();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,9 @@ public class StatementAsm extends StatementBase {
|
|||||||
/** ASM Fragment code. */
|
/** ASM Fragment code. */
|
||||||
private KickCParser.AsmLinesContext asmLines;
|
private KickCParser.AsmLinesContext asmLines;
|
||||||
|
|
||||||
public StatementAsm(KickCParser.AsmLinesContext asmLines) {
|
public StatementAsm(KickCParser.AsmLinesContext asmLines,
|
||||||
super(null);
|
StatementSource source) {
|
||||||
|
super(null, source);
|
||||||
this.asmLines = asmLines;
|
this.asmLines = asmLines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,24 +22,16 @@ public class StatementAssignment extends StatementBase implements StatementLValu
|
|||||||
private Operator operator;
|
private Operator operator;
|
||||||
private RValue rValue2;
|
private RValue rValue2;
|
||||||
|
|
||||||
public StatementAssignment(LValue lValue, RValue rValue2) {
|
public StatementAssignment(LValue lValue, RValue rValue2, StatementSource source) {
|
||||||
this(lValue, null, null, rValue2, null);
|
this(lValue, null, null, rValue2, null, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatementAssignment(LValue lValue, Operator operator, RValue rValue2) {
|
public StatementAssignment(LValue lValue, Operator operator, RValue rValue2,StatementSource source) {
|
||||||
this(lValue, null, operator, rValue2, null);
|
this(lValue, null, operator, rValue2, null, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatementAssignment(LValue lValue, RValue rValue1, Operator operator, RValue rValue2) {
|
public StatementAssignment(LValue lValue, RValue rValue1, Operator operator, RValue rValue2, StatementSource source) {
|
||||||
this(lValue, rValue1, operator, rValue2, null);
|
this(lValue, rValue1, operator, rValue2, null, source);
|
||||||
}
|
|
||||||
|
|
||||||
public StatementAssignment(Variable lValue, Variable rValue2) {
|
|
||||||
this(lValue.getRef(), rValue2.getRef());
|
|
||||||
}
|
|
||||||
|
|
||||||
public StatementAssignment(Variable lValue, RValue rValue2) {
|
|
||||||
this(lValue.getRef(), rValue2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatementAssignment(
|
public StatementAssignment(
|
||||||
@ -47,8 +39,9 @@ public class StatementAssignment extends StatementBase implements StatementLValu
|
|||||||
RValue rValue1,
|
RValue rValue1,
|
||||||
Operator operator,
|
Operator operator,
|
||||||
RValue rValue2,
|
RValue rValue2,
|
||||||
Integer index) {
|
Integer index,
|
||||||
super(index);
|
StatementSource source) {
|
||||||
|
super(index, source);
|
||||||
this.lValue = lValue;
|
this.lValue = lValue;
|
||||||
this.rValue1 = rValue1;
|
this.rValue1 = rValue1;
|
||||||
this.operator = operator;
|
this.operator = operator;
|
||||||
|
@ -12,10 +12,18 @@ import java.util.List;
|
|||||||
/** Statement base class implementing shared properties and logic */
|
/** Statement base class implementing shared properties and logic */
|
||||||
public abstract class StatementBase implements Statement {
|
public abstract class StatementBase implements Statement {
|
||||||
|
|
||||||
|
private StatementSource source;
|
||||||
|
|
||||||
private Integer index;
|
private Integer index;
|
||||||
|
|
||||||
public StatementBase(Integer index) {
|
public StatementBase(Integer index, StatementSource source) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StatementSource getSource() {
|
||||||
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -22,8 +22,8 @@ public class StatementCall extends StatementBase implements StatementLValue {
|
|||||||
private ProcedureRef procedure;
|
private ProcedureRef procedure;
|
||||||
private List<RValue> parameters;
|
private List<RValue> parameters;
|
||||||
|
|
||||||
public StatementCall(LValue lValue, String procedureName, List<RValue> parameters) {
|
public StatementCall(LValue lValue, String procedureName, List<RValue> parameters, StatementSource source) {
|
||||||
super(null);
|
super(null, source);
|
||||||
this.lValue = lValue;
|
this.lValue = lValue;
|
||||||
this.procedureName = procedureName;
|
this.procedureName = procedureName;
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
|
@ -20,8 +20,8 @@ public class StatementConditionalJump extends StatementBase {
|
|||||||
private RValue rValue2;
|
private RValue rValue2;
|
||||||
private LabelRef destination;
|
private LabelRef destination;
|
||||||
|
|
||||||
public StatementConditionalJump(RValue condition, LabelRef destination) {
|
public StatementConditionalJump(RValue condition, LabelRef destination,StatementSource source) {
|
||||||
super(null);
|
super(null, source);
|
||||||
this.rValue1 = null;
|
this.rValue1 = null;
|
||||||
this.operator = null;
|
this.operator = null;
|
||||||
this.rValue2 = condition;
|
this.rValue2 = condition;
|
||||||
@ -32,8 +32,9 @@ public class StatementConditionalJump extends StatementBase {
|
|||||||
RValue rValue1,
|
RValue rValue1,
|
||||||
Operator operator,
|
Operator operator,
|
||||||
RValue rValue2,
|
RValue rValue2,
|
||||||
LabelRef destination) {
|
LabelRef destination,
|
||||||
this(rValue1, operator, rValue2, destination, null);
|
StatementSource source) {
|
||||||
|
this(rValue1, operator, rValue2, destination, null, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatementConditionalJump(
|
public StatementConditionalJump(
|
||||||
@ -41,8 +42,9 @@ public class StatementConditionalJump extends StatementBase {
|
|||||||
Operator operator,
|
Operator operator,
|
||||||
RValue rValue2,
|
RValue rValue2,
|
||||||
LabelRef destination,
|
LabelRef destination,
|
||||||
Integer index) {
|
Integer index,
|
||||||
super(index);
|
StatementSource source) {
|
||||||
|
super(index, source);
|
||||||
this.rValue1 = rValue1;
|
this.rValue1 = rValue1;
|
||||||
this.operator = operator;
|
this.operator = operator;
|
||||||
this.rValue2 = rValue2;
|
this.rValue2 = rValue2;
|
||||||
|
@ -13,8 +13,9 @@ public class StatementJump extends StatementBase {
|
|||||||
|
|
||||||
private LabelRef destination;
|
private LabelRef destination;
|
||||||
|
|
||||||
public StatementJump(LabelRef destination) {
|
public StatementJump(LabelRef destination,
|
||||||
super(null);
|
StatementSource source) {
|
||||||
|
super(null, source);
|
||||||
this.destination = destination;
|
this.destination = destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,8 +10,9 @@ public class StatementLabel extends StatementBase {
|
|||||||
|
|
||||||
private LabelRef label;
|
private LabelRef label;
|
||||||
|
|
||||||
public StatementLabel(LabelRef label) {
|
public StatementLabel(LabelRef label,
|
||||||
super(null);
|
StatementSource source) {
|
||||||
|
super(null, source);
|
||||||
this.label = label;
|
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.Program;
|
||||||
import dk.camelot64.kickc.model.values.RValue;
|
import dk.camelot64.kickc.model.values.RValue;
|
||||||
import dk.camelot64.kickc.model.values.VariableRef;
|
import dk.camelot64.kickc.model.values.VariableRef;
|
||||||
|
import org.antlr.v4.runtime.RuleContext;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -22,13 +23,14 @@ public class StatementPhiBlock extends StatementBase {
|
|||||||
|
|
||||||
public StatementPhiBlock(
|
public StatementPhiBlock(
|
||||||
List<PhiVariable> phiVariables,
|
List<PhiVariable> phiVariables,
|
||||||
Integer index) {
|
Integer index,
|
||||||
super(index);
|
StatementSource source) {
|
||||||
|
super(index, source);
|
||||||
this.phiVariables = phiVariables;
|
this.phiVariables = phiVariables;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatementPhiBlock() {
|
public StatementPhiBlock() {
|
||||||
super(null);
|
super(null, new StatementSource(RuleContext.EMPTY));
|
||||||
this.phiVariables = new ArrayList<>();
|
this.phiVariables = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,8 +10,8 @@ public class StatementProcedureBegin extends StatementBase {
|
|||||||
|
|
||||||
private Strategy strategy;
|
private Strategy strategy;
|
||||||
|
|
||||||
public StatementProcedureBegin(ProcedureRef procedure) {
|
public StatementProcedureBegin(ProcedureRef procedure,StatementSource source) {
|
||||||
super(null);
|
super(null, source);
|
||||||
this.procedure = procedure;
|
this.procedure = procedure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,8 +10,8 @@ public class StatementProcedureEnd extends StatementBase {
|
|||||||
|
|
||||||
private ProcedureRef procedure;
|
private ProcedureRef procedure;
|
||||||
|
|
||||||
public StatementProcedureEnd(ProcedureRef procedure) {
|
public StatementProcedureEnd(ProcedureRef procedure, StatementSource source) {
|
||||||
super(null);
|
super(null, source);
|
||||||
this.procedure = procedure;
|
this.procedure = procedure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ public class StatementReturn extends StatementBase {
|
|||||||
*/
|
*/
|
||||||
private RValue value;
|
private RValue value;
|
||||||
|
|
||||||
public StatementReturn(RValue value) {
|
public StatementReturn(RValue value, StatementSource source) {
|
||||||
super(null);
|
super(null, source);
|
||||||
this.value = value;
|
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());
|
parameterList = (List<Variable>) this.visit(ctx.parameterListDecl());
|
||||||
}
|
}
|
||||||
procedure.setParameters(parameterList);
|
procedure.setParameters(parameterList);
|
||||||
sequence.addStatement(new StatementProcedureBegin(procedure.getRef()));
|
sequence.addStatement(new StatementProcedureBegin(procedure.getRef(), new StatementSource(ctx)));
|
||||||
if(ctx.stmtSeq() != null) {
|
if(ctx.stmtSeq() != null) {
|
||||||
this.visit(ctx.stmtSeq());
|
this.visit(ctx.stmtSeq());
|
||||||
}
|
}
|
||||||
sequence.addStatement(new StatementLabel(procExit.getRef()));
|
sequence.addStatement(new StatementLabel(procExit.getRef(), new StatementSource(ctx)));
|
||||||
if(returnVar != null) {
|
if(returnVar != null) {
|
||||||
sequence.addStatement(new StatementAssignment(returnVar, returnVar));
|
sequence.addStatement(new StatementAssignment(returnVar.getRef(), returnVar.getRef(), new StatementSource(ctx)));
|
||||||
}
|
}
|
||||||
VariableRef returnVarRef = null;
|
VariableRef returnVarRef = null;
|
||||||
if(returnVar != null) {
|
if(returnVar != null) {
|
||||||
returnVarRef = returnVar.getRef();
|
returnVarRef = returnVar.getRef();
|
||||||
}
|
}
|
||||||
sequence.addStatement(new StatementReturn(returnVarRef));
|
sequence.addStatement(new StatementReturn(returnVarRef, new StatementSource(ctx)));
|
||||||
scopeStack.pop();
|
scopeStack.pop();
|
||||||
sequence.addStatement(new StatementProcedureEnd(procedure.getRef()));
|
sequence.addStatement(new StatementProcedureEnd(procedure.getRef(), new StatementSource(ctx)));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,9 +158,9 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
SymbolTypeArray typeArray = (SymbolTypeArray) type;
|
SymbolTypeArray typeArray = (SymbolTypeArray) type;
|
||||||
Integer size = typeArray.getSize();
|
Integer size = typeArray.getSize();
|
||||||
if(size == null) {
|
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);
|
sequence.addStatement(stmt);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -181,23 +181,24 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
directives.add((Directive) this.visit(directiveContext));
|
directives.add((Directive) this.visit(directiveContext));
|
||||||
}
|
}
|
||||||
for(Directive directive : directives) {
|
for(Directive directive : directives) {
|
||||||
|
StatementSource source = new StatementSource(directivesCtx.get(0));
|
||||||
if(directive instanceof DirectiveConst) {
|
if(directive instanceof DirectiveConst) {
|
||||||
lValue.setDeclaredConstant(true);
|
lValue.setDeclaredConstant(true);
|
||||||
} else if(directive instanceof DirectiveAlign) {
|
} else if(directive instanceof DirectiveAlign) {
|
||||||
if(type instanceof SymbolTypeArray || type.equals(SymbolType.STRING)) {
|
if(type instanceof SymbolTypeArray || type.equals(SymbolType.STRING)) {
|
||||||
lValue.setDeclaredAlignment(((DirectiveAlign) directive).getAlignment());
|
lValue.setDeclaredAlignment(((DirectiveAlign) directive).getAlignment());
|
||||||
} else {
|
} 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) {
|
} else if(directive instanceof DirectiveRegister) {
|
||||||
DirectiveRegister directiveRegister = (DirectiveRegister) directive;
|
DirectiveRegister directiveRegister = (DirectiveRegister) directive;
|
||||||
Registers.Register register = Registers.getRegister(directiveRegister.getName());
|
Registers.Register register = Registers.getRegister(directiveRegister.getName());
|
||||||
if(register == null) {
|
if(register == null) {
|
||||||
throw new CompileError("Error! Unknown register " + directiveRegister.getName());
|
throw new CompileError("Error! Unknown register " + directiveRegister.getName(), source);
|
||||||
}
|
}
|
||||||
lValue.setDeclaredRegister(register);
|
lValue.setDeclaredRegister(register);
|
||||||
} else {
|
} 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));
|
directives.add((Directive) this.visit(directiveContext));
|
||||||
}
|
}
|
||||||
for(Directive directive : directives) {
|
for(Directive directive : directives) {
|
||||||
|
StatementSource source = new StatementSource(directivesCtx.get(0));
|
||||||
if(directive instanceof DirectiveInline) {
|
if(directive instanceof DirectiveInline) {
|
||||||
procedure.setDeclaredInline(true);
|
procedure.setDeclaredInline(true);
|
||||||
} else {
|
} 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(elseStmt==null) {
|
||||||
// If without else - skip the entire section if condition not met
|
// If without else - skip the entire section if condition not met
|
||||||
VariableRef notExprVar = getCurrentSymbols().addVariableIntermediate().getRef();
|
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());
|
PrePostModifierHandler.addPostModifiers(this, ctx.expr());
|
||||||
Label endJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
Label endJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
||||||
sequence.addStatement(new StatementConditionalJump(notExprVar, endJumpLabel.getRef()));
|
sequence.addStatement(new StatementConditionalJump(notExprVar, endJumpLabel.getRef(), new StatementSource(ctx)));
|
||||||
this.visit(ifStmt);
|
this.visit(ifStmt);
|
||||||
// No else statement - just add the label
|
// No else statement - just add the label
|
||||||
sequence.addStatement(new StatementLabel(endJumpLabel.getRef()));
|
sequence.addStatement(new StatementLabel(endJumpLabel.getRef(), new StatementSource(ctx)));
|
||||||
} else {
|
} else {
|
||||||
// If with else - jump to if section if condition met - fall into else otherwise.
|
// If with else - jump to if section if condition met - fall into else otherwise.
|
||||||
PrePostModifierHandler.addPostModifiers(this, ctx.expr());
|
PrePostModifierHandler.addPostModifiers(this, ctx.expr());
|
||||||
Label ifJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
Label ifJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
||||||
sequence.addStatement(new StatementConditionalJump(rValue, ifJumpLabel.getRef()));
|
sequence.addStatement(new StatementConditionalJump(rValue, ifJumpLabel.getRef(), new StatementSource(ctx)));
|
||||||
// Add else body
|
// Add else body
|
||||||
this.visit(elseStmt);
|
this.visit(elseStmt);
|
||||||
// There is an else statement - add the if part and any needed labels/jumps
|
// There is an else statement - add the if part and any needed labels/jumps
|
||||||
Label endJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
Label endJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
||||||
sequence.addStatement(new StatementJump(endJumpLabel.getRef()));
|
sequence.addStatement(new StatementJump(endJumpLabel.getRef(), new StatementSource(ctx)));
|
||||||
sequence.addStatement(new StatementLabel(ifJumpLabel.getRef()));
|
sequence.addStatement(new StatementLabel(ifJumpLabel.getRef(), new StatementSource(ctx)));
|
||||||
this.visit(ifStmt);
|
this.visit(ifStmt);
|
||||||
StatementLabel endJumpTarget = new StatementLabel(endJumpLabel.getRef());
|
StatementLabel endJumpTarget = new StatementLabel(endJumpLabel.getRef(), new StatementSource(ctx));
|
||||||
sequence.addStatement(endJumpTarget);
|
sequence.addStatement(endJumpTarget);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -310,21 +312,21 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
Label beginJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
Label beginJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
||||||
Label doJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
Label doJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
||||||
Label endJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
Label endJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
||||||
StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel.getRef());
|
StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel.getRef(), new StatementSource(ctx));
|
||||||
sequence.addStatement(beginJumpTarget);
|
sequence.addStatement(beginJumpTarget);
|
||||||
PrePostModifierHandler.addPreModifiers(this, ctx.expr());
|
PrePostModifierHandler.addPreModifiers(this, ctx.expr());
|
||||||
RValue rValue = (RValue) this.visit(ctx.expr());
|
RValue rValue = (RValue) this.visit(ctx.expr());
|
||||||
PrePostModifierHandler.addPostModifiers(this, 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);
|
sequence.addStatement(doJmpStmt);
|
||||||
Statement endJmpStmt = new StatementJump(endJumpLabel.getRef());
|
Statement endJmpStmt = new StatementJump(endJumpLabel.getRef(), new StatementSource(ctx));
|
||||||
sequence.addStatement(endJmpStmt);
|
sequence.addStatement(endJmpStmt);
|
||||||
StatementLabel doJumpTarget = new StatementLabel(doJumpLabel.getRef());
|
StatementLabel doJumpTarget = new StatementLabel(doJumpLabel.getRef(), new StatementSource(ctx));
|
||||||
sequence.addStatement(doJumpTarget);
|
sequence.addStatement(doJumpTarget);
|
||||||
this.visit(ctx.stmt());
|
this.visit(ctx.stmt());
|
||||||
Statement beginJmpStmt = new StatementJump(beginJumpLabel.getRef());
|
Statement beginJmpStmt = new StatementJump(beginJumpLabel.getRef(), new StatementSource(ctx));
|
||||||
sequence.addStatement(beginJmpStmt);
|
sequence.addStatement(beginJmpStmt);
|
||||||
StatementLabel endJumpTarget = new StatementLabel(endJumpLabel.getRef());
|
StatementLabel endJumpTarget = new StatementLabel(endJumpLabel.getRef(), new StatementSource(ctx));
|
||||||
sequence.addStatement(endJumpTarget);
|
sequence.addStatement(endJumpTarget);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -332,7 +334,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
@Override
|
@Override
|
||||||
public Void visitStmtDoWhile(KickCParser.StmtDoWhileContext ctx) {
|
public Void visitStmtDoWhile(KickCParser.StmtDoWhileContext ctx) {
|
||||||
Label beginJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
Label beginJumpLabel = getCurrentSymbols().addLabelIntermediate();
|
||||||
StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel.getRef());
|
StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel.getRef(), new StatementSource(ctx));
|
||||||
sequence.addStatement(beginJumpTarget);
|
sequence.addStatement(beginJumpTarget);
|
||||||
if(ctx.stmt() != null) {
|
if(ctx.stmt() != null) {
|
||||||
this.visit(ctx.stmt());
|
this.visit(ctx.stmt());
|
||||||
@ -340,7 +342,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
PrePostModifierHandler.addPreModifiers(this, ctx.expr());
|
PrePostModifierHandler.addPreModifiers(this, ctx.expr());
|
||||||
RValue rValue = (RValue) this.visit(ctx.expr());
|
RValue rValue = (RValue) this.visit(ctx.expr());
|
||||||
PrePostModifierHandler.addPostModifiers(this, 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);
|
sequence.addStatement(doJmpStmt);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -379,7 +381,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
}
|
}
|
||||||
// Add label
|
// Add label
|
||||||
Label repeatLabel = getCurrentSymbols().addLabelIntermediate();
|
Label repeatLabel = getCurrentSymbols().addLabelIntermediate();
|
||||||
StatementLabel repeatTarget = new StatementLabel(repeatLabel.getRef());
|
StatementLabel repeatTarget = new StatementLabel(repeatLabel.getRef(), new StatementSource(ctx));
|
||||||
sequence.addStatement(repeatTarget);
|
sequence.addStatement(repeatTarget);
|
||||||
// Add body
|
// Add body
|
||||||
if(stmtForCtx.stmt() != null) {
|
if(stmtForCtx.stmt() != null) {
|
||||||
@ -396,7 +398,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
RValue rValue = (RValue) this.visit(ctx.expr(0));
|
RValue rValue = (RValue) this.visit(ctx.expr(0));
|
||||||
PrePostModifierHandler.addPostModifiers(this, ctx.expr(0));
|
PrePostModifierHandler.addPostModifiers(this, ctx.expr(0));
|
||||||
// Add jump if condition was met
|
// 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);
|
sequence.addStatement(doJmpStmt);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -417,7 +419,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
lValue = getCurrentSymbols().getVariable(varName);
|
lValue = getCurrentSymbols().getVariable(varName);
|
||||||
}
|
}
|
||||||
if(lValue == null) {
|
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 rangeFirstCtx = ctx.expr(0);
|
||||||
KickCParser.ExprContext rangeLastCtx = ctx.expr(1);
|
KickCParser.ExprContext rangeLastCtx = ctx.expr(1);
|
||||||
@ -426,11 +428,11 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
ConstantInteger rangeLast = (ConstantInteger) ParseTreeConstantEvaluator.evaluate(rangeLastCtx);
|
ConstantInteger rangeLast = (ConstantInteger) ParseTreeConstantEvaluator.evaluate(rangeLastCtx);
|
||||||
// Assign loop variable with first value
|
// Assign loop variable with first value
|
||||||
RValue rValue = (RValue) visit(rangeFirstCtx);
|
RValue rValue = (RValue) visit(rangeFirstCtx);
|
||||||
Statement stmtInit = new StatementAssignment(lValue, rValue);
|
Statement stmtInit = new StatementAssignment(lValue.getRef(), rValue, new StatementSource(ctx));
|
||||||
sequence.addStatement(stmtInit);
|
sequence.addStatement(stmtInit);
|
||||||
// Add label
|
// Add label
|
||||||
Label repeatLabel = getCurrentSymbols().addLabelIntermediate();
|
Label repeatLabel = getCurrentSymbols().addLabelIntermediate();
|
||||||
StatementLabel repeatTarget = new StatementLabel(repeatLabel.getRef());
|
StatementLabel repeatTarget = new StatementLabel(repeatLabel.getRef(), new StatementSource(ctx));
|
||||||
sequence.addStatement(repeatTarget);
|
sequence.addStatement(repeatTarget);
|
||||||
// Add body
|
// Add body
|
||||||
if(stmtForCtx.stmt() != null) {
|
if(stmtForCtx.stmt() != null) {
|
||||||
@ -439,7 +441,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
// Add increment
|
// Add increment
|
||||||
ConstantInteger beyondLastVal;
|
ConstantInteger beyondLastVal;
|
||||||
if(rangeFirst.getValue() > rangeLast.getValue()) {
|
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);
|
sequence.addStatement(stmtInc);
|
||||||
if(rangeLast.getValue() == 0) {
|
if(rangeLast.getValue() == 0) {
|
||||||
beyondLastVal = new ConstantInteger(255L);
|
beyondLastVal = new ConstantInteger(255L);
|
||||||
@ -447,7 +449,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
beyondLastVal = new ConstantInteger(rangeLast.getValue() - 1);
|
beyondLastVal = new ConstantInteger(rangeLast.getValue() - 1);
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
sequence.addStatement(stmtInc);
|
||||||
if(rangeLast.getValue() == 255) {
|
if(rangeLast.getValue() == 255) {
|
||||||
beyondLastVal = new ConstantInteger(0L);
|
beyondLastVal = new ConstantInteger(0L);
|
||||||
@ -459,17 +461,17 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
// Add condition i<last+1 or i<last-1
|
// Add condition i<last+1 or i<last-1
|
||||||
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
||||||
VariableRef tmpVarRef = tmpVar.getRef();
|
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);
|
sequence.addStatement(stmtTmpVar);
|
||||||
// Add jump if condition was met
|
// 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);
|
sequence.addStatement(doJmpStmt);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitStmtAsm(KickCParser.StmtAsmContext ctx) {
|
public Object visitStmtAsm(KickCParser.StmtAsmContext ctx) {
|
||||||
sequence.addStatement(new StatementAsm(ctx.asmLines()));
|
sequence.addStatement(new StatementAsm(ctx.asmLines(), new StatementSource(ctx)));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,18 +484,18 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
PrePostModifierHandler.addPreModifiers(this, exprCtx);
|
PrePostModifierHandler.addPreModifiers(this, exprCtx);
|
||||||
rValue = (RValue) this.visit(exprCtx);
|
rValue = (RValue) this.visit(exprCtx);
|
||||||
Variable returnVar = procedure.getVariable("return");
|
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);
|
PrePostModifierHandler.addPostModifiers(this, exprCtx);
|
||||||
}
|
}
|
||||||
Label returnLabel = procedure.getLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addInitialAssignment(KickCParser.ExprContext initializer, Variable lValue) {
|
private void addInitialAssignment(KickCParser.ExprContext initializer, Variable lValue) {
|
||||||
PrePostModifierHandler.addPreModifiers(this, initializer);
|
PrePostModifierHandler.addPreModifiers(this, initializer);
|
||||||
RValue rValue = (RValue) visit(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);
|
sequence.addStatement(stmt);
|
||||||
PrePostModifierHandler.addPostModifiers(this, initializer);
|
PrePostModifierHandler.addPostModifiers(this, initializer);
|
||||||
}
|
}
|
||||||
@ -547,7 +549,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
lValue = new LvalueIntermediate((VariableRef) lValue);
|
lValue = new LvalueIntermediate((VariableRef) lValue);
|
||||||
}
|
}
|
||||||
RValue rValue = (RValue) this.visit(ctx.expr(1));
|
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);
|
sequence.addStatement(stmt);
|
||||||
return lValue;
|
return lValue;
|
||||||
}
|
}
|
||||||
@ -565,7 +567,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
String op = ((TerminalNode) ctx.getChild(1)).getSymbol().getText();
|
String op = ((TerminalNode) ctx.getChild(1)).getSymbol().getText();
|
||||||
Operator operator = Operators.getBinaryCompound(op);
|
Operator operator = Operators.getBinaryCompound(op);
|
||||||
// Assignment with operator
|
// 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);
|
sequence.addStatement(stmt);
|
||||||
return lValue;
|
return lValue;
|
||||||
}
|
}
|
||||||
@ -577,7 +579,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
Operator operator = Operators.getCastUnary(castType);
|
Operator operator = Operators.getCastUnary(castType);
|
||||||
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
||||||
VariableRef tmpVarRef = tmpVar.getRef();
|
VariableRef tmpVarRef = tmpVar.getRef();
|
||||||
Statement stmt = new StatementAssignment(tmpVarRef, operator, child);
|
Statement stmt = new StatementAssignment(tmpVarRef, operator, child, new StatementSource(ctx));
|
||||||
sequence.addStatement(stmt);
|
sequence.addStatement(stmt);
|
||||||
return tmpVarRef;
|
return tmpVarRef;
|
||||||
}
|
}
|
||||||
@ -593,7 +595,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
}
|
}
|
||||||
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
||||||
VariableRef tmpVarRef = tmpVar.getRef();
|
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;
|
return tmpVarRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -649,7 +651,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
Operator operator = Operators.getBinary(op);
|
Operator operator = Operators.getBinary(op);
|
||||||
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
||||||
VariableRef tmpVarRef = tmpVar.getRef();
|
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);
|
sequence.addStatement(stmt);
|
||||||
return tmpVarRef;
|
return tmpVarRef;
|
||||||
}
|
}
|
||||||
@ -667,7 +669,7 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
Operator operator = Operators.getUnary(op);
|
Operator operator = Operators.getUnary(op);
|
||||||
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
VariableIntermediate tmpVar = getCurrentSymbols().addVariableIntermediate();
|
||||||
VariableRef tmpVarRef = tmpVar.getRef();
|
VariableRef tmpVarRef = tmpVar.getRef();
|
||||||
Statement stmt = new StatementAssignment(tmpVarRef, operator, child);
|
Statement stmt = new StatementAssignment(tmpVarRef, operator, child, new StatementSource(ctx));
|
||||||
sequence.addStatement(stmt);
|
sequence.addStatement(stmt);
|
||||||
return tmpVarRef;
|
return tmpVarRef;
|
||||||
}
|
}
|
||||||
@ -763,21 +765,22 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
PrePostModifierHandler prePostModifierHandler = new PrePostModifierHandler(parser);
|
PrePostModifierHandler prePostModifierHandler = new PrePostModifierHandler(parser);
|
||||||
prePostModifierHandler.visit(ctx);
|
prePostModifierHandler.visit(ctx);
|
||||||
List<PrePostModifier> modifiers = prePostModifierHandler.getPostMods();
|
List<PrePostModifier> modifiers = prePostModifierHandler.getPostMods();
|
||||||
addModifierStatements(parser, modifiers);
|
addModifierStatements(parser, modifiers, new StatementSource(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addPreModifiers(Pass0GenerateStatementSequence parser, ParserRuleContext ctx) {
|
public static void addPreModifiers(Pass0GenerateStatementSequence parser, ParserRuleContext ctx) {
|
||||||
PrePostModifierHandler modifierHandler = new PrePostModifierHandler(parser);
|
PrePostModifierHandler modifierHandler = new PrePostModifierHandler(parser);
|
||||||
modifierHandler.visit(ctx);
|
modifierHandler.visit(ctx);
|
||||||
List<PrePostModifier> modifiers = modifierHandler.getPreMods();
|
List<PrePostModifier> modifiers = modifierHandler.getPreMods();
|
||||||
addModifierStatements(parser, modifiers);
|
addModifierStatements(parser, modifiers, new StatementSource(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addModifierStatements(
|
private static void addModifierStatements(
|
||||||
Pass0GenerateStatementSequence parser,
|
Pass0GenerateStatementSequence parser,
|
||||||
List<PrePostModifier> modifiers) {
|
List<PrePostModifier> modifiers,
|
||||||
|
StatementSource source) {
|
||||||
for(PrePostModifier mod : modifiers) {
|
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.sequence.addStatement(stmt);
|
||||||
parser.program.getLog().append("Adding pre/post-modifier " + stmt.toString(parser.program, true));
|
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.*;
|
||||||
import dk.camelot64.kickc.model.operators.Operators;
|
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.values.LValue;
|
||||||
import dk.camelot64.kickc.model.statements.Statement;
|
import dk.camelot64.kickc.model.statements.Statement;
|
||||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
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() + "). " +
|
String msg = "ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). " +
|
||||||
"In " + assignment.toString(getProgram(), false);
|
"In " + assignment.toString(getProgram(), false);
|
||||||
getProgram().getLog().append(msg);
|
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();
|
RValue value = assignment.getrValue2();
|
||||||
if(value instanceof ValueList) {
|
if(value instanceof ValueList) {
|
||||||
if(((ValueList) value).getList().size() != declaredSize) {
|
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) {
|
} else if(value instanceof ConstantString) {
|
||||||
if(((ConstantString) value).getValue().length() != declaredSize) {
|
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) {
|
if(lValue instanceof LvalueIntermediate) {
|
||||||
VariableRef intermediateVar = ((LvalueIntermediate) lValue).getVariable();
|
VariableRef intermediateVar = ((LvalueIntermediate) lValue).getVariable();
|
||||||
StatementAssignment assignment = getGraph().getAssignment(intermediateVar);
|
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);
|
Collection<VariableRef> used = referenceInfos.getUsedVars(statement);
|
||||||
for(VariableRef usedRef : used) {
|
for(VariableRef usedRef : used) {
|
||||||
if(!defined.contains(usedRef)) {
|
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);
|
Collection<VariableRef> defd = referenceInfos.getDefinedVars(statement);
|
||||||
|
@ -69,7 +69,7 @@ public class Pass1FixLValuesLoHi extends Pass1Base {
|
|||||||
statementLValue.setlValue(tmpVarRef);
|
statementLValue.setlValue(tmpVarRef);
|
||||||
SymbolTypeInference.inferLValue(getProgram(), statementLValue, false);
|
SymbolTypeInference.inferLValue(getProgram(), statementLValue, false);
|
||||||
// Insert an extra "set low" assignment statement
|
// 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);
|
statementsIt.add(setLoHiAssignment);
|
||||||
getLog().append("Fixing lo/hi-lvalue with new tmpVar " + tmpVarRef + " " + statementLValue.toString());
|
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.ProcedureRef;
|
||||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||||
|
import org.antlr.v4.runtime.RuleContext;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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);
|
ControlFlowBlock firstBlock = getOrCreateBlock(scope.addLabel(SymbolRef.BEGIN_BLOCK_NAME).getRef(), ScopeRef.ROOT);
|
||||||
Stack<ControlFlowBlock> blockStack = new Stack<>();
|
Stack<ControlFlowBlock> blockStack = new Stack<>();
|
||||||
blockStack.push(firstBlock);
|
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()) {
|
for(Statement statement : sequence.getStatements()) {
|
||||||
ControlFlowBlock currentBlock = blockStack.peek();
|
ControlFlowBlock currentBlock = blockStack.peek();
|
||||||
Symbol currentBlockLabel = scope.getSymbol(currentBlock.getLabel());
|
Symbol currentBlockLabel = scope.getSymbol(currentBlock.getLabel());
|
||||||
|
@ -58,7 +58,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
|
|||||||
if(assignedSymbol.isDeclaredConstant()) {
|
if(assignedSymbol.isDeclaredConstant()) {
|
||||||
Collection<VariableVersion> versions = assignedVar.getScope().getVersions(assignedSymbol);
|
Collection<VariableVersion> versions = assignedVar.getScope().getVersions(assignedSymbol);
|
||||||
if(versions.size() != 0) {
|
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 = assignedSymbol.createVersion();
|
||||||
version.setDeclaredConstant(true);
|
version.setDeclaredConstant(true);
|
||||||
|
@ -43,7 +43,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
|
|||||||
for(int i = 0; i < parameterDecls.size(); i++) {
|
for(int i = 0; i < parameterDecls.size(); i++) {
|
||||||
Variable parameterDecl = parameterDecls.get(i);
|
Variable parameterDecl = parameterDecls.get(i);
|
||||||
RValue parameterValue = parameterValues.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();
|
String procedureName = origCall.getProcedureName();
|
||||||
Variable procReturnVar = procedure.getVariable("return");
|
Variable procReturnVar = procedure.getVariable("return");
|
||||||
@ -51,7 +51,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
|
|||||||
if(procReturnVar != null) {
|
if(procReturnVar != null) {
|
||||||
procReturnVarRef = procReturnVar.getRef();
|
procReturnVarRef = procReturnVar.getRef();
|
||||||
}
|
}
|
||||||
StatementCall copyCall = new StatementCall(procReturnVarRef, procedureName, null);
|
StatementCall copyCall = new StatementCall(procReturnVarRef, procedureName, null, origCall.getSource());
|
||||||
copyCall.setProcedure(procedureRef);
|
copyCall.setProcedure(procedureRef);
|
||||||
addStatementToCurrentBlock(copyCall);
|
addStatementToCurrentBlock(copyCall);
|
||||||
getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
|
getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
|
||||||
@ -64,7 +64,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
|
|||||||
}
|
}
|
||||||
splitCurrentBlock(currentBlockScope.addLabelIntermediate().getRef());
|
splitCurrentBlock(currentBlockScope.addLabelIntermediate().getRef());
|
||||||
if(!SymbolType.VOID.equals(procedure.getReturnType()) && origCall.getlValue() != null) {
|
if(!SymbolType.VOID.equals(procedure.getReturnType()) && origCall.getlValue() != null) {
|
||||||
addStatementToCurrentBlock(new StatementAssignment(origCall.getlValue(), procReturnVarRef));
|
addStatementToCurrentBlock(new StatementAssignment(origCall.getlValue(), procReturnVarRef, origCall.getSource()));
|
||||||
} else {
|
} else {
|
||||||
// No return type. Remove variable receiving the result.
|
// No return type. Remove variable receiving the result.
|
||||||
LValue lValue = origCall.getlValue();
|
LValue lValue = origCall.getlValue();
|
||||||
@ -77,7 +77,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
|
|||||||
// Add self-assignments for all variables modified in the procedure
|
// Add self-assignments for all variables modified in the procedure
|
||||||
Set<VariableRef> modifiedVars = program.getProcedureModifiedVars().getModifiedVars(procedure.getRef());
|
Set<VariableRef> modifiedVars = program.getProcedureModifiedVars().getModifiedVars(procedure.getRef());
|
||||||
for(VariableRef modifiedVar : modifiedVars) {
|
for(VariableRef modifiedVar : modifiedVars) {
|
||||||
addStatementToCurrentBlock(new StatementAssignment(modifiedVar, modifiedVar));
|
addStatementToCurrentBlock(new StatementAssignment(modifiedVar, modifiedVar, origCall.getSource()));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
|
|||||||
// Add self-assignments for all variables modified in the procedure
|
// Add self-assignments for all variables modified in the procedure
|
||||||
Set<VariableRef> modifiedVars = program.getProcedureModifiedVars().getModifiedVars(procedure.getRef());
|
Set<VariableRef> modifiedVars = program.getProcedureModifiedVars().getModifiedVars(procedure.getRef());
|
||||||
for(VariableRef modifiedVar : modifiedVars) {
|
for(VariableRef modifiedVar : modifiedVars) {
|
||||||
addStatementToCurrentBlock(new StatementAssignment(modifiedVar, modifiedVar));
|
addStatementToCurrentBlock(new StatementAssignment(modifiedVar, modifiedVar, origReturn.getSource()));
|
||||||
}
|
}
|
||||||
return super.visitReturn(origReturn);
|
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.Label;
|
||||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
|
import org.antlr.v4.runtime.RuleContext;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
|
|||||||
ProcedureRef procedureRef = origCall.getProcedure();
|
ProcedureRef procedureRef = origCall.getProcedure();
|
||||||
Procedure procedure = program.getScope().getProcedure(procedureRef);
|
Procedure procedure = program.getScope().getProcedure(procedureRef);
|
||||||
String procedureName = origCall.getProcedureName();
|
String procedureName = origCall.getProcedureName();
|
||||||
StatementCall copyCall = new StatementCall(null, procedureName, null);
|
StatementCall copyCall = new StatementCall(null, procedureName, null, origCall.getSource());
|
||||||
copyCall.setProcedure(procedureRef);
|
copyCall.setProcedure(procedureRef);
|
||||||
addStatementToCurrentBlock(copyCall);
|
addStatementToCurrentBlock(copyCall);
|
||||||
getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
|
getCurrentBlock().setCallSuccessor(procedure.getLabel().getRef());
|
||||||
@ -53,7 +54,7 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
|
|||||||
if(returnVarFinal == null) {
|
if(returnVarFinal == null) {
|
||||||
throw new RuntimeException("Error! Cannot find final return variable for " + procedure.getFullName());
|
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);
|
addStatementToCurrentBlock(returnAssignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +103,7 @@ public class Pass1ProcedureCallsReturnValue extends ControlFlowGraphCopyVisitor
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatementReturn visitReturn(StatementReturn origReturn) {
|
public StatementReturn visitReturn(StatementReturn origReturn) {
|
||||||
addStatementToCurrentBlock(new StatementReturn(null));
|
addStatementToCurrentBlock(new StatementReturn(null, origReturn.getSource()));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ public class Pass1ProcedureInline extends Pass1Base {
|
|||||||
Variable procReturnVar = procedure.getVariable("return");
|
Variable procReturnVar = procedure.getVariable("return");
|
||||||
String inlinedReturnVarName = getInlineSymbolName(procedure, procReturnVar, serial);
|
String inlinedReturnVarName = getInlineSymbolName(procedure, procReturnVar, serial);
|
||||||
Variable inlinedReturnVar = callScope.getVariable(inlinedReturnVarName);
|
Variable inlinedReturnVar = callScope.getVariable(inlinedReturnVarName);
|
||||||
restBlock.addStatement(new StatementAssignment(call.getlValue(), inlinedReturnVar.getRef()));
|
restBlock.addStatement(new StatementAssignment(call.getlValue(), inlinedReturnVar.getRef(), call.getSource()));
|
||||||
} else {
|
} else {
|
||||||
// Remove the tmp var receiving the result
|
// Remove the tmp var receiving the result
|
||||||
LValue lValue = call.getlValue();
|
LValue lValue = call.getlValue();
|
||||||
@ -165,10 +165,10 @@ public class Pass1ProcedureInline extends Pass1Base {
|
|||||||
Statement inlinedStatement;
|
Statement inlinedStatement;
|
||||||
if(procStatement instanceof StatementAssignment) {
|
if(procStatement instanceof StatementAssignment) {
|
||||||
StatementAssignment procAssignment = (StatementAssignment) procStatement;
|
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) {
|
} else if(procStatement instanceof StatementCall) {
|
||||||
StatementCall procCall = (StatementCall) procStatement;
|
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());
|
inlinedCall.setProcedure(procCall.getProcedure());
|
||||||
inlinedStatement = inlinedCall;
|
inlinedStatement = inlinedCall;
|
||||||
} else if(procStatement instanceof StatementConditionalJump) {
|
} else if(procStatement instanceof StatementConditionalJump) {
|
||||||
@ -180,12 +180,12 @@ public class Pass1ProcedureInline extends Pass1Base {
|
|||||||
String inlineSymbolName = getInlineSymbolName(procedure, procDestination, serial);
|
String inlineSymbolName = getInlineSymbolName(procedure, procDestination, serial);
|
||||||
inlinedDest = callScope.getLabel(inlineSymbolName);
|
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) {
|
} else if(procStatement instanceof StatementReturn) {
|
||||||
// No statement needed
|
// No statement needed
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} 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) {
|
if(inlinedStatement!=null) {
|
||||||
ValueReplacer.executeAll(inlinedStatement, new RValueInliner(procedure, serial, callScope), null, 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);
|
String inlineParameterVarName = getInlineSymbolName(procedure, parameterDecl, serial);
|
||||||
Variable inlineParameterVar = callScope.getVariable(inlineParameterVarName);
|
Variable inlineParameterVar = callScope.getVariable(inlineParameterVarName);
|
||||||
RValue parameterValue = parameterValues.get(i);
|
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());
|
replaceable.set(variable.getRef());
|
||||||
} else {
|
} else {
|
||||||
getLog().append("ERROR! Unknown variable " + varName);
|
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());
|
Scope currentScope = getScope().getScope(block.getScope());
|
||||||
Procedure procedure = currentScope.getProcedure(procedureName);
|
Procedure procedure = currentScope.getProcedure(procedureName);
|
||||||
if(procedure == null) {
|
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());
|
call.setProcedure(procedure.getRef());
|
||||||
if(procedure.getParameters().size() != call.getParameters().size()) {
|
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);
|
SymbolTypeInference.inferCallLValue(getProgram(), (StatementCall) statement, false);
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,12 @@ public class Pass2AssertRValues extends Pass2SsaAssertion {
|
|||||||
ValueReplacer.executeAll(getGraph(), (replaceable, currentStmt, stmtIt, currentBlock) -> {
|
ValueReplacer.executeAll(getGraph(), (replaceable, currentStmt, stmtIt, currentBlock) -> {
|
||||||
RValue rValue = replaceable.get();
|
RValue rValue = replaceable.get();
|
||||||
if(rValue instanceof ForwardVariableRef) {
|
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) {
|
if(rValue instanceof VariableRef) {
|
||||||
VariableRef variableRef = (VariableRef) rValue;
|
VariableRef variableRef = (VariableRef) rValue;
|
||||||
if(!variableRef.isIntermediate() && !variableRef.isVersion()) {
|
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
|
// Types do not match
|
||||||
getLog().append("ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). In " + statement.toString(getProgram(), false));
|
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();
|
Label newBlockLabel = currentScope.addLabelIntermediate();
|
||||||
ControlFlowBlock newBlock = new ControlFlowBlock(newBlockLabel.getRef(), currentScopeRef);
|
ControlFlowBlock newBlock = new ControlFlowBlock(newBlockLabel.getRef(), currentScopeRef);
|
||||||
getGraph().addBlock(newBlock);
|
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.setDefaultSuccessor(block.getDefaultSuccessor());
|
||||||
newBlock.setConditionalSuccessor(conditional.getDestination());
|
newBlock.setConditionalSuccessor(conditional.getDestination());
|
||||||
// Rewrite the conditional to use only the first part of the && condition expression
|
// 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();
|
Label newBlockLabel = currentScope.addLabelIntermediate();
|
||||||
ControlFlowBlock newBlock = new ControlFlowBlock(newBlockLabel.getRef(), currentScopeRef);
|
ControlFlowBlock newBlock = new ControlFlowBlock(newBlockLabel.getRef(), currentScopeRef);
|
||||||
getGraph().addBlock(newBlock);
|
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.setConditionalSuccessor(conditional.getDestination());
|
||||||
newBlock.setDefaultSuccessor(block.getDefaultSuccessor());
|
newBlock.setDefaultSuccessor(block.getDefaultSuccessor());
|
||||||
// Rewrite the conditional to use only the first part of the && condition expression
|
// 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
|
// Move backward - to insert before the current statement
|
||||||
stmtIt.previous();
|
stmtIt.previous();
|
||||||
// Add assignment of the new tmpVar
|
// 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);
|
stmtIt.add(assignment);
|
||||||
// Move back before the current statement
|
// Move back before the current statement
|
||||||
stmtIt.next();
|
stmtIt.next();
|
||||||
|
@ -23,13 +23,13 @@ public class Pass3AssertNoMulDivMod extends Pass2SsaAssertion {
|
|||||||
if(statement instanceof StatementAssignment) {
|
if(statement instanceof StatementAssignment) {
|
||||||
StatementAssignment assignment = (StatementAssignment) statement;
|
StatementAssignment assignment = (StatementAssignment) statement;
|
||||||
if(Operators.MULTIPLY.equals(assignment.getOperator())) {
|
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())) {
|
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())) {
|
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" +
|
"Error! Value list not resolved to word constructor or array initializer" +
|
||||||
"\n value list: " + value.toString(getProgram()) +
|
"\n value list: " + value.toString(getProgram()) +
|
||||||
"\n statement: " + currentStmt.toString(getProgram(), false)
|
"\n statement: " + currentStmt.toString(getProgram(), false)
|
||||||
|
, currentStmt.getSource()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -61,7 +61,7 @@ public class Pass3PhiLifting {
|
|||||||
if(predecessorStatements.size() > 0) {
|
if(predecessorStatements.size() > 0) {
|
||||||
lastPredecessorStatement = predecessorStatements.get(predecessorStatements.size() - 1);
|
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) {
|
if(lastPredecessorStatement instanceof StatementConditionalJump) {
|
||||||
// Use or Create a new block between the predecessor and this one - getReplacement labels where appropriate
|
// Use or Create a new block between the predecessor and this one - getReplacement labels where appropriate
|
||||||
ControlFlowBlock newBlock;
|
ControlFlowBlock newBlock;
|
||||||
|
Loading…
Reference in New Issue
Block a user