From 434515d9578e011a67735c44aa4c539f73774ea9 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 27 Oct 2022 23:31:57 +0200 Subject: [PATCH] fix: array[x] = ~array[x] no longer crashes the codegen --- .../cpu6502/assignment/AssignmentAsmGen.kt | 3 +- .../assignment/AugmentableAssignmentAsmGen.kt | 18 +++++----- .../codegeneration/TestArrayInplaceAssign.kt | 14 ++++---- docs/source/todo.rst | 2 +- examples/test.p8 | 34 ++++--------------- 5 files changed, 23 insertions(+), 48 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 68e3e0d4e..069fdb510 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -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 { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt index c21c51e7b..4853e5d87 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt @@ -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") } } diff --git a/compiler/test/codegeneration/TestArrayInplaceAssign.kt b/compiler/test/codegeneration/TestArrayInplaceAssign.kt index f551a5a98..c90ac5921 100644 --- a/compiler/test/codegeneration/TestArrayInplaceAssign.kt +++ b/compiler/test/codegeneration/TestArrayInplaceAssign.kt @@ -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 } }) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 6c85d5ec6..7e5611050 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -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 diff --git a/examples/test.p8 b/examples/test.p8 index daeb20cc6..13e8b08d5 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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 } }