From e800c165f987e40dda2be646eace845f24a49e4c Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 14 Aug 2025 20:38:18 +0200 Subject: [PATCH] fix 6502 inplace pointer variable assignment --- .../src/prog8/codegen/cpu6502/AsmGen.kt | 2 +- .../cpu6502/assignment/AsmAssignment.kt | 4 ++++ .../assignment/AugmentableAssignmentAsmGen.kt | 23 +++++++++---------- compiler/test/TestPointers.kt | 11 +++++++++ examples/test.p8 | 11 +++------ 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index faef2642f..373d3ab7e 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -1440,7 +1440,7 @@ $repeatLabel""") if(params!=null) { for(param in params) { param as PtSubroutineParameter - if(param.name==name) + if(param.scopedName==name) return param } } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt index 6f63a7aa7..bb562ccdf 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt @@ -55,6 +55,10 @@ internal class AsmAssignTarget(val kind: TargetStorageKind, require(register!=null) else require(register==null) + if(kind==TargetStorageKind.POINTER) + require(pointer!=null) + if(pointer!=null) + require(kind==TargetStorageKind.POINTER) } companion object { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt index 46f80c7ee..b07b13cf1 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt @@ -85,22 +85,23 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, } } } - target.datatype.isWord -> { + target.datatype.isWord || target.datatype.isPointer -> { val block = target.origAstTarget?.definingBlock() + val targetDt = if(target.datatype.isWord) target.datatype else DataType.UWORD // pointers themselves that get a new value are just treated as UWORD variables when(value.kind) { - SourceStorageKind.LITERALBOOLEAN -> inplacemodificationWordWithLiteralval(target.asmVarname, target.datatype, operator, value.boolean!!.asInt(), block) - SourceStorageKind.LITERALNUMBER -> inplacemodificationWordWithLiteralval(target.asmVarname, target.datatype, operator, value.number!!.number.toInt(), block) - SourceStorageKind.VARIABLE -> inplacemodificationWordWithVariable(target.asmVarname, target.datatype, operator, value.asmVarname, value.datatype, block) - SourceStorageKind.REGISTER -> inplacemodificationWordWithVariable(target.asmVarname, target.datatype, operator, regName(value), value.datatype, block) - SourceStorageKind.MEMORY -> inplacemodificationWordWithMemread(target.asmVarname, target.datatype, operator, value.memory!!) - SourceStorageKind.ARRAY -> inplacemodificationWordWithValue(target.asmVarname, target.datatype, operator, value.array!!, block) + SourceStorageKind.LITERALBOOLEAN -> inplacemodificationWordWithLiteralval(target.asmVarname, targetDt, operator, value.boolean!!.asInt(), block) + SourceStorageKind.LITERALNUMBER -> inplacemodificationWordWithLiteralval(target.asmVarname, targetDt, operator, value.number!!.number.toInt(), block) + SourceStorageKind.VARIABLE -> inplacemodificationWordWithVariable(target.asmVarname, targetDt, operator, value.asmVarname, value.datatype, block) + SourceStorageKind.REGISTER -> inplacemodificationWordWithVariable(target.asmVarname, targetDt, operator, regName(value), value.datatype, block) + SourceStorageKind.MEMORY -> inplacemodificationWordWithMemread(target.asmVarname, targetDt, operator, value.memory!!) + SourceStorageKind.ARRAY -> inplacemodificationWordWithValue(target.asmVarname, targetDt, operator, value.array!!, block) SourceStorageKind.EXPRESSION -> { if(value.expression is PtTypeCast) { if (tryInplaceModifyWithRemovedRedundantCast(value.expression, target, operator)) return - inplacemodificationWordWithValue(target.asmVarname, target.datatype, operator, value.expression, block) + inplacemodificationWordWithValue(target.asmVarname, targetDt, operator, value.expression, block) } else { - inplacemodificationWordWithValue(target.asmVarname, target.datatype, operator, value.expression!!, block) + inplacemodificationWordWithValue(target.asmVarname, targetDt, operator, value.expression!!, block) } } } @@ -123,8 +124,6 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, } } } - target.datatype.isPointer -> - ptrgen.inplaceModification(PtrTarget(target), operator, value) else -> throw AssemblyError("weird type to do in-place modification on ${target.datatype}") } } @@ -309,7 +308,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, } } } - target.datatype.isPointer -> ptrgen.inplaceModification(PtrTarget(target), operator, value) + target.datatype.isPointer -> TODO("inplace modification of pointer array ${target.position}") else -> throw AssemblyError("weird type to do in-place modification on ${target.datatype}") } } diff --git a/compiler/test/TestPointers.kt b/compiler/test/TestPointers.kt index 0366d2e99..98e3f03d7 100644 --- a/compiler/test/TestPointers.kt +++ b/compiler/test/TestPointers.kt @@ -1390,6 +1390,7 @@ main { } sub test(str argument) -> str { + argument++ return "bye" } }""" @@ -1397,11 +1398,21 @@ main { val vmtest = vmprg.codegenAst!!.allBlocks().first { it.name == "main" }.children[1] as PtSub vmtest.signature.returns.single() shouldBe DataType.pointer(BaseDataType.UBYTE) (vmtest.signature.children.single() as PtSubroutineParameter).type shouldBe DataType.pointer(BaseDataType.UBYTE) + val vminc = vmtest.children[2] as PtAugmentedAssign + vminc.operator shouldBe "+=" + vminc.target.identifier!!.name shouldBe "main.test.argument" + vminc.target.identifier!!.type shouldBe DataType.pointer(BaseDataType.UBYTE) + (vminc.value as PtNumber).number shouldBe 1.0 val c64prg = compileText(C64Target(), false, src, outputDir)!! val c64test = c64prg.codegenAst!!.allBlocks().first { it.name == "p8b_main" }.children[1] as PtSub c64test.signature.returns.single() shouldBe DataType.pointer(BaseDataType.UBYTE) (c64test.signature.children.single() as PtSubroutineParameter).type shouldBe DataType.pointer(BaseDataType.UBYTE) + val c64inc = c64test.children[2] as PtAugmentedAssign + c64inc.operator shouldBe "+=" + c64inc.target.identifier!!.name shouldBe "p8b_main.p8s_test.p8v_argument" + c64inc.target.identifier!!.type shouldBe DataType.pointer(BaseDataType.UBYTE) + (c64inc.value as PtNumber).number shouldBe 1.0 } test("hoist variable decl and initializer correctly in case of pointer type variable as well") { diff --git a/examples/test.p8 b/examples/test.p8 index bc43bd980..03c3df52f 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,14 +1,9 @@ main { sub start() { - -label: - uword @shared addr - addr = label - addr = thing - addr = &label - addr = &thing + console_write("sdf") } - sub thing() { + sub console_write(^^ubyte isoString) { + isoString++ } }