diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorMinus.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorMinus.java index 3053607cd..3f018c9d5 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorMinus.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorMinus.java @@ -5,6 +5,7 @@ import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypeInteger; import dk.camelot64.kickc.model.types.SymbolTypePointer; import dk.camelot64.kickc.model.types.SymbolTypeSimple; +import dk.camelot64.kickc.model.values.ConstantChar; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; import dk.camelot64.kickc.model.values.ConstantPointer; @@ -24,6 +25,8 @@ public class OperatorMinus extends OperatorBinary { } else if(left instanceof ConstantPointer && right instanceof ConstantInteger) { long location = ((ConstantPointer) left).getLocation() - ((ConstantInteger) right).getInteger(); return new ConstantPointer(location, ((ConstantPointer) left).getElementType()); + } else if(left instanceof ConstantChar && right instanceof ConstantInteger) { + return new ConstantInteger(((ConstantChar) left).getChar() - ((ConstantInteger) right).getInteger()); } throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right); } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index c68af5ba0..e89ac0f61 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -32,6 +32,16 @@ public class TestPrograms { public TestPrograms() { } + @Test + public void testLiteralCharMinusNumber() throws IOException, URISyntaxException { + compileAndCompare("literal-char-minus-number"); + } + + //@Test + //public void testPaulNelsenSandboxTernaryError() throws IOException, URISyntaxException { + // compileAndCompare("sandbox-ternary-error", log().verboseParse().verboseCreateSsa().setVerboseSSAOptimize().verboseStatementSequence()); + //} + @Test public void testPaulNelsenSandbox() throws IOException, URISyntaxException { compileAndCompare("sandbox"); diff --git a/src/test/kc/literal-char-minus-number.kc b/src/test/kc/literal-char-minus-number.kc new file mode 100644 index 000000000..f3fcccc34 --- /dev/null +++ b/src/test/kc/literal-char-minus-number.kc @@ -0,0 +1,6 @@ +// Tests subtracting a number from a literal char + +void main() { + const byte* SCREEN = 0x0400; + *SCREEN = 'a' - 1; +} \ No newline at end of file diff --git a/src/test/kc/sandbox-ternary-error.kc b/src/test/kc/sandbox-ternary-error.kc new file mode 100644 index 000000000..6937ececb --- /dev/null +++ b/src/test/kc/sandbox-ternary-error.kc @@ -0,0 +1,13 @@ +// Demonstrates error with nested ternary operator + +void main(void) { + const byte* SCREEN = 0x0400; + for ( byte b: 0..2 ) { + *SCREEN = (b == 0) ? 'a' : ((b == 1) ? 'b' : 'c'); + } +} + + + + + diff --git a/src/test/kc/sandbox.kc b/src/test/kc/sandbox.kc index 90f839738..14c8800b0 100644 --- a/src/test/kc/sandbox.kc +++ b/src/test/kc/sandbox.kc @@ -1,11 +1,11 @@ import "division" -const byte * zp1 = 0x61; // #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- +const byte * zp1 = 0x61; // #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- https://gitlab.com/camelot/kickc/issues/169 const byte * zp2 = 0x62; const byte * TIMEHI = 0xA1; const byte * TIMELO = 0xA2; const byte * VICBANK = 0xD018; -byte[16] buf16; // "char buf16[16]" is the normal way -- not supported +byte[16] buf16; // "char buf16[16]" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/162 byte[100] strTemp; // simple 'utoa' without using multiply or divide @@ -33,21 +33,22 @@ byte myprintf(byte *dst, byte *str, word w1, word w2, word w3) { for (; *str != 0; ++str) { b = *str; - if (bFormat != 0) { // "(bFormat)" is the normal way -- not supported + if (bFormat != 0) { // "(bFormat)" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/135 if (b == '0') { bLeadZero = 1; continue; } if (b >= '1' && b <= '9') { bDigits = b - '0'; continue; } if (b == '-') { bTrailing = 1; continue; } - if (b == 'c'){ // "switch" is the normal way -- not supported + if (b == 'c'){ // "switch" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/170 dst[bLen++] = (byte)w; } else if (b == 'd') { utoa(w, buf6); - b = 1; while(buf6[b] != 0) ++b; // strlen() not supported - // if (bDigits > b) is used because non-executing for loop is not supported + b = 1; while(buf6[b] != 0) ++b; // strlen() not supported -- https://gitlab.com/camelot/kickc/issues/182 + // if (bDigits > b) is used because non-executing for loop is not supported -- https://gitlab.com/camelot/kickc/issues/183 if (bTrailing == 0 && bDigits > b) for (; bDigits > b; --bDigits) dst[bLen++] = (bLeadZero == 0) ? ' ' : '0'; for (digit = 0; digit < b; ++digit) dst[bLen++] = buf6[digit]; if (bTrailing != 0 && bDigits > b) for (; bDigits > b; --bDigits) dst[bLen++] = ' '; } else if (b == 'x' || b == 'X'){ // hex - b = (w >> 4) & 0xF; dst[bLen++] = (b < 10 ? '0' : 0x57) + b; // "('a' - 10)" is the normal way -- not supported + b = (w >> 4) & 0xF; + dst[bLen++] = (b < 10 ? '0' : 0x57) + b; // "('a' - 10)" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/184 b = w & 0xF; dst[bLen++] = (b < 10 ? '0' : 0x57) + b; } bFormat = 0; @@ -56,7 +57,7 @@ byte myprintf(byte *dst, byte *str, word w1, word w2, word w3) { if (b == '%') { bFormat = 1; bLeadZero = 0; bDigits = 1; bTrailing = 0; // default format - //w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" + //w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" -- https://gitlab.com/camelot/kickc/issues/185 if (bArg == 0) w = w1; else if (bArg == 1) w = w2; else w = w3; diff --git a/src/test/ref/sandbox.asm b/src/test/ref/sandbox.asm index a8836c169..3b8c30fa4 100644 --- a/src/test/ref/sandbox.asm +++ b/src/test/ref/sandbox.asm @@ -2,7 +2,7 @@ :BasicUpstart(main) .pc = $80d "Program" .label zp1 = $61 - // #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- + // #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- https://gitlab.com/camelot/kickc/issues/169 .label zp2 = $62 .label TIMEHI = $a1 .label TIMELO = $a2 @@ -342,7 +342,7 @@ myprintf: { jmp b12 b6: lda w - // "switch" is the normal way -- not supported + // "switch" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/170 ldy bLen sta strTemp,y inc bLen @@ -361,7 +361,7 @@ myprintf: { cpx #'%' bne b28 // default format - //w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" + //w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" -- https://gitlab.com/camelot/kickc/issues/185 lda bArg cmp #0 beq b42 @@ -722,5 +722,5 @@ divr16u: { bne b1 rts } - // "char buf16[16]" is the normal way -- not supported + // "char buf16[16]" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/162 strTemp: .fill $64, 0 diff --git a/src/test/ref/sandbox.log b/src/test/ref/sandbox.log index 78165ea55..7ff508c4e 100644 --- a/src/test/ref/sandbox.log +++ b/src/test/ref/sandbox.log @@ -3876,7 +3876,7 @@ INITIAL ASM .pc = $80d "Program" //SEG2 Global Constants & labels .label zp1 = $61 - // #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- + // #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- https://gitlab.com/camelot/kickc/issues/169 .label zp2 = $62 .label TIMEHI = $a1 .label TIMELO = $a2 @@ -4671,7 +4671,7 @@ myprintf: { lda w sta _47 //SEG251 [115] *((const byte[$64]) strTemp#0 + (byte) myprintf::bLen#14) ← (byte~) myprintf::$47 -- pbuc1_derefidx_vbuz1=vbuz2 - // "switch" is the normal way -- not supported + // "switch" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/170 lda _47 ldy bLen sta strTemp,y @@ -4713,7 +4713,7 @@ myprintf: { b32: //SEG268 [120] if((byte) myprintf::bArg#12==(byte/signed byte/word/signed word/dword/signed dword) 0) goto myprintf::@42 -- vbuz1_eq_0_then_la1 // default format - //w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" + //w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" -- https://gitlab.com/camelot/kickc/issues/185 lda bArg cmp #0 beq b42 @@ -5463,7 +5463,7 @@ divr16u: { //SEG464 [212] return rts } - // "char buf16[16]" is the normal way -- not supported + // "char buf16[16]" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/162 strTemp: .fill $64, 0 REGISTER UPLIFT POTENTIAL REGISTERS @@ -5857,7 +5857,7 @@ ASSEMBLER BEFORE OPTIMIZATION .pc = $80d "Program" //SEG2 Global Constants & labels .label zp1 = $61 - // #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- + // #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- https://gitlab.com/camelot/kickc/issues/169 .label zp2 = $62 .label TIMEHI = $a1 .label TIMELO = $a2 @@ -6561,7 +6561,7 @@ myprintf: { //SEG250 [114] (byte~) myprintf::$47 ← ((byte)) (word) myprintf::w#10 -- vbuaa=_byte_vwuz1 lda w //SEG251 [115] *((const byte[$64]) strTemp#0 + (byte) myprintf::bLen#14) ← (byte~) myprintf::$47 -- pbuc1_derefidx_vbuz1=vbuaa - // "switch" is the normal way -- not supported + // "switch" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/170 ldy bLen sta strTemp,y //SEG252 [116] (byte) myprintf::bLen#1 ← ++ (byte) myprintf::bLen#14 -- vbuz1=_inc_vbuz1 @@ -6601,7 +6601,7 @@ myprintf: { b32: //SEG268 [120] if((byte) myprintf::bArg#12==(byte/signed byte/word/signed word/dword/signed dword) 0) goto myprintf::@42 -- vbuz1_eq_0_then_la1 // default format - //w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" + //w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" -- https://gitlab.com/camelot/kickc/issues/185 lda bArg cmp #0 beq b42 @@ -7235,7 +7235,7 @@ divr16u: { //SEG464 [212] return rts } - // "char buf16[16]" is the normal way -- not supported + // "char buf16[16]" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/162 strTemp: .fill $64, 0 ASSEMBLER OPTIMIZATIONS @@ -7838,7 +7838,7 @@ Score: 355871 .pc = $80d "Program" //SEG2 Global Constants & labels .label zp1 = $61 - // #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- + // #define zp1 *(byte *)0x61 -- allows "zp1" vs "*zp1" below -- not supported -- https://gitlab.com/camelot/kickc/issues/169 .label zp2 = $62 .label TIMEHI = $a1 .label TIMELO = $a2 @@ -8427,7 +8427,7 @@ myprintf: { //SEG250 [114] (byte~) myprintf::$47 ← ((byte)) (word) myprintf::w#10 -- vbuaa=_byte_vwuz1 lda w //SEG251 [115] *((const byte[$64]) strTemp#0 + (byte) myprintf::bLen#14) ← (byte~) myprintf::$47 -- pbuc1_derefidx_vbuz1=vbuaa - // "switch" is the normal way -- not supported + // "switch" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/170 ldy bLen sta strTemp,y //SEG252 [116] (byte) myprintf::bLen#1 ← ++ (byte) myprintf::bLen#14 -- vbuz1=_inc_vbuz1 @@ -8463,7 +8463,7 @@ myprintf: { //SEG267 myprintf::@32 //SEG268 [120] if((byte) myprintf::bArg#12==(byte/signed byte/word/signed word/dword/signed dword) 0) goto myprintf::@42 -- vbuz1_eq_0_then_la1 // default format - //w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" + //w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" -- https://gitlab.com/camelot/kickc/issues/185 lda bArg cmp #0 beq b42 @@ -9020,6 +9020,6 @@ divr16u: { //SEG464 [212] return rts } - // "char buf16[16]" is the normal way -- not supported + // "char buf16[16]" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/162 strTemp: .fill $64, 0