mirror of
https://github.com/irmen/prog8.git
synced 2025-11-06 08:17:10 +00:00
assigning to plain pointer with array indexing
This commit is contained in:
@@ -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(
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
134
examples/test.p8
134
examples/test.p8
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user