assigning to plain pointer with array indexing

This commit is contained in:
Irmen de Jong
2025-05-28 18:08:53 +02:00
parent 4e61e25c02
commit 86da9d3c7e
5 changed files with 98 additions and 72 deletions

View File

@@ -570,8 +570,33 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
valueRegister: Int, valueRegister: Int,
valueFpRegister: Int valueFpRegister: Int
) { ) {
// TODO should be replaced by pointerderef in Ast itself maybe!?? val pointerTr = expressionEval.translateExpression(targetIdent)
TODO("Not yet implemented: plain pointer indexed assignment ${targetIdent.position}") // TODO huh, this was working in earlier code wasn't it? where is the routine gone? result += pointerTr.chunks
val pointerReg = pointerTr.resultReg
val constIndex = targetArray.index.asConstInteger()
if(zeroValue) {
if(constIndex!=null) {
val offset = eltSize * constIndex
addInstr(result, IRInstruction(Opcode.ADD, IRDataType.WORD, reg1=pointerReg, immediate = offset), null)
} else {
val (code, indexReg) = loadIndexReg(targetArray, eltSize, true)
result += code
addInstr(result, IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1=pointerReg, reg2=indexReg), null)
}
codeGen.storeValueAtPointersLocation(result, pointerReg, targetIdent.type.dereference(), true, -1)
} else {
if(constIndex!=null) {
val offset = eltSize * constIndex
addInstr(result, IRInstruction(Opcode.ADD, IRDataType.WORD, reg1=pointerReg, immediate = offset), null)
} else {
val (code, indexReg) = loadIndexReg(targetArray, eltSize, true)
result += code
addInstr(result, IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1=pointerReg, reg2=indexReg), null)
}
val realValueReg = if(targetDt == IRDataType.FLOAT) valueFpRegister else valueRegister
codeGen.storeValueAtPointersLocation(result, pointerReg, targetIdent.type.dereference(), false, realValueReg)
}
} }
private fun translateRegularAssignArrayIndexed( private fun translateRegularAssignArrayIndexed(

View File

@@ -602,7 +602,7 @@ main {
compileText(VMTarget(), false, src, outputDir) shouldNotBe null compileText(VMTarget(), false, src, outputDir) shouldNotBe null
} }
xtest("uword as pointer versus pointer to uword difference") { test("uword as pointer versus pointer to uword difference") {
val src=""" val src="""
main { main {
sub start() { sub start() {

View File

@@ -233,7 +233,6 @@ class BinaryExpression(
val leftIdentfier = left as? IdentifierReference val leftIdentfier = left as? IdentifierReference
val leftIndexer = left as? ArrayIndexedExpression val leftIndexer = left as? ArrayIndexedExpression
val rightIdentifier = right as? IdentifierReference val rightIdentifier = right as? IdentifierReference
val rightIndexer = right as? ArrayIndexedExpression
if(rightIdentifier!=null) { if(rightIdentifier!=null) {
val struct: StructDecl? = val struct: StructDecl? =
if (leftIdentfier != null) { if (leftIdentfier != null) {

View File

@@ -57,15 +57,13 @@ STRUCTS and TYPED POINTERS
- DONE: what about static initialization of an array of struct pointers? -> impossible right now because the pointer values are not constants. - DONE: what about static initialization of an array of struct pointers? -> impossible right now because the pointer values are not constants.
- DONE: make typeForAddressOf() be even more specific about the typed pointers it returns for the address-of operator. - DONE: make typeForAddressOf() be even more specific about the typed pointers it returns for the address-of operator.
- add unit tests for expected AST elements for all syntaxes dealing with pointers, dereference(chain), derefs, and indexing (both as value and assigntargets) - add unit tests for expected AST elements for all syntaxes dealing with pointers, dereference(chain), derefs, and indexing (both as value and assigntargets)
- clean up pointerdereference in the grammar, regarding dealing with final ^^ or not (is there still any left?)
- fix TODO("address-of pointer dereference")
- fix TODO("replace ptr^^ by @(ptr)") - fix TODO("replace ptr^^ by @(ptr)")
- add unit tests for all changes (pointers and structs) - add unit tests for all changes (pointers and structs)
- try to fix parse error l1^^.s[0] = 4242 (equivalent to l1.s[0]=4242 , which does parse correctly) - try to fix parse error l1^^.s[0] = 4242 (equivalent to l1.s[0]=4242 , which does parse correctly)
- 6502 codegen: remove checks in checkForPointerTypesOn6502() - 6502 codegen: remove checks in checkForPointerTypesOn6502()
- 6502 codegen should warn about writing to initialized struct instances when using romable code, like with arrays "can only be used as read-only in ROMable code" - 6502 codegen should warn about writing to initialized struct instances when using romable code, like with arrays "can only be used as read-only in ROMable code"
- 6502 asm symbol name prefixing should work for dereferences too. - 6502 asm symbol name prefixing should work for dereferences too.
- fixing the pointer dereferencing issues (cursed hybrid beween IdentifierReference, PtrDereferece and PtrIndexedDereference) may require getting rid of scoped identifiers altogether and treat '.' as a "scope or pointer following operator" - really fixing the pointer dereferencing issues (cursed hybrid beween IdentifierReference, PtrDereferece and PtrIndexedDereference) may require getting rid of scoped identifiers altogether and treat '.' as a "scope or pointer following operator"
- (later, nasty parser problem:) support chaining pointer dereference on function calls that return a pointer. (type checking now fails on stuff like func().field and func().next.field) - (later, nasty parser problem:) support chaining pointer dereference on function calls that return a pointer. (type checking now fails on stuff like func().field and func().next.field)
- update syntax highlighting files - update syntax highlighting files

View File

@@ -5,79 +5,83 @@ main {
sub start() { sub start() {
simpleptrindexing() simpleptrindexing()
;; struct List { struct List {
;; float f float f
;; ^^uword s ^^uword s
;; ^^float fp ^^float fp
;; uword n uword n
;; } }
;; ^^List l = List() ^^List l = List()
;; l.s = 2000 l.s = 2000
;; l.fp = 3000 l.fp = 3000
;;
;; pokew(2000, 1) pokew(2000, 1)
;; pokew(2002, 2) pokew(2002, 2)
;; pokew(2004, 3) pokew(2004, 3)
;; pokew(2006, 4) pokew(2006, 4)
;; pokew(2008, 5) pokew(2008, 5)
;; pokef(3000, 1.111) pokef(3000, 1.111)
;; pokef(3008, 2.222) pokef(3008, 2.222)
;; pokef(3016, 3.333) pokef(3016, 3.333)
;; pokef(3024, 4.444) pokef(3024, 4.444)
;; pokef(3032, 5.555) pokef(3032, 5.555)
;;
;; cx16.r9L = 2 cx16.r9L = 2
;;
;; lvref1() lvref1()
;; lvref2() lvref2()
;; lvref1f() lvref1f()
;; lvref2f() lvref2f()
;;
;; ref1() ref1()
;; ref2() ref2()
;; ref1f() ref1f()
;; ref2f() ref2f()
;
; sub lvref1() { sub lvref1() {
; l.s[2] = 3333 l.s[2] = 3333
; } }
; sub lvref2() { sub lvref2() {
; l.s[cx16.r9L+1] = 4444 l.s[cx16.r9L+1] = 4444
; } }
; sub lvref1f() { sub lvref1f() {
; l.fp[2] = 3333.3 l.fp[2] = 3333.3
; } }
; sub lvref2f() { sub lvref2f() {
; l.fp[cx16.r9L+1] = 4444.4 l.fp[cx16.r9L+1] = 4444.4
; } }
;
; sub ref1() { sub ref1() {
; cx16.r0 = l.s[2] cx16.r0 = l.s[2]
; txt.print_uw(l.s[2]) txt.print_uw(l.s[2])
; txt.nl() txt.nl()
; } }
; sub ref2() { sub ref2() {
; cx16.r1 = l.s[cx16.r9L+1] cx16.r1 = l.s[cx16.r9L+1]
; txt.print_uw(l.s[cx16.r9L+1]) txt.print_uw(l.s[cx16.r9L+1])
; txt.nl() txt.nl()
; } }
; sub ref1f() { sub ref1f() {
; txt.print_f(l.fp[2]) txt.print_f(l.fp[2])
; txt.nl() txt.nl()
; } }
; sub ref2f() { sub ref2f() {
; txt.print_f(l.fp[cx16.r9L+1]) txt.print_f(l.fp[cx16.r9L+1])
; txt.nl() txt.nl()
; } }
} }
sub simpleptrindexing() { sub simpleptrindexing() {
^^float flptr = 2000 ^^float flptr = 2000
^^bool bptr = 3000
; flptr[0] = 0.0 ; flptr[0] = 0.0
; flptr[1] = 1.1 ; flptr[1] = 1.1
flptr[2] = 2.2 ;; TODO Fix wrong memory write cx16.r9L = 2
flptr[cx16.r9L] = 2.2
bptr[cx16.r9L] = true
; txt.print_f(flptr[0]) ; txt.print_f(flptr[0])
; txt.nl() ; txt.nl()