From 8446dd567be0a5a96d523793536aa36227172317 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 29 Oct 2018 02:05:22 +0100 Subject: [PATCH] assignments again --- compiler/examples/test.p8 | 210 ++++++++++-------- compiler/src/prog8/ast/AstChecker.kt | 2 +- .../src/prog8/compiler/target/c64/AsmGen.kt | 164 ++++++++------ 3 files changed, 210 insertions(+), 166 deletions(-) diff --git a/compiler/examples/test.p8 b/compiler/examples/test.p8 index 2cbccac6c..03a61a619 100644 --- a/compiler/examples/test.p8 +++ b/compiler/examples/test.p8 @@ -59,104 +59,122 @@ byte_assignment_to_register: A = X A = ub A = mubyte - A = ubarr1[2] - A = ubmatrix1[1,2] - A = string[4] A = AY[4] + A = ubarr1[2] + A = string[4] + A = string[X] + A = string[b] + A = string[ub] + A = ubarr1[X] + A = ubarr1[b] + A = ubarr1[ub] + A = AY[Y] + A = AY[b] + A = AY[ub] + A = ubmatrix1[1,2] + ;A = ubmatrix1[1,Y] ; todo via evaluation + A = ubmatrix1[X,2] ; todo via evaluation TODO fix error constant y dimension of index should have been const-folded with x into one value + ;A = ubmatrix1[X,Y] ; todo via evaluation + ;A = ubmatrix1[1,b2] ; todo via evaluation + ;A = ubmatrix1[X,b2] ; todo via evaluation + A = ubmatrix1[b2,2] ; todo FIX ERROR constant y dimension of index should have been const-folded with x into one value + ;A = ubmatrix1[b2,X] ; todo via evaluation + ;A = ubmatrix1[b,b2] ; todo via evaluation + ;A = ubmatrix1[ub,ub2] ; todo via evaluation -byte_assignment_to_bytevar: - b = 42 - b = b2 - b = mbyte - b = barr1[2] - b = bmatrix1[1,2] - - ub = 42 - ub = X - ub = ub2 - ub = mubyte - ub = ubarr1[2] - ub = ubmatrix1[1,2] - ub = string[4] - ub = AY[4] - - -; all possible assignments to a WORD VARIABLE (not array) - -word_assignment_to_registerpair: - AY = 42 - AY = 42.w - AY = 42555 - AY = X - AY = XY - AY = ub - AY = mubyte - AY = ubarr1[2] - AY = ubmatrix1[1,2] - AY = string[4] - AY = uw - AY = muword - AY = uwarr1[2] - AY = string[4] - AY = XY[4] - -;word_assignment_to_wordvar: - w = -42 - w = -42.w - w = -12345 - w = X - w = b2 - w = ub2 - w = w2 - w = mbyte - w = mubyte - w = mword - w = barr1[2] - w = ubarr1[2] - w = warr1[2] - w = bmatrix1[1,2] - w = ubmatrix1[1,2] - w = string[4] - w = AY[4] - - uw = 42 - uw = 42.w - uw = 42555 - uw = X - uw = AY - uw = ub2 - uw = uw2 - uw = mubyte - uw = muword - uw = ubarr1[2] - uw = uwarr1[2] - uw = ubmatrix1[1,2] - uw = string[4] - uw = AY[4] - - -; all possible assignments to a FLOAT VARIABLE -float_assignment_to_floatvar: - fl1 = 34 - fl1 = 34555.w - fl1 = 3.33e22 - fl1 = X - fl1 = AY - fl1 = b2 - fl1 = ub2 - fl1 = w2 - fl1 = uw2 - fl1 = mbyte - fl1 = mubyte - fl1 = mword - fl1 = muword - fl1 = barr1[2] - fl1 = ubarr1[2] - fl1 = warr1[2] - fl1 = uwarr1[2] - fl1 = bmatrix1[1,2] - fl1 = ubmatrix1[1,2] - fl1 = string[4] +;byte_assignment_to_bytevar: +; b = 42 +; b = b2 +; b = mbyte +; b = barr1[2] +; b = bmatrix1[1,2] +; +; ub = 42 +; ub = X +; ub = ub2 +; ub = mubyte +; ub = ubarr1[2] +; ub = ubmatrix1[1,2] +; ub = string[4] +; ub = AY[4] +; +; +;; all possible assignments to a WORD VARIABLE (not array) +; +;word_assignment_to_registerpair: +; AY = 42 +; AY = 42.w +; AY = 42555 +; AY = X +; AY = XY +; AY = ub +; AY = mubyte +; AY = ubarr1[2] +; AY = ubmatrix1[1,2] +; AY = string[4] +; AY = uw +; AY = muword +; AY = uwarr1[2] +; AY = string[4] +; AY = XY[4] +; +;;word_assignment_to_wordvar: +; w = -42 +; w = -42.w +; w = -12345 +; w = X +; w = b2 +; w = ub2 +; w = w2 +; w = mbyte +; w = mubyte +; w = mword +; w = barr1[2] +; w = ubarr1[2] +; w = warr1[2] +; w = bmatrix1[1,2] +; w = ubmatrix1[1,2] +; w = string[4] +; w = AY[4] +; +; uw = 42 +; uw = 42.w +; uw = 42555 +; uw = X +; uw = AY +; uw = ub2 +; uw = uw2 +; uw = mubyte +; uw = muword +; uw = ubarr1[2] +; uw = uwarr1[2] +; uw = ubmatrix1[1,2] +; uw = string[4] +; uw = AY[4] +; +; +;; all possible assignments to a FLOAT VARIABLE +;float_assignment_to_floatvar: +; fl1 = 34 +; fl1 = 34555.w +; fl1 = 3.33e22 +; fl1 = X +; fl1 = AY +; fl1 = b2 +; fl1 = ub2 +; fl1 = w2 +; fl1 = uw2 +; fl1 = mbyte +; fl1 = mubyte +; fl1 = mword +; fl1 = muword +; fl1 = barr1[2] +; fl1 = ubarr1[2] +; fl1 = warr1[2] +; fl1 = uwarr1[2] +; fl1 = bmatrix1[1,2] +; fl1 = ubmatrix1[1,2] +; fl1 = string[4] return } diff --git a/compiler/src/prog8/ast/AstChecker.kt b/compiler/src/prog8/ast/AstChecker.kt index 657451d92..8f049151d 100644 --- a/compiler/src/prog8/ast/AstChecker.kt +++ b/compiler/src/prog8/ast/AstChecker.kt @@ -729,7 +729,7 @@ class AstChecker(private val namespace: INameScope, if(arraysize!=null) { // check out of bounds if((arrayIndexedExpression.arrayspec.y as? LiteralValue)?.asIntegerValue != null) { - throw FatalAstException("constant y dimension of index should have been const-folded with x into one value") + throw FatalAstException("constant y dimension of index should have been const-folded with x into one value ${arrayIndexedExpression.arrayspec.position}") } val index = (arrayIndexedExpression.arrayspec.x as? LiteralValue)?.asIntegerValue if(index!=null && (index<0 || index>=arraysize)) diff --git a/compiler/src/prog8/compiler/target/c64/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/AsmGen.kt index 3c7173a41..b95e449e6 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmGen.kt @@ -704,8 +704,13 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, } } - for(pattern in patterns.filter { it.sequence.size <= segment.size}) { - if(pattern.sequence == opcodes.subList(0, pattern.sequence.size)) { + for(pattern in patterns.filter { it.sequence.size <= segment.size || (it.altSequence != null && it.altSequence.size <= segment.size)}) { + val opcodesList = opcodes.subList(0, pattern.sequence.size) + if(pattern.sequence == opcodesList) { + val asm = pattern.asm(segment) + if(asm!=null) + result.add(AsmFragment(asm, pattern.sequence.size)) + } else if(pattern.altSequence == opcodesList) { val asm = pattern.asm(segment) if(asm!=null) result.add(AsmFragment(asm, pattern.sequence.size)) @@ -905,7 +910,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, class AsmFragment(val asm: String, var segmentSize: Int=0) - class AsmPattern(val sequence: List, val asm: (List)->String?) + class AsmPattern(val sequence: List, val altSequence: List?=null, val asm: (List)->String?) private val patterns = listOf( @@ -953,13 +958,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, } }, // var = mem (u)byte - AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.POP_VAR_BYTE)) { segment -> - when(segment[1].callLabel) { - "A", "X", "Y" -> " ld${segment[1].callLabel!!.toLowerCase()} ${segment[0].arg!!.integerValue().toHex()}" - else -> " lda ${segment[0].arg!!.integerValue().toHex()} | sta ${segment[1].callLabel}" - } - }, - AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.POP_VAR_BYTE)) { segment -> + AsmPattern( + listOf(Opcode.PUSH_MEM_B, Opcode.POP_VAR_BYTE), + listOf(Opcode.PUSH_MEM_UB, Opcode.POP_VAR_BYTE)) { segment -> when(segment[1].callLabel) { "A", "X", "Y" -> " ld${segment[1].callLabel!!.toLowerCase()} ${segment[0].arg!!.integerValue().toHex()}" else -> " lda ${segment[0].arg!!.integerValue().toHex()} | sta ${segment[1].callLabel}" @@ -998,7 +999,68 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, }, // var = bytearray[indexvar] AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.POP_VAR_BYTE)) { segment -> - TODO("$segment") + // TODO reuse: load byte in A + val setupPtr: String + val loadByte: String + when(segment[1].callLabel) { + "AX" -> { + setupPtr = "sta ${C64Zeropage.SCRATCH_W1} | stx ${C64Zeropage.SCRATCH_W1 + 1} " + loadByte = when (segment[0].callLabel) { + "A" -> "tay | lda (${C64Zeropage.SCRATCH_W1}),y" + "X" -> "txa | tay | lda (${C64Zeropage.SCRATCH_W1}),y" + "Y" -> "lda (${C64Zeropage.SCRATCH_W1}),y" + else -> "ldy ${segment[0].callLabel} | lda (${C64Zeropage.SCRATCH_W1}),y" + } + } + "AY" -> { + setupPtr = " sta ${C64Zeropage.SCRATCH_W1} | sty ${C64Zeropage.SCRATCH_W1 + 1} " + loadByte = when (segment[0].callLabel) { + "A" -> "tay | lda (${C64Zeropage.SCRATCH_W1}),y" + "X" -> "txa | tay | lda (${C64Zeropage.SCRATCH_W1}),y" + "Y" -> "lda (${C64Zeropage.SCRATCH_W1}),y" + else -> "ldy ${segment[0].callLabel} | lda (${C64Zeropage.SCRATCH_W1}),y" + } + } + "XY" -> { + setupPtr = " stx ${C64Zeropage.SCRATCH_W1} | sty ${C64Zeropage.SCRATCH_W1 + 1} " + loadByte = when (segment[0].callLabel) { + "A" -> "tay | lda (${C64Zeropage.SCRATCH_W1}),y" + "X" -> "txa | tay | lda (${C64Zeropage.SCRATCH_W1}),y" + "Y" -> "lda (${C64Zeropage.SCRATCH_W1}),y" + else -> "ldy ${segment[0].callLabel} | lda (${C64Zeropage.SCRATCH_W1}),y" + } + } + else -> { + when (segment[0].callLabel) { + "A" -> { + setupPtr = "" + loadByte = "tay | lda ${segment[1].callLabel},y" + } + "X" -> { + setupPtr = "" + loadByte = "txa | tay | lda ${segment[1].callLabel},y" + } + "Y" -> { + setupPtr = "" + loadByte = "lda ${segment[1].callLabel},y" + } + else -> { + setupPtr = "" + loadByte = "ldy ${segment[0].callLabel} | lda ${segment[1].callLabel},y" + } + } + } + } + + // store A in target + val storeByte = when(segment[2].callLabel) { + "A" -> "" + "X" -> " tax" + "Y" -> " tya" + else -> " sta ${segment[2].callLabel}" + } + + " $setupPtr | $loadByte | $storeByte" }, @@ -1089,21 +1151,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, } }, // var = mem (u)word - AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.POP_VAR_WORD)) { segment -> - when(segment[1].callLabel) { - "AX" -> " lda ${segment[0].arg!!.integerValue().toHex()} | ldx ${(segment[0].arg!!.integerValue()+1).toHex()}" - "AY" -> " lda ${segment[0].arg!!.integerValue().toHex()} | ldy ${(segment[0].arg!!.integerValue()+1).toHex()}" - "XY" -> " ldx ${segment[0].arg!!.integerValue().toHex()} | ldy ${(segment[0].arg!!.integerValue()+1).toHex()}" - else -> - """ - lda ${segment[0].arg!!.integerValue().toHex()} - sta ${segment[1].callLabel} - lda ${(segment[0].arg!!.integerValue()+1).toHex()} - sta ${segment[1].callLabel}+1 - """ - } - }, - AsmPattern(listOf(Opcode.PUSH_MEM_UW, Opcode.POP_VAR_WORD)) { segment -> + AsmPattern( + listOf(Opcode.PUSH_MEM_W, Opcode.POP_VAR_WORD), + listOf(Opcode.PUSH_MEM_UW, Opcode.POP_VAR_WORD)) { segment -> when(segment[1].callLabel) { "AX" -> " lda ${segment[0].arg!!.integerValue().toHex()} | ldx ${(segment[0].arg!!.integerValue()+1).toHex()}" "AY" -> " lda ${segment[0].arg!!.integerValue().toHex()} | ldy ${(segment[0].arg!!.integerValue()+1).toHex()}" @@ -1209,14 +1259,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, else -> " lda ${segment[1].callLabel}+$index | sta ${segment[2].callLabel} | lda ${segment[1].callLabel}+${index+1} | sta ${segment[2].callLabel}+1" } }, - // var = bytearray[indexvar] (sign extended) - AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_VAR_WORD)) { segment -> - TODO("$segment") - }, - // var = (u)wordarray[indexvar] - AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_VAR_WORD)) { segment -> - TODO("$segment") - }, + // var = bytearray[indexvar] (sign extended) VIA REGULAR STACK EVALUATION: Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_VAR_WORD + // TODO: UB2UWORD + POP_VAR_WORD special pattern? + // var = (u)wordarray[indexvar] VIA REGULAR STACK EVALUATION: Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_VAR_WORD // ----------- assignment to MEMORY WORD ---------------- @@ -1458,17 +1503,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment -> TODO("$segment") }, - // floatvar = floatarray[indexvar] - AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment -> - TODO("$segment") - }, - // floatvar = floatarray[mem index (u)byte] - AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment -> - TODO("$segment") - }, - AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment -> - TODO("$segment") - }, + // floatvar = floatarray[indexvar] VIA REGULAR STACK EVALUATION FOR NOW: Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT) TODO Optimize this in special pattern? + // floatvar = floatarray[mem index (u)byte] VIA REGULAR STACK EVALUATION FOR NOW: Opcode.PUSH_MEM_[U]B, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT TODO Optimize this in special pattern? @@ -1548,10 +1584,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, }, // assignment: bytearray[memory (u)byte] = byte - AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - TODO("$segment") - }, - AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> + AsmPattern( + listOf(Opcode.PUSH_BYTE, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_BYTE), + listOf(Opcode.PUSH_BYTE, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> TODO("$segment") }, @@ -1565,16 +1600,16 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, }, // assignment: bytearray[mem (u)byte] = bytevar - AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> - TODO("$segment") - }, - AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> + AsmPattern( + listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_BYTE), + listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> TODO("$segment") }, // assignment: bytearray[idxbyte] = membyte AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> val index = segment[1].arg!!.integerValue() + TODO("registerpair array") // same as below??? " lda ${segment[0].arg!!.integerValue().toHex()} | sta ${segment[2].callLabel}+$index " }, // assignment: bytearray[idxbyte] = memubyte @@ -1599,10 +1634,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, }, // assignment: wordarray[memory (u)byte] = word - AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - TODO("$segment") - }, - AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> + AsmPattern( + listOf(Opcode.PUSH_WORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD), + listOf(Opcode.PUSH_WORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> TODO("$segment") }, @@ -1630,18 +1664,10 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> TODO("$segment") }, - // assignment: wordarray[idxbyte] = memword - AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> - val index = segment[1].arg!!.integerValue()*2 - """ - lda ${segment[0].arg!!.integerValue().toHex()} - ldy ${(segment[0].arg!!.integerValue()+1).toHex()} - sta ${segment[2].callLabel}+$index - sty ${segment[2].callLabel}+${index+1} - """ - }, - // assignment: wordarray[idxbyte] = memuword (=same as above) - AsmPattern(listOf(Opcode.PUSH_MEM_UW, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> + // assignment: wordarray[idxbyte] = mem(u)word + AsmPattern( + listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD), + listOf(Opcode.PUSH_MEM_UW, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> val index = segment[1].arg!!.integerValue()*2 """ lda ${segment[0].arg!!.integerValue().toHex()}