mirror of
				https://github.com/irmen/prog8.git
				synced 2025-11-04 10:16:13 +00:00 
			
		
		
		
	identified problems with pointer array as parameter
This commit is contained in:
		@@ -1320,4 +1320,115 @@ main {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        compileText(VMTarget(), false, src, outputDir) shouldNotBe null
 | 
					        compileText(VMTarget(), false, src, outputDir) shouldNotBe null
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xtest("array of pointers as subroutine param - not the primitive type pointers") {
 | 
				
			||||||
 | 
					        val src="""
 | 
				
			||||||
 | 
					%option enable_floats
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sub start() {
 | 
				
			||||||
 | 
					        ^^ubyte[4] array1
 | 
				
			||||||
 | 
					        ^^byte[4] array2
 | 
				
			||||||
 | 
					        ^^bool[4] array3
 | 
				
			||||||
 | 
					        ^^word[4] array4
 | 
				
			||||||
 | 
					        ^^uword[4] array5
 | 
				
			||||||
 | 
					        ^^float[4] array6
 | 
				
			||||||
 | 
					        ^^long[4] array7
 | 
				
			||||||
 | 
					        ^^str[4] array8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        error1(array1)
 | 
				
			||||||
 | 
					        error2(array2)
 | 
				
			||||||
 | 
					        error3(array3)
 | 
				
			||||||
 | 
					        error4(array4)
 | 
				
			||||||
 | 
					        error5(array5)
 | 
				
			||||||
 | 
					        error6(array6)
 | 
				
			||||||
 | 
					        error7(array7)
 | 
				
			||||||
 | 
					        error8(array8)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sub error1(^^ubyte ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error2(^^byte ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error3(^^bool ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error4(^^word ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error5(^^uword ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error6(^^float ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error7(^^long ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error8(^^str ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}"""
 | 
				
			||||||
 | 
					        val errors = ErrorReporterForTests()
 | 
				
			||||||
 | 
					        compileText(VMTarget(), false, src, outputDir, errors = errors) shouldBe null
 | 
				
			||||||
 | 
					        errors.errors.size shouldBe 999
 | 
				
			||||||
 | 
					        // TODO
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xtest("array of pointers as subroutine param") {
 | 
				
			||||||
 | 
					        val src="""
 | 
				
			||||||
 | 
					%option enable_floats
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sub start() {
 | 
				
			||||||
 | 
					        ^^ubyte[4] array1
 | 
				
			||||||
 | 
					        ^^byte[4] array2
 | 
				
			||||||
 | 
					        ^^bool[4] array3
 | 
				
			||||||
 | 
					        ^^word[4] array4
 | 
				
			||||||
 | 
					        ^^uword[4] array5
 | 
				
			||||||
 | 
					        ^^float[4] array6
 | 
				
			||||||
 | 
					        ^^long[4] array7
 | 
				
			||||||
 | 
					        ^^str[4] array8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ok1(array1)
 | 
				
			||||||
 | 
					        ok2(array2)
 | 
				
			||||||
 | 
					        ok3(array3)
 | 
				
			||||||
 | 
					        ok4(array4)
 | 
				
			||||||
 | 
					        ok5(array5)
 | 
				
			||||||
 | 
					        ok6(array6)
 | 
				
			||||||
 | 
					        ok7(array7)
 | 
				
			||||||
 | 
					        ok8(array8)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sub ok1(^^ubyte[] ptr) {
 | 
				
			||||||
 | 
					        cx16.r0 = ptr
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok2(^^byte[] ptr) {
 | 
				
			||||||
 | 
					        cx16.r0 = ptr
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok3(^^bool[] ptr) {
 | 
				
			||||||
 | 
					        cx16.r0 = ptr
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok4(^^word[] ptr) {
 | 
				
			||||||
 | 
					        cx16.r0 = ptr
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok5(^^uword[] ptr) {
 | 
				
			||||||
 | 
					        cx16.r0 = ptr
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok6(^^float[] ptr) {
 | 
				
			||||||
 | 
					        cx16.r0 = ptr
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok7(^^long[] ptr) {
 | 
				
			||||||
 | 
					        cx16.r0 = ptr
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok8(^^str[] ptr) {
 | 
				
			||||||
 | 
					        cx16.r0 = ptr
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}"""
 | 
				
			||||||
 | 
					        compileText(VMTarget(), false, src, outputDir) shouldNotBe null
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
@@ -30,17 +30,45 @@ Typed pointer to simple datatype
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
The syntax for declaring typed pointers is as follows:
 | 
					The syntax for declaring typed pointers is as follows:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``^^type``: pointer to that type
 | 
					``^^type``: pointer to a type
 | 
				
			||||||
    You can declare a pointer to any numeric datatype (bytes, words, longs, floats), booleans,
 | 
					    You can declare a pointer to any numeric datatype (bytes, words, longs, floats), booleans, and also strings.
 | 
				
			||||||
    and also strings.  (the latter, ``^^str`` - a pointer to a string - is equivalient to ``^^ubyte`` though because a string is just an array of ubytes.)
 | 
					    (The latter: ``^^str`` - a pointer to a string - is equivalient to ``^^ubyte`` though because a string is just an array of ubytes.)
 | 
				
			||||||
    ``^^float fptr`` declares fptr as a pointer to a float value.
 | 
					 | 
				
			||||||
    Finally, the type can be a struct type, which then declares a pointer to that struct type. This is explained in the next section.
 | 
					    Finally, the type can be a struct type, which then declares a pointer to that struct type. This is explained in the next section.
 | 
				
			||||||
 | 
					    So, for example; ``^^float fptr`` declares fptr as a pointer to a float value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``^^type[size]``: array with size size containing pointers to type.
 | 
					``^^type[size]``: array with size size containing pointers to a type.
 | 
				
			||||||
    So ``^^word[100] values`` declares values to be an array of 100 pointers to words.
 | 
					    So for example; ``^^word[100] values`` declares values to be an array of 100 pointers to words.
 | 
				
			||||||
    Note that an array of pointers (regardless of the type they point to) is always a @split word array by default.
 | 
					    Note that an array of pointers (regardless of the type they point to) is always a @split word array.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It is not possible to define "pointers to arrays"; ``^^(type[])`` is invalid syntax.
 | 
					It is not possible to define pointers to *arrays*; ``^^(type[])`` is invalid syntax.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Pointers of different types cannot be assigned to one another, unless you use an explicit cast.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Typed pointers and an 'untyped' uword pointer/value can be assigned to each other without an explicit cast.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Because it is pretty common to check if a pointer value is zero or not (because zero usually means that the pointer doesn't exist/has no value),
 | 
				
			||||||
 | 
					pointers can be implicitly cast to a boolean. This allows you to easily write conditionals such as ``while ptr { ... }``
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Dereferencing a pointer, pointer arithmetic
 | 
				
			||||||
 | 
					-------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To get the value the pointer points at, you *dereference* the pointer. The syntax for that is: ``pointer^^``.
 | 
				
			||||||
 | 
					Say the pointer variable is of type ``^^float``, then ``pointer^^`` will return the float value it points at.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can also use array indexing syntax to get the n-th value. For example: ``floatpointer[3]`` will return the
 | 
				
			||||||
 | 
					fourth floating point value in the sequence that the floatpointer points at. Because the pointer is a typed pointer,
 | 
				
			||||||
 | 
					the compiler knows what the size of the value is that it points at and correctly skips forward the required number of bytes in memory.
 | 
				
			||||||
 | 
					In this case, say a float takes 5 bytes, then ``floatpointer[3]`` will return the float value stored at memory address floatpointer+15.
 | 
				
			||||||
 | 
					Notice that ``floatpointer[0]`` is equivalent to ``floatpointer^^``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can add and subtract values from a pointer, this is called **pointer arithmetic**.
 | 
				
			||||||
 | 
					For example, to advance a pointer to the next value, you can use ``pointer++``.
 | 
				
			||||||
 | 
					To make it point to the preceding value, you can use ``pointer--``.
 | 
				
			||||||
 | 
					Adding or subtracting X to a pointer will change the pointer by X times the size of the value it points at (the same as the C language does it).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is true even for pointers to struct types: the compiler knows the storage size of the whole struct type and advances or rewinds
 | 
				
			||||||
 | 
					the pointer value (memory address) by the appropriate number of bytes (X times the size of the struct). More info below.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Structs
 | 
					Structs
 | 
				
			||||||
@@ -53,9 +81,3 @@ Typed pointer to Struct type
 | 
				
			|||||||
----------------------------
 | 
					----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Work in progress.
 | 
					Work in progress.
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Pointer arithmetic and array indexing
 | 
					 | 
				
			||||||
-------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Work in progress.
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,7 +61,11 @@ STRUCTS and TYPED POINTERS
 | 
				
			|||||||
- DONE: added peekbool() and pokebool() and pokebowl()  boolean peek and poke, the latter is equivalent to pokebool()
 | 
					- DONE: added peekbool() and pokebool() and pokebowl()  boolean peek and poke, the latter is equivalent to pokebool()
 | 
				
			||||||
- DONE: fixed support for (expression) array index dereferencing "array[2]^^"   where array contains pointers to primitives: replace with peek()
 | 
					- DONE: fixed support for (expression) array index dereferencing "array[2]^^"   where array contains pointers to primitives: replace with peek()
 | 
				
			||||||
- DONE: fixed support for (assigntarget) array index dereferencing "array[2]^^"   where array contains pointers to primitives: replace with poke()
 | 
					- DONE: fixed support for (assigntarget) array index dereferencing "array[2]^^"   where array contains pointers to primitives: replace with poke()
 | 
				
			||||||
 | 
					- fix ^^bool[] ptr  in sub params
 | 
				
			||||||
 | 
					- ^^bool[3] ptr  in sub param should give proper error for the array size that is not allowed there? or can we actually use it?
 | 
				
			||||||
- write docs in structpointers.rst
 | 
					- write docs in structpointers.rst
 | 
				
			||||||
 | 
					- scan through virtual examples to change untyped uword pointers to typed pointers
 | 
				
			||||||
 | 
					- scan through virtual library modules to change untyped uword pointers to typed pointers
 | 
				
			||||||
- add support for array index dereferencing as assign target "array[2]^^.value = 99"   where array is struct pointers (currently a 'no support' error)
 | 
					- add support for array index dereferencing as assign target "array[2]^^.value = 99"   where array is struct pointers (currently a 'no support' error)
 | 
				
			||||||
- add support for array index dereferencing as assign target "array[2].value = 99"   where array is struct pointers (currently a parser error)
 | 
					- add support for array index dereferencing as assign target "array[2].value = 99"   where array is struct pointers (currently a parser error)
 | 
				
			||||||
- 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)
 | 
				
			||||||
@@ -70,6 +74,9 @@ STRUCTS and TYPED POINTERS
 | 
				
			|||||||
- 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.
 | 
				
			||||||
 | 
					- update structpointers.rst docs with 6502 things?
 | 
				
			||||||
 | 
					- 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
 | 
				
			||||||
- 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"
 | 
					- 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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										110
									
								
								examples/test.p8
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								examples/test.p8
									
									
									
									
									
								
							@@ -1,38 +1,92 @@
 | 
				
			|||||||
 | 
					%import textio
 | 
				
			||||||
%option enable_floats
 | 
					%option enable_floats
 | 
				
			||||||
 | 
					
 | 
				
			||||||
main {
 | 
					main {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sub start() {
 | 
					    sub start() {
 | 
				
			||||||
        ^^ubyte[4] array1 = [1000, 1100, 1200, 1300]
 | 
					        ^^ubyte[4] array1
 | 
				
			||||||
        ^^byte[4] array2 = [1000, 1100, 1200, 1300]
 | 
					        ^^byte[4] array2
 | 
				
			||||||
        ^^bool[4] array3 = [1000, 1100, 1200, 1300]
 | 
					        ^^bool[4] array3
 | 
				
			||||||
        ^^word[4] array4 = [1000, 1100, 1200, 1300]
 | 
					        ^^word[4] array4
 | 
				
			||||||
        ^^uword[4] array5 = [1000, 1100, 1200, 1300]
 | 
					        ^^uword[4] array5
 | 
				
			||||||
        ^^float[4] array6 = [1000, 1100, 1200, 1300]
 | 
					        ^^float[4] array6
 | 
				
			||||||
        ^^long[4] array7 = [1000, 1100, 1200, 1300]
 | 
					        ^^long[4] array7
 | 
				
			||||||
        ^^str[4] array8 = [1000, 1100, 1200, 1300]
 | 
					        ^^str[4] array8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cx16.r0 = array1[2]
 | 
					        error1(array1)
 | 
				
			||||||
        cx16.r1 = array2[2]
 | 
					        error2(array2)
 | 
				
			||||||
        cx16.r2 = array3[2]
 | 
					        error3(array3)
 | 
				
			||||||
        cx16.r3 = array4[2]
 | 
					        error4(array4)
 | 
				
			||||||
        cx16.r4 = array5[2]
 | 
					        error5(array5)
 | 
				
			||||||
        cx16.r5 = array6[2]
 | 
					        error6(array6)
 | 
				
			||||||
        cx16.r6 = array7[2]
 | 
					        error7(array7)
 | 
				
			||||||
        cx16.r7 = array8[2]
 | 
					        error8(array8)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;        txt.print_uw(array[1])
 | 
					        ok1(array1)
 | 
				
			||||||
;        txt.print_uw(array[2])
 | 
					        ok2(array2)
 | 
				
			||||||
;        txt.print_uw(array[3])
 | 
					        ok3(array3)
 | 
				
			||||||
;        txt.print_uw(array[4])
 | 
					        ok4(array4)
 | 
				
			||||||
;        txt.print_uw(array[5])
 | 
					        ok5(array5)
 | 
				
			||||||
;        txt.print_uw(array[6])
 | 
					        ok6(array6)
 | 
				
			||||||
;        txt.print_uw(array[7])
 | 
					        ok7(array7)
 | 
				
			||||||
;
 | 
					        ok8(array8)
 | 
				
			||||||
;        func(farray)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;    sub func(^^float zzz) {
 | 
					    sub error1(^^ubyte ptr) {
 | 
				
			||||||
;        cx16.r0++
 | 
					        cx16.r0++
 | 
				
			||||||
;    }
 | 
					    }
 | 
				
			||||||
 | 
					    sub error2(^^byte ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error3(^^bool ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error4(^^word ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error5(^^uword ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error6(^^float ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error7(^^long ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub error8(^^str ptr) {
 | 
				
			||||||
 | 
					        cx16.r0++
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sub ok1(^^ubyte[] ptr) {
 | 
				
			||||||
 | 
					        txt.print_uw(ptr)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok2(^^byte[] ptr) {
 | 
				
			||||||
 | 
					        txt.print_uw(ptr)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok3(^^bool[] ptr) {
 | 
				
			||||||
 | 
					        txt.print_uw(ptr)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok4(^^word[] ptr) {
 | 
				
			||||||
 | 
					        txt.print_uw(ptr)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok5(^^uword[] ptr) {
 | 
				
			||||||
 | 
					        txt.print_uw(ptr)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok6(^^float[] ptr) {
 | 
				
			||||||
 | 
					        txt.print_uw(ptr)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok7(^^long[] ptr) {
 | 
				
			||||||
 | 
					        txt.print_uw(ptr)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    sub ok8(^^str[] ptr) {
 | 
				
			||||||
 | 
					        txt.print_uw(ptr)
 | 
				
			||||||
 | 
					        txt.nl()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user