fix: array[x] = ~array[x] no longer crashes the codegen

This commit is contained in:
Irmen de Jong 2022-10-27 23:31:57 +02:00
parent 094f7803b7
commit 434515d957
5 changed files with 23 additions and 48 deletions

View File

@ -297,11 +297,10 @@ internal class AssignmentAsmGen(private val program: Program,
false, program.memsizer, assign.position
)
)
val target = virtualRegsToVariables(assign.target)
when (value.operator) {
"+" -> {}
"-" -> augmentableAsmGen.inplaceNegate(assign)
"~" -> augmentableAsmGen.inplaceInvert(target, target.datatype)
"~" -> augmentableAsmGen.inplaceInvert(assign)
else -> throw AssemblyError("invalid prefix operator")
}
} else {

View File

@ -21,13 +21,10 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
when (val value = assign.source.expression!!) {
is PrefixExpression -> {
// A = -A , A = +A, A = ~A, A = not A
val target = assignmentAsmGen.virtualRegsToVariables(assign.target)
val itype = value.inferType(program)
val type = itype.getOrElse { throw AssemblyError("unknown dt") }
when (value.operator) {
"+" -> {}
"-" -> inplaceNegate(assign)
"~" -> inplaceInvert(target, type)
"~" -> inplaceInvert(assign)
else -> throw AssemblyError("invalid prefix operator")
}
}
@ -1796,8 +1793,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
internal fun inplaceInvert(target: AsmAssignTarget, dt: DataType) {
when (dt) {
internal fun inplaceInvert(assign: AsmAssignment) {
val target = assign.target
when (assign.target.datatype) {
DataType.UBYTE -> {
when (target.kind) {
TargetStorageKind.VARIABLE -> {
@ -1840,7 +1838,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
TargetStorageKind.STACK -> TODO("no asm gen for byte stack invert")
TargetStorageKind.ARRAY -> TODO("no asm gen for in-place invert ubyte for ${target.kind}")
TargetStorageKind.ARRAY -> assignmentAsmGen.assignPrefixedExpressionToArrayElt(assign)
else -> throw AssemblyError("weird target")
}
}
@ -1865,7 +1863,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
TargetStorageKind.STACK -> TODO("no asm gen for word stack invert")
TargetStorageKind.ARRAY -> TODO("no asm gen for in-place invert uword for ${target.kind}")
TargetStorageKind.ARRAY -> assignmentAsmGen.assignPrefixedExpressionToArrayElt(assign)
else -> throw AssemblyError("weird target")
}
}
@ -1875,7 +1873,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
internal fun inplaceNegate(assign: AsmAssignment) {
val target = assign.target
when (val dt=assign.target.datatype) {
when (assign.target.datatype) {
DataType.BYTE -> {
when (target.kind) {
TargetStorageKind.VARIABLE -> {
@ -1980,7 +1978,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
else -> throw AssemblyError("weird target for float negation")
}
}
else -> throw AssemblyError("negate of invalid type $dt")
else -> throw AssemblyError("negate of invalid type")
}
}

View File

@ -3,6 +3,7 @@ package prog8tests.codegeneration
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldNotBe
import prog8.code.target.C64Target
import prog8.code.target.VMTarget
import prog8tests.helpers.compileText
class TestArrayInplaceAssign: FunSpec({
@ -17,18 +18,16 @@ class TestArrayInplaceAssign: FunSpec({
}
"""
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
compileText(VMTarget(), false, text, writeAssembly = true) shouldNotBe null
}
test("array in-place negation (integer types)") {
val text = """
%import floats
main {
byte[10] foo
ubyte[10] foou
word[10] foow
uword[10] foowu
float[10] flt
sub start() {
foo[1] = 42
@ -36,16 +35,13 @@ main {
foow[1] = 4242
foow[1] = -foow[1]
; TODO floating point in-place negation is not yet implemented in the code generator
; flt[1] = 42.42
; flt[1] = -flt[1]
}
}"""
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
compileText(VMTarget(), false, text, writeAssembly = true) shouldNotBe null
}
// TODO implement this in codegen and enable test
// TODO implement this in 6502 codegen, fix the fpReg1 out of bounds issue in vmcodegen, and re-enable test
xtest("array in-place negation (float type) - ignored for now because not implemented in codegen yet") {
val text = """
%import floats
@ -58,6 +54,7 @@ main {
flt[1] = -flt[1]
}
}"""
compileText(VMTarget(), false, text, writeAssembly = true) shouldNotBe null
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
}
@ -76,6 +73,7 @@ main {
}
}"""
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
compileText(VMTarget(), false, text, writeAssembly = true) shouldNotBe null
}
})

View File

@ -3,7 +3,7 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- fix the array in place assignment issue
- fix flt[1] = -flt[1] compiler crash for vm target: fpReg1 out of bounds, re enable test in TestArrayInplaceAssign
- ir: asmsub contents remains blank in IR file

View File

@ -1,37 +1,17 @@
%import floats
%import textio
%import floats
%zeropage basicsafe
main {
byte[10] foo
ubyte[10] foou
word[10] foow
uword[10] foowu
float[10] flt
byte d
sub start() {
; foo[0] = -d ; TODO fix codegen in assignExpression that splits this up
uword pointer = $1000
uword index
foou[1] = 42
pointer[$40] = 24
pointer[$40] = foou[1]+10
txt.print_ub(@($1040))
float ff = 9.0
flt[1] = 42.42
flt[1] = -9.0
flt[1] = -ff
flt[1] = -flt[1] ; TODO also fix crash when selecting vm target: fpReg1 out of bounds
floats.print_f(flt[1])
txt.nl()
pointer[index+$100] = foou[1]
pointer[index+$1000] = foou[1]+1
txt.print_ub(@($1100))
txt.nl()
txt.print_ub(@($2000))
txt.nl()
; foo[0] = -foo[0]
; foou[0] = ~foou[0]
; foow[0] = -foow[0]
; foowu[0] = ~foowu[0]
; flt[0] = -flt[0] ; TODO also fix crash when selecting vm target: fpReg1 out of bounds
}
}