fix compiler crash on ptrvar[n+1] = ptrvar[2]

This commit is contained in:
Irmen de Jong 2023-11-14 21:46:11 +01:00
parent 86c6530e46
commit 0c9daf6eaf
4 changed files with 60 additions and 28 deletions

View File

@ -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

View File

@ -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
}
})

View File

@ -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?)

View File

@ -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
}
}