mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-26 03:32:23 +00:00
Procedure.bank is now never null.
This commit is contained in:
parent
8c7a144579
commit
8b7afa4ad0
@ -116,8 +116,23 @@ public record Bank(String bankArea, Long bankNumber) {
|
||||
public Bank {
|
||||
}
|
||||
|
||||
/** The common/shared bank which is always visible. */
|
||||
public static Bank COMMON = new Bank("", 0L);
|
||||
|
||||
/**
|
||||
* Is this the common/shared bank which is always visible.
|
||||
* @return True if this is the common bank
|
||||
*/
|
||||
public boolean isCommon() {
|
||||
return COMMON.equals(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "__bank(" + this.bankArea() + ", " + this.bankNumber() + ") ";
|
||||
if(isCommon()) {
|
||||
return "";
|
||||
} else {
|
||||
return "__bank(" + this.bankArea() + ", " + this.bankNumber() + ") ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,11 +44,9 @@ public class Procedure extends Scope {
|
||||
/**
|
||||
* The bank that the procedure code is placed in.
|
||||
* Used to decide whether to produce near, close or far call code when generating calls.
|
||||
* If null, the procedure is in a common bank (always visible) and all calls will be near.
|
||||
*/
|
||||
private Bank bank;
|
||||
|
||||
|
||||
/** The names of all legal intrinsic procedures. */
|
||||
final public static List<String> INTRINSIC_PROCEDURES = Arrays.asList(
|
||||
Pass1PrintfIntrinsicRewrite.INTRINSIC_PRINTF_NAME,
|
||||
@ -62,7 +60,7 @@ public class Procedure extends Scope {
|
||||
}
|
||||
|
||||
public void setBank(Bank bank) {
|
||||
this.bank = bank;
|
||||
this.bank = Objects.requireNonNull(bank);
|
||||
}
|
||||
|
||||
/** The bank distance between a caller and callee, which will determine the type of call needed. */
|
||||
@ -75,13 +73,13 @@ public class Procedure extends Scope {
|
||||
FAR;
|
||||
|
||||
public static CallingDistance forCall(Bank from, Bank to) {
|
||||
if(to==null) {
|
||||
if(to.isCommon()) {
|
||||
// NEAR: call to the common bank
|
||||
return NEAR;
|
||||
} else if(to.equals(from)) {
|
||||
// NEAR: call to the same bank in the same banking area
|
||||
return NEAR;
|
||||
} else if(from==null) {
|
||||
} else if(from.isCommon()) {
|
||||
// CLOSE: call from common bank to any bank
|
||||
return CLOSE;
|
||||
} else if(!from.bankArea().equals(to.bankArea())) {
|
||||
@ -146,10 +144,10 @@ public class Procedure extends Scope {
|
||||
super(name, parentScope, segmentData);
|
||||
this.procedureType = procedureType;
|
||||
this.declaredInline = false;
|
||||
this.bank = bank;
|
||||
this.bank = Objects.requireNonNull(bank);
|
||||
this.interruptType = null;
|
||||
this.comments = new ArrayList<>();
|
||||
this.segmentCode = segmentCode;
|
||||
this.segmentCode = Objects.requireNonNull(segmentCode);
|
||||
this.callingConvention = callingConvention;
|
||||
this.constructorRefs = new ArrayList<>();
|
||||
this.isConstructor = false;
|
||||
@ -260,24 +258,6 @@ public class Procedure extends Scope {
|
||||
this.declaredInline = declaredInline;
|
||||
}
|
||||
|
||||
public boolean isBanked() {
|
||||
return bank != null;
|
||||
}
|
||||
|
||||
public Long getBankNumber() {
|
||||
if(bank != null)
|
||||
return bank.bankNumber();
|
||||
else
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public String getBankArea() {
|
||||
if(bank != null)
|
||||
return bank.bankArea();
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getInterruptType() {
|
||||
return interruptType;
|
||||
}
|
||||
@ -338,9 +318,7 @@ public class Procedure extends Scope {
|
||||
if(declaredIntrinsic) {
|
||||
res.append("__intrinsic ");
|
||||
}
|
||||
if(isBanked()) {
|
||||
res.append("__bank(").append(this.getBankArea()).append(", ").append(this.getBankNumber()).append(") ");
|
||||
}
|
||||
res.append(bank.toString());
|
||||
if(!callingConvention.equals(CallingConvention.PHI_CALL)) {
|
||||
res.append(getCallingConvention().getName()).append(" ");
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public abstract class Scope implements Symbol {
|
||||
this.name = name;
|
||||
this.parentScope = parentScope;
|
||||
this.symbols = new LinkedHashMap<>();
|
||||
this.segmentData = segmentData;
|
||||
this.segmentData = Objects.requireNonNull(segmentData);
|
||||
setFullName();
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
Procedure initProc = program.getScope().getLocalProcedure(SymbolRef.INIT_PROC_NAME);
|
||||
if(initProc == null) {
|
||||
// Create the _init() procedure
|
||||
initProc = new Procedure(SymbolRef.INIT_PROC_NAME, new SymbolTypeProcedure(SymbolType.VOID, new ArrayList<>()), program.getScope(), Scope.SEGMENT_CODE_DEFAULT, Scope.SEGMENT_DATA_DEFAULT, Procedure.CallingConvention.PHI_CALL, null);
|
||||
initProc = new Procedure(SymbolRef.INIT_PROC_NAME, new SymbolTypeProcedure(SymbolType.VOID, new ArrayList<>()), program.getScope(), Scope.SEGMENT_CODE_DEFAULT, Scope.SEGMENT_DATA_DEFAULT, Procedure.CallingConvention.PHI_CALL, Bank.COMMON);
|
||||
initProc.setDeclaredInline(true);
|
||||
initProc.setParameters(new ArrayList<>());
|
||||
program.getScope().add(initProc);
|
||||
@ -187,7 +187,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
// Add the _start() procedure to the program
|
||||
{
|
||||
program.setStartProcedure(new ProcedureRef(SymbolRef.START_PROC_NAME));
|
||||
final Procedure startProcedure = new Procedure(SymbolRef.START_PROC_NAME, new SymbolTypeProcedure(SymbolType.VOID, new ArrayList<>()), program.getScope(), Scope.SEGMENT_CODE_DEFAULT, Scope.SEGMENT_DATA_DEFAULT, Procedure.CallingConvention.PHI_CALL, null);
|
||||
final Procedure startProcedure = new Procedure(SymbolRef.START_PROC_NAME, new SymbolTypeProcedure(SymbolType.VOID, new ArrayList<>()), program.getScope(), Scope.SEGMENT_CODE_DEFAULT, Scope.SEGMENT_DATA_DEFAULT, Procedure.CallingConvention.PHI_CALL, Bank.COMMON);
|
||||
startProcedure.setParameters(new ArrayList<>());
|
||||
program.getScope().add(startProcedure);
|
||||
final ProcedureCompilation startProcedureCompilation = program.createProcedureCompilation(startProcedure.getRef());
|
||||
@ -305,7 +305,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
break;
|
||||
case CParser.PRAGMA_NOBANK:
|
||||
this.currentBank = null; // When the current segment is null, the procedure will not be declared as far.
|
||||
this.currentBank = Bank.COMMON; // When the current segment is null, the procedure will not be declared as far.
|
||||
break;
|
||||
case CParser.PRAGMA_RESOURCE:
|
||||
String resourceFileName = pragmaParamString(pragmaParamSingle(ctx));
|
||||
@ -450,7 +450,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
private String currentSegmentData = Scope.SEGMENT_DATA_DEFAULT;
|
||||
|
||||
/** The current far segment. If null, the sequent procedures won't be banked. */
|
||||
private Bank currentBank;
|
||||
private Bank currentBank = Bank.COMMON;
|
||||
|
||||
/** The current default interrupt type. */
|
||||
private String currentInterruptType;
|
||||
@ -564,10 +564,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
parameterList.add(paramVar);
|
||||
}
|
||||
procedure.setParameters(parameterList);
|
||||
procedure.setSegmentData(currentSegmentData); // When a procedure is defined, the currentDataSegment is to be set.
|
||||
procedure.setSegmentCode(currentSegmentCode); // When a procedure is defined, the currentSegmentCode is to be set.
|
||||
if(procedure.getBank() == null && currentBank != null) {
|
||||
procedure.setBank(currentBank); // When a procedure is defined, the currentBank is to be set, or far calls won't work.
|
||||
procedure.setSegmentData(currentSegmentData);
|
||||
procedure.setSegmentCode(currentSegmentCode);
|
||||
if(procedure.getBank().isCommon()) {
|
||||
procedure.setBank(currentBank);
|
||||
}
|
||||
// Add return variable
|
||||
if(!SymbolType.VOID.equals(procedure.getReturnType())) {
|
||||
@ -2508,7 +2508,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
new SymbolTypeProcedure(SymbolType.DWORD, Arrays.asList(new SymbolType[]{SymbolType.BYTE, SymbolType.BYTE, SymbolType.BYTE, SymbolType.BYTE})),
|
||||
program.getScope(),
|
||||
Scope.SEGMENT_CODE_DEFAULT, Scope.SEGMENT_DATA_DEFAULT,
|
||||
Procedure.CallingConvention.INTRINSIC_CALL, null);
|
||||
Procedure.CallingConvention.INTRINSIC_CALL, Bank.COMMON);
|
||||
makeword4.setDeclaredIntrinsic(true);
|
||||
final Variable hihi = new Variable("hihi", Variable.Kind.PHI_MASTER, SymbolType.BYTE, makeword4, Variable.MemoryArea.ZEROPAGE_MEMORY, Scope.SEGMENT_DATA_DEFAULT, null);
|
||||
makeword4.add(hihi);
|
||||
|
@ -240,7 +240,7 @@ public class Pass4CodeGeneration {
|
||||
if (i > 0) {
|
||||
asm.addComment(signature.toString(), false);
|
||||
}
|
||||
if(procedure.getBank() != null) {
|
||||
if(!procedure.getBank().isCommon()) {
|
||||
asm.addComment(" " + procedure.getBank(), false);
|
||||
}
|
||||
}
|
||||
@ -583,31 +583,30 @@ public class Pass4CodeGeneration {
|
||||
if (registerMainMem.getAddress() == null) {
|
||||
// Generate into the data segment
|
||||
// Set segment
|
||||
// We check first the bank of the variable. Only local variables can be stored in the bank.
|
||||
// Parameters must be stored in main memory.
|
||||
if(!variable.getDataSegment().equals(Scope.SEGMENT_DATA_DEFAULT)) {
|
||||
if(scope instanceof Procedure) {
|
||||
Procedure procedure = (Procedure) scope;
|
||||
List<Variable> parameters = procedure.getParameters();
|
||||
if (variable.isKindPhiVersion()) {
|
||||
Variable master = variable.getPhiMaster();
|
||||
if (master != null) {
|
||||
if (parameters.contains(master) || master.getLocalName().equals("return")) {
|
||||
variable.setDataSegment(Scope.SEGMENT_DATA_DEFAULT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intermediate variables are placed at the banked data segment, but parameters and return values are kept untouched.
|
||||
if (variable.isKindIntermediate()) {
|
||||
if (scope instanceof Procedure) {
|
||||
Procedure procedure = (Procedure) scope;
|
||||
variable.setDataSegment(procedure.getSegmentData());
|
||||
}
|
||||
}
|
||||
setCurrentSegment(variable.getDataSegment(), asm);
|
||||
// // We check first the bank of the variable. Only local variables can be stored in the bank.
|
||||
// // Parameters must be stored in main memory.
|
||||
// if(!variable.getDataSegment().equals(Scope.SEGMENT_DATA_DEFAULT)) {
|
||||
// if(scope instanceof Procedure) {
|
||||
// Procedure procedure = (Procedure) scope;
|
||||
// List<Variable> parameters = procedure.getParameters();
|
||||
// if (variable.isKindPhiVersion()) {
|
||||
// Variable master = variable.getPhiMaster();
|
||||
// if (master != null) {
|
||||
// if (parameters.contains(master) || master.getLocalName().equals("return")) {
|
||||
// variable.setDataSegment(Scope.SEGMENT_DATA_DEFAULT);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Intermediate variables are placed at the banked data segment, but parameters and return values are kept untouched.
|
||||
// if (variable.isKindIntermediate()) {
|
||||
// if (scope instanceof Procedure) {
|
||||
// Procedure procedure = (Procedure) scope;
|
||||
// variable.setDataSegment(procedure.getSegmentData());
|
||||
// }
|
||||
// }
|
||||
setCurrentSegment(variable.getDataSegment(), asm);
|
||||
// Add any comments
|
||||
generateComments(asm, variable.getComments());
|
||||
|
Loading…
Reference in New Issue
Block a user