From 0c9daf6eaf9f43dd7b3028629a62a500190a246f Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 14 Nov 2023 21:46:11 +0100 Subject: [PATCH] fix compiler crash on ptrvar[n+1] = ptrvar[2] --- .../cpu6502/assignment/AssignmentAsmGen.kt | 47 +++++++++++++------ .../test/codegeneration/TestArrayThings.kt | 18 +++++++ docs/source/todo.rst | 2 +- examples/test.p8 | 21 ++++----- 4 files changed, 60 insertions(+), 28 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index bea50807e..43ba5a367 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -2621,7 +2621,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, if(constIndex!=null) { asmgen.out(" lda #$constIndex") } else { - val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) + val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) // TODO index could also be a binexpr asmgen.out(" lda $asmvarname") } asmgen.out(" jsr floats.set_array_float_from_fac1") @@ -2658,7 +2658,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, if(constIndex!=null) { asmgen.out(" lda #$constIndex") } else { - val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) + val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) // TODO index could also be a binexpr asmgen.out(" lda $asmvarname") } asmgen.out(" jsr floats.set_array_float") @@ -2700,7 +2700,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, if(constIndex!=null) { asmgen.out(" lda #$constIndex") } else { - val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) + val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) // TODO index could also be a binexpr asmgen.out(" lda $asmvarname") } asmgen.out(" jsr floats.set_array_float") @@ -3138,6 +3138,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, throw AssemblyError("cannot assign byte to split word array here ${target.position}") if(assignsIndexedPointerVar(target)) { + // assign byte to a byte array via an uword pointervariable instead of a regular array variable if (target.constArrayIndexValue!=null) { when (register) { CpuRegister.A -> {} @@ -3162,17 +3163,33 @@ internal class AssignmentAsmGen(private val program: PtProgram, CpuRegister.X -> asmgen.out(" txa") CpuRegister.Y -> asmgen.out(" tya") } - val indexVar = target.array.index as PtIdentifier - if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { - asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta (${target.asmVarname}),y") + val indexVar = target.array.index as? PtIdentifier + if(indexVar!=null) { + if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { + asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta (${target.asmVarname}),y") + } else { + asmgen.out(""" + ldy ${target.asmVarname} + sty P8ZP_SCRATCH_W1 + ldy ${target.asmVarname}+1 + sty P8ZP_SCRATCH_W1+1 + ldy ${asmgen.asmVariableName(indexVar)} + sta (P8ZP_SCRATCH_W1),y""") + } } else { - asmgen.out(""" - ldy ${target.asmVarname} - sty P8ZP_SCRATCH_W1 - ldy ${target.asmVarname}+1 - sty P8ZP_SCRATCH_W1+1 - ldy ${asmgen.asmVariableName(indexVar)} - sta (P8ZP_SCRATCH_W1),y""") + asmgen.saveRegisterStack(register, false) + asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.Y, false) + asmgen.restoreRegisterStack(CpuRegister.A, false) + if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { + asmgen.out(" sta (${target.asmVarname}),y") + } else { + asmgen.out(""" + ldx ${target.asmVarname} + stx P8ZP_SCRATCH_W1 + ldx ${target.asmVarname}+1 + stx P8ZP_SCRATCH_W1+1 + sta (P8ZP_SCRATCH_W1),y""") + } } } return @@ -3645,7 +3662,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, sta ${target.asmVarname}+$indexValue+4 """) } else { - val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) + val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) // TODO index could also be a binexpr asmgen.out(""" lda #<${target.asmVarname} sta P8ZP_SCRATCH_W1 @@ -3694,7 +3711,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, ldy #>($arrayVarName+$indexValue) jsr floats.copy_float""") } else { - val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) + val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) // TODO index could also be a binexpr asmgen.out(""" lda #<${constFloat} sta P8ZP_SCRATCH_W1 diff --git a/compiler/test/codegeneration/TestArrayThings.kt b/compiler/test/codegeneration/TestArrayThings.kt index 14922d2a9..0f9e87eae 100644 --- a/compiler/test/codegeneration/TestArrayThings.kt +++ b/compiler/test/codegeneration/TestArrayThings.kt @@ -175,5 +175,23 @@ main { assembly shouldContain "thearray_lsb" assembly shouldContain "thearray_msb" } + + test("indexing str or pointervar with expression") { + val text = """ +main { + sub start() { + str name = "thing" + modify(name) + + sub modify(str arg) { + ubyte n=1 + uword pointervar + arg[n+1] = arg[1] + pointervar[n+1] = pointervar[1] + } + } +}""" + compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null + } }) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 809323916..17942bfba 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,7 +2,6 @@ TODO ==== -- fix the compiler crash on s1[n+1] = s1[2] where s1 is a subroutine param (regular variable works) - improve the working of %option merge: should be able to merge your own stuff into say textio. , and improve the docs about it too. - give error when using %option merge in module scope. @@ -27,6 +26,7 @@ Compiler: - Currently "320*240/8/8" gives integer overflow, so: allow constant integer subexpressions to contain out of range integers (>65535 etc) as long as the final constant value is within byte/word range. - allow 'chained' array indexing for expressions: value = ptrarray[0][0] - allow 'chained' array indexing for assign targets: ptrarray[0][0] = 42 this is just evaluating the lhs as a uword pointer expression +- fix the other cases of "TODO index could also be a binexpr" (in AssignmentAsmGen), but these are for float arrays so rarely used. - [much work:] more support for (64tass) SEGMENTS ? - (What, how, isn't current BSS support enough?) diff --git a/examples/test.p8 b/examples/test.p8 index b9e44b712..1ae0ece23 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,18 +1,15 @@ -%import string %zeropage basicsafe main { - sub start() { - cat("aaaaa") + str name = "thing" + modify(name) + + sub modify(str arg) { + ubyte n=1 + uword pointervar + arg[n+1] = arg[1] + pointervar[n+1] = pointervar[1] + } } - -sub cat(str s1) { - str s2 = "three" - ubyte n=2 - - ; s1[n+1] = s1[2] ; TODO compiler crash - s2[n+1] = s2[2] ; works fine -} - }