mirror of
https://github.com/irmen/prog8.git
synced 2026-04-24 21:17:10 +00:00
proper warning for struct instance assignment (not yet supported)
This commit is contained in:
@@ -694,7 +694,8 @@ internal class AstChecker(private val program: Program,
|
||||
return super.visit(assignment)
|
||||
|
||||
// unfortunately the AST regarding pointer dereferencing is a bit of a mess, and we cannot do precise type checking on elements inside such expressions yet.
|
||||
if(assignment.value.inferType(program).isUnknown) {
|
||||
val valueDt = assignment.value.inferType(program)
|
||||
if(valueDt.isUnknown) {
|
||||
val binexpr = assignment.value as? BinaryExpression
|
||||
if(assignment.target.multi==null) {
|
||||
if (binexpr != null && binexpr.operator != ".")
|
||||
@@ -702,6 +703,8 @@ internal class AstChecker(private val program: Program,
|
||||
else
|
||||
errors.err("invalid assignment value", assignment.value.position)
|
||||
}
|
||||
} else if(valueDt.isStructInstance) {
|
||||
errors.err("no support yet for assigning a struct instance by value", assignment.value.position)
|
||||
}
|
||||
|
||||
super.visit(assignment)
|
||||
|
||||
@@ -744,18 +744,21 @@ _after:
|
||||
// special case simple struct instance assignment via memory copy
|
||||
val deref = assignment.value as? PtrDereference
|
||||
if(deref!=null) {
|
||||
// ptr1^^ = ptr2^^ --> memcopy(ptr2, ptr1, sizeof(struct))
|
||||
val sourcePtr = IdentifierReference(deref.chain, assignment.position)
|
||||
val targetPtr = IdentifierReference(assignment.target.pointerDereference!!.chain, assignment.position)
|
||||
val size = program.memsizer.memorySize(sourceDt.getOrUndef(), null)
|
||||
require(program.memsizer.memorySize(targetDt.getOrUndef(), null)==size)
|
||||
val numBytes = NumericLiteral.optimalInteger(size, assignment.position)
|
||||
val memcopy = FunctionCallStatement(IdentifierReference(listOf("sys", "memcopy"), assignment.position),
|
||||
mutableListOf(sourcePtr, targetPtr, numBytes),
|
||||
false, assignment.position)
|
||||
return listOf(IAstModification.ReplaceNode(assignment, memcopy, parent))
|
||||
val targetDeref = assignment.target.pointerDereference
|
||||
if(targetDeref!=null) {
|
||||
// ptr1^^ = ptr2^^ --> memcopy(ptr2, ptr1, sizeof(struct))
|
||||
val targetPtr = IdentifierReference(targetDeref.chain, assignment.position)
|
||||
val size = program.memsizer.memorySize(sourceDt.getOrUndef(), null)
|
||||
require(program.memsizer.memorySize(targetDt.getOrUndef(), null)==size)
|
||||
val numBytes = NumericLiteral.optimalInteger(size, assignment.position)
|
||||
val memcopy = FunctionCallStatement(IdentifierReference(listOf("sys", "memcopy"), assignment.position),
|
||||
mutableListOf(sourcePtr, targetPtr, numBytes),
|
||||
false, assignment.position)
|
||||
return listOf(IAstModification.ReplaceNode(assignment, memcopy, parent))
|
||||
}
|
||||
}
|
||||
// TODO support other forms of struct instance assignments? such as ptr^^ = array[2]^^
|
||||
// TODO support other forms of struct instance assignments, such as ptr^^ = array[2]^^ , array[3] = array[2], array[3] = ptr^^
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -325,12 +325,11 @@ main {
|
||||
cx16.r0L = ubyteptr[999]
|
||||
cx16.r1L = wordptr[999]
|
||||
cx16.r2L = array[9]
|
||||
listptr2 = listptr[999]
|
||||
}
|
||||
}"""
|
||||
val result = compileText(VMTarget(), false, src, outputDir, writeAssembly = false)!!
|
||||
val st = result.compilerAst.entrypoint.statements
|
||||
st.size shouldBe 28
|
||||
st.size shouldBe 27
|
||||
|
||||
val a_zz = (st[20] as Assignment).value
|
||||
a_zz shouldBe instanceOf<ArrayIndexedExpression>()
|
||||
@@ -1197,10 +1196,11 @@ main {
|
||||
|
||||
val errors=ErrorReporterForTests()
|
||||
compileText(VMTarget(), false, src, outputDir, errors=errors)
|
||||
errors.errors.size shouldBe 3
|
||||
errors.errors[0] shouldContain "doesn't match"
|
||||
errors.errors[1] shouldContain "assigning this value to struct instance not supported"
|
||||
errors.errors.size shouldBe 4
|
||||
errors.errors[0] shouldContain "struct instance by value"
|
||||
errors.errors[1] shouldContain "doesn't match"
|
||||
errors.errors[2] shouldContain "assigning this value to struct instance not supported"
|
||||
errors.errors[3] shouldContain "assigning this value to struct instance not supported"
|
||||
}
|
||||
|
||||
test("a.b.c[i]^^.value as expression where pointer is struct") {
|
||||
@@ -1876,9 +1876,11 @@ main {
|
||||
}"""
|
||||
val errors=ErrorReporterForTests(keepMessagesAfterReporting = true)
|
||||
compileText(VMTarget(), false, src, outputDir, errors=errors) shouldBe null
|
||||
errors.errors.size shouldBe 2
|
||||
errors.errors[0] shouldContain "no support for getting the target value of pointer array indexing"
|
||||
errors.errors[1] shouldContain "assigning this value to struct instance not supported"
|
||||
errors.errors.size shouldBe 4
|
||||
errors.errors[0] shouldContain "struct instance by value"
|
||||
errors.errors[1] shouldContain "no support for getting the target value of pointer array indexing"
|
||||
errors.errors[2] shouldContain "struct instance by value"
|
||||
errors.errors[3] shouldContain "assigning this value to struct instance not supported"
|
||||
}
|
||||
|
||||
test("pointer variable usage detection in other block 1") {
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
fix compiler crash (virtual) for ^^List @shared lp ; ^^List @shared temp = lp[2]
|
||||
fix invalid pointer arithmetic in 6502 code for &&lp[2] (it adds 2 to the pointer itself rather than the value of the pointer, and 2 is wrong as well)
|
||||
|
||||
|
||||
|
||||
STRUCTS and TYPED POINTERS (6502 codegen specific)
|
||||
--------------------------------------------------
|
||||
|
||||
- implement the TODO's in PointerAssignmentsGen. (mostly related to an array indexed pointer assignment target)
|
||||
- implement the TODO's in PointerAssignmentsGen.
|
||||
- implement some more struct instance assignments (via memcopy) in CodeDesugarer (see the TODO)
|
||||
- scan through 6502 library modules to change untyped uword pointers to typed pointers
|
||||
- scan through 6502 examples to change untyped uword pointers to typed pointers
|
||||
- fix code size regressions (if any left)
|
||||
|
||||
+154
-122
@@ -4,137 +4,169 @@
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
|
||||
|
||||
main {
|
||||
|
||||
struct List {
|
||||
^^uword s
|
||||
ubyte n
|
||||
^^List next
|
||||
}
|
||||
|
||||
sub start() {
|
||||
floatprob()
|
||||
basicpointers()
|
||||
ubyte[10] array
|
||||
uword @shared wordptr
|
||||
^^bool @shared boolptr
|
||||
^^float @shared floatptr
|
||||
^^byte @shared byteptr
|
||||
^^ubyte @shared ubyteptr
|
||||
^^List @shared listptr
|
||||
^^List @shared listptr2
|
||||
|
||||
; TODO test address-of with array indexed as well
|
||||
}
|
||||
bool @shared zz
|
||||
float @shared fl
|
||||
byte @shared bb
|
||||
|
||||
sub floatprob() {
|
||||
uword @shared dummy
|
||||
^^float[10] floatptrs
|
||||
^^float fptr1 = 20000 + 3*sizeof(float)
|
||||
^^float fptr2 = 20000
|
||||
txt.print_uw(&floatptrs)
|
||||
txt.spc()
|
||||
txt.print_uw(&floatptrs[3]) ; NOTE: will be 3 because the pointer array is split-words . This codegen is OK!
|
||||
txt.nl()
|
||||
|
||||
txt.print_uw(fptr1)
|
||||
txt.spc()
|
||||
txt.print_uw(fptr2)
|
||||
txt.spc()
|
||||
txt.print_uw(& fptr2[3])
|
||||
txt.spc()
|
||||
txt.print_uw(&& fptr2[3])
|
||||
txt.spc()
|
||||
cx16.r0L = 3
|
||||
txt.print_uw(& fptr2[cx16.r0L])
|
||||
txt.spc()
|
||||
txt.print_uw(&& fptr2[cx16.r0L])
|
||||
txt.nl()
|
||||
cx16.r0L = 2
|
||||
txt.print_uw(& fptr2[cx16.r0L+1])
|
||||
txt.spc()
|
||||
txt.print_uw(&& fptr2[cx16.r0L+1])
|
||||
txt.nl()
|
||||
|
||||
pokef(20000+3*sizeof(float), 3.1415927)
|
||||
txt.print_f(fptr1^^)
|
||||
txt.spc()
|
||||
txt.print_f(fptr2[3])
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub basicpointers() {
|
||||
^^bool bptr = 20000
|
||||
^^float fptr = 20100
|
||||
^^word wptr = 20200
|
||||
^^ubyte ubptr = 20300
|
||||
|
||||
txt.print("direct deref:\n")
|
||||
txt.print_bool(bptr^^)
|
||||
txt.spc()
|
||||
txt.print_f(fptr^^)
|
||||
txt.spc()
|
||||
txt.print_w(wptr^^)
|
||||
txt.spc()
|
||||
txt.print_ub(ubptr^^)
|
||||
txt.nl()
|
||||
|
||||
@(20000) = 1
|
||||
pokef(20100, 3.1415927)
|
||||
pokew(20200, -22222 as uword)
|
||||
@(20300) = 123
|
||||
|
||||
txt.print_bool(bptr^^)
|
||||
txt.spc()
|
||||
txt.print_f(fptr^^)
|
||||
txt.spc()
|
||||
txt.print_w(wptr^^)
|
||||
txt.spc()
|
||||
txt.print_ub(ubptr^^)
|
||||
txt.nl()
|
||||
|
||||
|
||||
txt.print("indexed deref (const):\n")
|
||||
@(20003) = 1
|
||||
pokef(20100+3*sizeof(float), 9.876543)
|
||||
pokew(20200+3*2, -11111 as uword)
|
||||
@(20300+3) = 42
|
||||
|
||||
txt.print_bool(bptr[3])
|
||||
txt.spc()
|
||||
txt.print_f(fptr[3])
|
||||
txt.spc()
|
||||
txt.print_w(wptr[3])
|
||||
txt.spc()
|
||||
txt.print_ub(ubptr[3])
|
||||
txt.nl()
|
||||
|
||||
|
||||
txt.print("indexed deref (var):\n")
|
||||
cx16.r0L = 3
|
||||
txt.print_bool(bptr[cx16.r0L])
|
||||
txt.spc()
|
||||
txt.print_f(fptr[cx16.r0L])
|
||||
txt.spc()
|
||||
txt.print_w(wptr[cx16.r0L])
|
||||
txt.spc()
|
||||
txt.print_ub(ubptr[cx16.r0L])
|
||||
txt.nl()
|
||||
|
||||
txt.print("indexed deref (expr):\n")
|
||||
cx16.r0L = 2
|
||||
txt.print_bool(bptr[cx16.r0L+1])
|
||||
txt.spc()
|
||||
txt.print_f(fptr[cx16.r0L+1])
|
||||
txt.spc()
|
||||
txt.print_w(wptr[cx16.r0L+1])
|
||||
txt.spc()
|
||||
txt.print_ub(ubptr[cx16.r0L+1])
|
||||
txt.nl()
|
||||
zz = boolptr[999]
|
||||
fl = floatptr[999]
|
||||
bb = byteptr[999]
|
||||
cx16.r0L = ubyteptr[999]
|
||||
cx16.r1L = wordptr[999]
|
||||
cx16.r2L = array[9]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
; ^^Node[5] nodesarray
|
||||
;
|
||||
; cx16.r0L = nodesarray[2].weight
|
||||
; cx16.r0L = nodes[2].weight
|
||||
|
||||
|
||||
;main {
|
||||
; sub start() {
|
||||
; struct List {
|
||||
; bool b
|
||||
; uword value
|
||||
; }
|
||||
; floatprob()
|
||||
; basicpointers()
|
||||
;
|
||||
; ^^List[10] listarray
|
||||
; cx16.r0 = listarray[2].value
|
||||
; cx16.r1 = listarray[3]^^.value
|
||||
; ; TODO test address-of with array indexed as well
|
||||
; }
|
||||
;
|
||||
; sub floatprob() {
|
||||
; uword @shared dummy
|
||||
; ^^float[10] floatptrs
|
||||
; ^^float fptr1 = 20000 + 3*sizeof(float)
|
||||
; ^^float fptr2 = 20000
|
||||
; txt.print_uw(&floatptrs)
|
||||
; txt.spc()
|
||||
; txt.print_uw(&floatptrs[3]) ; NOTE: will be 3 because the pointer array is split-words . This codegen is OK!
|
||||
; txt.nl()
|
||||
;
|
||||
; txt.print_uw(fptr1)
|
||||
; txt.spc()
|
||||
; txt.print_uw(fptr2)
|
||||
; txt.spc()
|
||||
; txt.print_uw(& fptr2[3])
|
||||
; txt.spc()
|
||||
; txt.print_uw(&& fptr2[3])
|
||||
; txt.spc()
|
||||
; cx16.r0L = 3
|
||||
; txt.print_uw(& fptr2[cx16.r0L])
|
||||
; txt.spc()
|
||||
; txt.print_uw(&& fptr2[cx16.r0L])
|
||||
; txt.nl()
|
||||
; cx16.r0L = 2
|
||||
; txt.print_uw(& fptr2[cx16.r0L+1])
|
||||
; txt.spc()
|
||||
; txt.print_uw(&& fptr2[cx16.r0L+1])
|
||||
; txt.nl()
|
||||
;
|
||||
; pokef(20000+3*sizeof(float), 3.1415927)
|
||||
; txt.print_f(fptr1^^)
|
||||
; txt.spc()
|
||||
; txt.print_f(fptr2[3])
|
||||
; txt.nl()
|
||||
; }
|
||||
;
|
||||
; sub basicpointers() {
|
||||
; ^^bool bptr = 20000
|
||||
; ^^float fptr = 20100
|
||||
; ^^word wptr = 20200
|
||||
; ^^ubyte ubptr = 20300
|
||||
;
|
||||
; txt.print("direct deref:\n")
|
||||
; txt.print_bool(bptr^^)
|
||||
; txt.spc()
|
||||
; txt.print_f(fptr^^)
|
||||
; txt.spc()
|
||||
; txt.print_w(wptr^^)
|
||||
; txt.spc()
|
||||
; txt.print_ub(ubptr^^)
|
||||
; txt.nl()
|
||||
;
|
||||
; @(20000) = 1
|
||||
; pokef(20100, 3.1415927)
|
||||
; pokew(20200, -22222 as uword)
|
||||
; @(20300) = 123
|
||||
;
|
||||
; txt.print_bool(bptr^^)
|
||||
; txt.spc()
|
||||
; txt.print_f(fptr^^)
|
||||
; txt.spc()
|
||||
; txt.print_w(wptr^^)
|
||||
; txt.spc()
|
||||
; txt.print_ub(ubptr^^)
|
||||
; txt.nl()
|
||||
;
|
||||
;
|
||||
; txt.print("indexed deref (const):\n")
|
||||
; @(20003) = 1
|
||||
; pokef(20100+3*sizeof(float), 9.876543)
|
||||
; pokew(20200+3*2, -11111 as uword)
|
||||
; @(20300+3) = 42
|
||||
;
|
||||
; txt.print_bool(bptr[3])
|
||||
; txt.spc()
|
||||
; txt.print_f(fptr[3])
|
||||
; txt.spc()
|
||||
; txt.print_w(wptr[3])
|
||||
; txt.spc()
|
||||
; txt.print_ub(ubptr[3])
|
||||
; txt.nl()
|
||||
;
|
||||
;
|
||||
; txt.print("indexed deref (var):\n")
|
||||
; cx16.r0L = 3
|
||||
; txt.print_bool(bptr[cx16.r0L])
|
||||
; txt.spc()
|
||||
; txt.print_f(fptr[cx16.r0L])
|
||||
; txt.spc()
|
||||
; txt.print_w(wptr[cx16.r0L])
|
||||
; txt.spc()
|
||||
; txt.print_ub(ubptr[cx16.r0L])
|
||||
; txt.nl()
|
||||
;
|
||||
; txt.print("indexed deref (expr):\n")
|
||||
; cx16.r0L = 2
|
||||
; txt.print_bool(bptr[cx16.r0L+1])
|
||||
; txt.spc()
|
||||
; txt.print_f(fptr[cx16.r0L+1])
|
||||
; txt.spc()
|
||||
; txt.print_w(wptr[cx16.r0L+1])
|
||||
; txt.spc()
|
||||
; txt.print_ub(ubptr[cx16.r0L+1])
|
||||
; txt.nl()
|
||||
; }
|
||||
;}
|
||||
;
|
||||
;
|
||||
;; ^^Node[5] nodesarray
|
||||
;;
|
||||
;; cx16.r0L = nodesarray[2].weight
|
||||
;; cx16.r0L = nodes[2].weight
|
||||
;
|
||||
;
|
||||
;;main {
|
||||
;; sub start() {
|
||||
;; struct List {
|
||||
;; bool b
|
||||
;; uword value
|
||||
;; }
|
||||
;;
|
||||
;; ^^List[10] listarray
|
||||
;; cx16.r0 = listarray[2].value
|
||||
;; cx16.r1 = listarray[3]^^.value
|
||||
;; }
|
||||
;;}
|
||||
|
||||
Reference in New Issue
Block a user