mirror of
https://github.com/irmen/prog8.git
synced 2026-04-21 17:16:33 +00:00
add support for struct pointers and short-form initializers in arrays and assignments
This commit is contained in:
@@ -18,8 +18,8 @@ Structs and Pointers
|
||||
Due to some limitations in the language parser, not all pointer related syntax is currently supported
|
||||
if it is a pointer to a struct type.
|
||||
The compiler tries its best to give a descriptive error message but sometimes there is still a
|
||||
parser limitation that has to be worked around at the moment. For example, this syntax is not supported
|
||||
right now and will result in a parse error::
|
||||
parser limitation that has to be worked around at the moment. For example, this pointer arithmetic
|
||||
indexing syntax is not supported right now and will result in a parse error::
|
||||
|
||||
^^Node np
|
||||
np[2].field = 9999
|
||||
@@ -30,6 +30,8 @@ Structs and Pointers
|
||||
^^Node thirdnode = &&np[2]
|
||||
thirdnode.field = 9999
|
||||
|
||||
*Note: this example is not regular array indexing syntax, it's pointer arithmetic by indexing on the pointer itself. Regular array syntax is supported just fine for arrays containing pointers etc.*
|
||||
|
||||
|
||||
|
||||
Legacy untyped pointers (uword)
|
||||
@@ -139,12 +141,13 @@ You can copy the whole contents of a struct to another one by assigning the dere
|
||||
e1^^ = e2^^ ; copies all fields of e2 into e1
|
||||
|
||||
|
||||
The struct type creates a new name scape, so accessing the fields of a struct is done as usual with the dotted notation::
|
||||
The struct type creates a new name scape, so accessing the fields of a struct is done as usual with the dotted notation.
|
||||
Because it implies pointer dereferencing you can usually omit the explicit `^^`, prog8 will know what it means::
|
||||
|
||||
if e1.ypos > 300
|
||||
e1.health -= 10
|
||||
|
||||
; notice that that implicitly dereferences the pointer variable, actually it is doing this:
|
||||
; explicit dereferencing notation:
|
||||
|
||||
if e1^^.ypos > 300
|
||||
e1^^.health -= 10
|
||||
@@ -184,13 +187,40 @@ called multiple times, or inside a loop, the struct *will be the same instance e
|
||||
Read below if you need *dynamic* struct allocation!
|
||||
You write a static struct initialization expression like this:
|
||||
|
||||
``^^Node : [1,2,3,4]``
|
||||
statically places an instance of struct 'Node' in memory, with its fields set to 1,2,3,4 and returns the address of this struct.
|
||||
``^^Node : [1,"one", 1000, true, 1.111]``
|
||||
statically places an instance of struct 'Node' in memory, with its fields set to 1, "one", 1000 etcetera and returns the address of this struct.
|
||||
The values in the initialization array must correspond exactly with the first to last declared fields in the struct type.
|
||||
``^^Node : []``
|
||||
(without values) Places a 'Node' instance in BSS variable space instead, which gets zeroed out at program startup.
|
||||
Returns the address of this empty struct.
|
||||
|
||||
It is also possible to put struct initializer inside arrays to make them all statically initialized and accessible via the array::
|
||||
|
||||
^^Node[] allnodes = [
|
||||
^^Node: [1,"one", 1000, true, 1.111],
|
||||
^^Node: [2,"two", 2000, false, 2.222],
|
||||
^^Node: [],
|
||||
^^Node: [],
|
||||
]
|
||||
|
||||
Short form initializers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If the required type can be inferred from the context you can also omit the struct pointer type prefix altogether.
|
||||
The initializer value then is syntactically the same as an array, but Prog8 internally turns it back into a proper
|
||||
struct initializer value based on the the type of the array element or pointer variable it is assigned to.
|
||||
So you can write the above in short form as::
|
||||
|
||||
^^Node nodepointer = [1,2,3,4]
|
||||
|
||||
^^Node[] allnodes = [
|
||||
[1,"one", 1000, true, 1.111],
|
||||
[2,"two", 2000, false, 2.222],
|
||||
[],
|
||||
[]
|
||||
]
|
||||
|
||||
|
||||
|
||||
Dynamic allocation of structs
|
||||
=============================
|
||||
|
||||
+12
-1
@@ -58,7 +58,8 @@ and for example the below code omits line 5::
|
||||
STRUCTS and TYPED POINTERS
|
||||
--------------------------
|
||||
|
||||
- can we have some syntactic sugar to avoid the struct name pointer prefix for all array elements that are a struct instance?
|
||||
- fix type checks for wrong pointer types in pointer array initalizer and assignment
|
||||
- fix the pointers/hashtable.p8 example
|
||||
- fix code size regressions (if any left)
|
||||
- optimize deref in PointerAssignmentsGen: optimize 'forceTemporary' to only use a temporary when the offset is >0
|
||||
- update structpointers.rst docs with 6502 specific things?
|
||||
@@ -79,6 +80,16 @@ STRUCTS and TYPED POINTERS
|
||||
Future Things and Ideas
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- optimization conflict detection:
|
||||
1 fun applyModificationsSafely(modifications: List<IAstModification>) {
|
||||
2 // Can check for conflicts before applying
|
||||
3 modifications.groupBy { getTargetNode(it) }.forEach { target, mods ->
|
||||
4 if (mods.size > 1) {
|
||||
5 // Handle or report conflicting modifications
|
||||
6 }
|
||||
7 }
|
||||
8 modifications.forEach { it.perform() }
|
||||
9 }
|
||||
- allow memory() to occur in array initializer
|
||||
- %breakpoint after an assignment is parsed as part of the expression (x % breakpoint), that should not happen
|
||||
- when a complete block is removed because unused, suppress all info messages about everything in the block being removed
|
||||
|
||||
Reference in New Issue
Block a user