From 71fc9631458263e80f0c18bbe2c9793820597c20 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sat, 7 Sep 2019 16:14:08 +0200 Subject: [PATCH] Improved error reporting when generating ASM statement fails. Added missing fragment. Added another test showing problems with number resolving. --- src/main/fragment/vduz1=vduz2_ror_vbuxx.asm | 18 ++++++++++++++++++ .../kickc/fragment/AsmFragmentInstance.java | 5 +++-- .../dk/camelot64/kickc/model/CompileError.java | 7 +++++++ .../kickc/passes/Pass4CodeGeneration.java | 13 ++++++++----- .../dk/camelot64/kickc/test/TestPrograms.java | 7 +++++++ src/test/kc/const-bool-0.kc | 9 +++++++++ 6 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 src/main/fragment/vduz1=vduz2_ror_vbuxx.asm create mode 100644 src/test/kc/const-bool-0.kc diff --git a/src/main/fragment/vduz1=vduz2_ror_vbuxx.asm b/src/main/fragment/vduz1=vduz2_ror_vbuxx.asm new file mode 100644 index 000000000..bb43bc060 --- /dev/null +++ b/src/main/fragment/vduz1=vduz2_ror_vbuxx.asm @@ -0,0 +1,18 @@ +lda {z2} +sta {z1} +lda {z2}+1 +sta {z1}+1 +lda {z2}+2 +sta {z1}+2 +lda {z2}+3 +sta {z1}+3 +cpx #0 +beq !e+ +!: +lsr {z1}+3 +ror {z1}+2 +ror {z1}+1 +ror {z1} +dex +bne !- +!e: \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java index 723d46ccc..98cbc1195 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java @@ -3,6 +3,7 @@ package dk.camelot64.kickc.fragment; import dk.camelot64.kickc.NumberParser; import dk.camelot64.kickc.asm.*; import dk.camelot64.kickc.model.ConstantNotLiteral; +import dk.camelot64.kickc.model.InternalError; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.Registers; import dk.camelot64.kickc.model.symbols.ConstantVar; @@ -100,7 +101,7 @@ public class AsmFragmentInstance { String param = AsmFormat.asmFix(((Label) boundValue).getLocalName()); return new AsmParameter(param, false); } else { - throw new RuntimeException("Bound Value Type not implemented " + boundValue); + throw new InternalError("Bound Value Type not implemented " + boundValue); } } @@ -296,7 +297,7 @@ public class AsmFragmentInstance { addressingMode, parameter.isZp()); if(type == null) { - throw new RuntimeException("Error in " + name + ".asm line " + ctx.getStart().getLine() + " - Instruction type unknown " + mnemonic + " " + addressingMode + " " + parameter); + throw new InternalError("Error in " + name + ".asm line " + ctx.getStart().getLine() + " - Instruction type unknown " + mnemonic + " " + addressingMode + " " + parameter); } return new AsmInstruction(type, parameter.getParam()); } diff --git a/src/main/java/dk/camelot64/kickc/model/CompileError.java b/src/main/java/dk/camelot64/kickc/model/CompileError.java index 384c03ddf..37fd98c9d 100644 --- a/src/main/java/dk/camelot64/kickc/model/CompileError.java +++ b/src/main/java/dk/camelot64/kickc/model/CompileError.java @@ -6,12 +6,15 @@ import dk.camelot64.kickc.model.statements.StatementSource; /** Signals some error in the code (or compilation) */ public class CompileError extends RuntimeException { + private String source; + public CompileError(String message) { super(message); } public CompileError(String message, StatementSource source) { super(message+"\n"+source.toString()); + this.source = source.toString(); } public CompileError(String message, Statement statement) { @@ -21,4 +24,8 @@ public class CompileError extends RuntimeException { public CompileError(String message, Throwable cause) { super(message, cause); } + + public String getSource() { + return source; + } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index 15bb92551..f1f661e3f 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -654,6 +654,10 @@ public class Pass4CodeGeneration { } else { throw new CompileError("Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature(), statement.getSource()); } + } catch(CompileError e) { + if(e.getSource()==null) { + throw new CompileError(e.getMessage(), statement); + } } } } @@ -668,8 +672,7 @@ public class Pass4CodeGeneration { * @param aluState State of the special ALU register. Used to generate composite fragments when two consecutive statements can be executed effectively. * For example ADC $1100,x combines two statements $0 = $1100 staridx X, A = A+$0 . */ - public void generateStatementAsm(AsmProgram asm, ControlFlowBlock block, Statement statement, AsmCodegenAluState - aluState, boolean genCallPhiEntry) { + public void generateStatementAsm(AsmProgram asm, ControlFlowBlock block, Statement statement, AsmCodegenAluState aluState, boolean genCallPhiEntry) { asm.startChunk(block.getScope(), statement.getIndex(), statement.toString(program, verboseAliveInfo)); generateComments(asm, statement.getComments()); @@ -722,7 +725,7 @@ public class Pass4CodeGeneration { if(callSuccessor != null && callSuccessor.hasPhiBlock()) { PhiTransitions.PhiTransition transition = getTransitions(callSuccessor).getTransition(block); if(transitionIsGenerated(transition)) { - throw new RuntimeException("Error! JSR transition already generated. Must modify PhiTransitions code to ensure this does not happen."); + throw new InternalError("Error! JSR transition already generated. Must modify PhiTransitions code to ensure this does not happen."); } genBlockPhiTransition(asm, block, callSuccessor, block.getScope()); } @@ -812,10 +815,10 @@ public class Pass4CodeGeneration { asm.getCurrentChunk().setClobberOverwrite(AsmClobber.CLOBBER_ALL); } if(!supported) { - throw new RuntimeException("Call Pointer not supported " + statement); + throw new InternalError("Call Pointer not supported " + statement); } } else { - throw new RuntimeException("Statement not supported " + statement); + throw new InternalError("Statement not supported " + statement); } } } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 499fd59e3..29332c88b 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -44,6 +44,13 @@ public class TestPrograms { } */ + /** Fix number type resolving https://gitlab.com/camelot/kickc/issues/199 + @Test + public void testConstBool0() throws IOException, URISyntaxException { + compileAndCompare("const-bool-0"); + } + */ + @Test public void testAsmCullingJmp() throws IOException, URISyntaxException { compileAndCompare("asm-culling-jmp"); diff --git a/src/test/kc/const-bool-0.kc b/src/test/kc/const-bool-0.kc new file mode 100644 index 000000000..9f97b779f --- /dev/null +++ b/src/test/kc/const-bool-0.kc @@ -0,0 +1,9 @@ +// Tests a complex constant binary + +void main() { + char bError = 7; + bError &= ~(0x10 | 0x20 | 0x40); + const char* screen = 0x0400; + *screen = bError; +} +