fix address-of identifier alias replacement stripping array index away

This commit is contained in:
Irmen de Jong
2025-07-14 23:54:26 +02:00
parent 3f34b83e0d
commit dc434d034a
3 changed files with 60 additions and 23 deletions

View File

@@ -7,10 +7,7 @@ import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.string.shouldContain
import io.kotest.matchers.types.instanceOf
import prog8.ast.expressions.AddressOf
import prog8.ast.expressions.ArrayIndexedExpression
import prog8.ast.expressions.DirectMemoryRead
import prog8.ast.expressions.PtrDereference
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.code.ast.*
import prog8.code.core.BaseDataType
@@ -659,6 +656,44 @@ main {
compileText(VMTarget(), false, src, outputDir) shouldNotBe null
}
test("address-of pointer arithmetic on alias") {
val src="""
main {
sub start() {
ubyte @shared index = 3
ubyte[10] array
alias curframe = array
cx16.r0 = &curframe
cx16.r1 = &curframe[3]
cx16.r2 = &curframe + 3
cx16.r3 = &curframe[index]
cx16.r4 = &curframe + index
}
}"""
val result = compileText(VMTarget(), false, src, outputDir)!!
val st = result.compilerAst.entrypoint.statements
st.size shouldBe 9
(st[3] as Assignment).value shouldBe instanceOf<AddressOf>()
val a1v = (st[4] as Assignment).value as AddressOf
a1v.identifier?.nameInSource shouldBe listOf("array")
a1v.arrayIndex?.indexExpr?.constValue(result.compilerAst)?.number shouldBe 3.0
val a2v = (st[5] as Assignment).value as BinaryExpression
a2v.left shouldBe instanceOf<AddressOf>()
a2v.operator shouldBe "+"
(a2v.right as NumericLiteral).number shouldBe 3.0
val a3v = (st[6] as Assignment).value as AddressOf
a3v.identifier?.nameInSource shouldBe listOf("array")
(a3v.arrayIndex?.indexExpr as IdentifierReference).nameInSource shouldBe listOf("index")
val a4v = (st[7] as Assignment).value as BinaryExpression
a4v.left shouldBe instanceOf<AddressOf>()
a4v.operator shouldBe "+"
(a4v.right as TypecastExpression).expression shouldBe instanceOf<IdentifierReference>()
}
test("uword struct field array indexing") {
val src="""
main {

View File

@@ -520,12 +520,10 @@ data class AddressOf(var identifier: IdentifierReference?, var arrayIndex: Array
node===identifier -> {
if(replacement is IdentifierReference) {
identifier = replacement
arrayIndex = null
dereference = null
} else {
dereference = replacement as PtrDereference
identifier = null
arrayIndex = null
}
}
node===arrayIndex -> {

View File

@@ -1,27 +1,31 @@
%option enable_floats
%import textio
%zeropage basicsafe
%option no_sysinit
%zeropage basicsafe
%import textio
main {
float f
sub start() {
txt.print("classic float pointer+1: ")
txt.print_uwhex(&f, true)
txt.spc()
txt.print_uwhex(&f + 1, true)
txt.spc()
txt.print_uw(&f + 1 - &f)
txt.nl()
ubyte @shared index = 3
ubyte[10] array
alias curframe = array
txt.print("typed float pointer+1: ")
txt.print_uwhex(&&f, true)
cx16.r0 = &curframe
cx16.r1 = &curframe[3]
cx16.r2 = &curframe + 3
cx16.r3 = &curframe[index]
cx16.r4 = &curframe + index
txt.print_uw(cx16.r0)
txt.nl()
txt.print_uw(cx16.r1)
txt.spc()
txt.print_uwhex(&&f + 1, true)
txt.print_uw(cx16.r2)
txt.nl()
txt.print_uw(cx16.r3)
txt.spc()
txt.print_uw(&&f + 1 - &&f)
txt.print_uw(cx16.r4)
txt.nl()
}
}
; code sizes on 11.5: 6502: $20a virt: 140 instr
; code sizes on 12.0: 6502: ???? virt: ??? instr (BORKED!)