From 8b7afa4ad0f4458a387e186169053ef413e3b26f Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sun, 23 Apr 2023 22:04:23 +0200 Subject: [PATCH] Procedure.bank is now never null. --- .../camelot64/kickc/model/symbols/Bank.java | 17 ++++++- .../kickc/model/symbols/Procedure.java | 34 +++---------- .../camelot64/kickc/model/symbols/Scope.java | 2 +- .../Pass0GenerateStatementSequence.java | 18 +++---- .../kickc/passes/Pass4CodeGeneration.java | 51 +++++++++---------- 5 files changed, 57 insertions(+), 65 deletions(-) diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/Bank.java b/src/main/java/dk/camelot64/kickc/model/symbols/Bank.java index ce1ace201..446f08eb6 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Bank.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Bank.java @@ -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() + ") "; + } } } diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java b/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java index ab3b78f0f..3bcedd63e 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Procedure.java @@ -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 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(" "); } diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java b/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java index b73ae4353..a4b6e0736 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java @@ -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(); } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 9d4cf7357..a62082a72 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -130,7 +130,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor()), 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()), 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 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 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 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());