mirror of
https://github.com/irmen/prog8.git
synced 2025-11-03 04:17:16 +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