mirror of
https://github.com/irmen/prog8.git
synced 2025-11-01 06:16:15 +00:00
start writing docs about structs and pointers, update syntax files with ^^
This commit is contained in:
4
.idea/libraries/eclipse_lsp4j.xml
generated
4
.idea/libraries/eclipse_lsp4j.xml
generated
@@ -4,8 +4,8 @@
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/lsp4j/org.eclipse.lsp4j/0.24.0/org.eclipse.lsp4j-0.24.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/lsp4j/org.eclipse.lsp4j.jsonrpc/0.24.0/org.eclipse.lsp4j.jsonrpc-0.24.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.12.1/gson-2.12.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.36.0/error_prone_annotations-2.36.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.13.1/gson-2.13.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.38.0/error_prone_annotations-2.38.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
@@ -61,6 +61,7 @@ What does Prog8 provide?
|
||||
- code often is smaller and faster than equivalent C code compiled with CC65 or even LLVM-MOS
|
||||
- modularity, symbol scoping, subroutines. No need for forward declarations.
|
||||
- various data types other than just bytes (16-bit words, floats, strings)
|
||||
- Structs and typed pointers
|
||||
- floating point math is supported on certain targets
|
||||
- access to most Kernal ROM routines as external subroutine definitions you can call normally
|
||||
- tight control over Zeropage usage
|
||||
|
||||
@@ -46,6 +46,7 @@ Data types
|
||||
- maximum storage size for arrays is 256 bytes (512 for split word arrays) , the maximum number of elements in the array depends on the size of a single element value.
|
||||
you can use larger "arrays" via pointer indexing, see below at Pointers. One way of obtaining a piece of memory to store
|
||||
such an "array" is by using ``memory()`` builtin function.
|
||||
- there is limited support for structs and typed pointers, see below at "Pointers and Structs".
|
||||
|
||||
|
||||
Variables
|
||||
@@ -76,10 +77,13 @@ Subroutines
|
||||
With only a little bit of code it is possible to implement a simple cooperative multitasking system that runs multiple tasks simultaneously. See the "multitasking" example,
|
||||
which uses the "coroutines" library. Each task is a subroutine and it simply has its state stored in the statically allocated variables so it can resume after yielding, without doing anything special.
|
||||
|
||||
Pointers
|
||||
--------
|
||||
- There is no specific pointer datatype.
|
||||
However, variables of the ``uword`` datatype can be used as a pointer to one of the possible 65536 memory locations,
|
||||
Pointers and Structs
|
||||
--------------------
|
||||
|
||||
Legacy 'untyped' pointers:
|
||||
|
||||
- In Prog8 versions before 12.0 there was no support for typed pointers, only 'untyped' ones:
|
||||
Variables of the ``uword`` datatype can be used as a pointer to one of the possible 65536 memory locations,
|
||||
so the value it points to is always a single byte. This is similar to ``uint8_t*`` from C.
|
||||
You have to deal with the uword manually if the object it points to is something different.
|
||||
- Note that there is the ``peekw`` builtin function that *does* allow you to directy obtain the *word* value at the given memory location.
|
||||
@@ -88,6 +92,12 @@ Pointers
|
||||
- Pointers don't have to be a variable, you can immediately access the value of a given memory location using ``@($d020)`` for instance.
|
||||
Reading is done by assigning it to a variable, writing is done by just assigning the new value to it.
|
||||
|
||||
Typed pointers and structs:
|
||||
|
||||
- Since version 12, prog8 supports struct types and typed pointers.
|
||||
- Structs are a grouping of one or more fields, that together make up the struct type.
|
||||
- Typed pointers are just that: a pointer to a specific type (which can be a simple type such as float, or a struct type.)
|
||||
|
||||
|
||||
Foreign function interface (external/ROM calls)
|
||||
-----------------------------------------------
|
||||
|
||||
@@ -96,6 +96,7 @@ Features
|
||||
and inline assembly to have full control when every register, cycle or byte matters
|
||||
- Variables are all allocated statically, no memory allocation overhead
|
||||
- Variable data types include signed and unsigned bytes and words, arrays, strings.
|
||||
- Structs and typed pointers
|
||||
- Tight control over Zeropage usage
|
||||
- Programs can be restarted after exiting (i.e. run them multiple times without having to reload everything), due to automatic variable (re)initializations.
|
||||
- Programs can be configured to execute in ROM
|
||||
@@ -222,6 +223,7 @@ Look in the `syntax-files <https://github.com/irmen/prog8/tree/master/syntax-fil
|
||||
compiling.rst
|
||||
programming.rst
|
||||
variables.rst
|
||||
structpointers.rst
|
||||
binlibrary.rst
|
||||
libraries.rst
|
||||
targetsystem.rst
|
||||
|
||||
@@ -1061,7 +1061,7 @@ Reusing *virtual registers* R0-R15 for parameters
|
||||
|
||||
Normally, every subroutine parameter will get its own local variable in the subroutine where the argument value
|
||||
will be stored when the subroutine is called. In certain situations, this may lead to many variables being allocated.
|
||||
You *can* instruct the compiler to not allocate a new variable, but instead to reuse one of the *virtual registers* R0-R15
|
||||
You *can* tell the compiler to not allocate a new variable, but instead to reuse one of the *virtual registers* R0-R15
|
||||
(accessible in the code as ``cx16.r0`` - ``cx16.r15``) for the parameter. This is done by adding a ``@Rx`` tag
|
||||
to the parameter. This can only be done for booleans, byte, and word types.
|
||||
Note: the R0-R15 *virtual registers* are described in more detail below for the Assembly subroutines.
|
||||
|
||||
7
docs/source/structpointers.rst
Normal file
7
docs/source/structpointers.rst
Normal file
@@ -0,0 +1,7 @@
|
||||
.. _pointers:
|
||||
|
||||
====================
|
||||
Structs and Pointers
|
||||
====================
|
||||
|
||||
Work in progress.
|
||||
@@ -134,7 +134,8 @@ Calling a subroutine requires three steps:
|
||||
|
||||
#. preparing the arguments (if any) and passing them to the routine.
|
||||
Numeric types are passed by value (bytes, words, booleans, floats),
|
||||
but array types and strings are passed by reference which means as ``uword`` being a pointer to their address in memory.
|
||||
but array types passed by reference which means as ``uword`` being a pointer to their address in memory.
|
||||
Strings are passed as a pointer to a byte: ``^^ubyte``.
|
||||
#. calling the subroutine
|
||||
#. preparing the return value (if any) and returning that from the call.
|
||||
|
||||
|
||||
@@ -58,11 +58,10 @@ STRUCTS and TYPED POINTERS
|
||||
- DONE: allow a.b.ptr[i].value (equiv to a.b.ptr[i]^^.value) expressions (assignment target doesn't parse yet, see below)
|
||||
- DONE: check passing arrays to typed ptr sub-parameters. NOTE: word array can only be a @nosplit array if the parameter type is ^^word, because the words need to be sequential in memory there
|
||||
- DONE: allow str assign to ^^ubyte without cast (take address)
|
||||
- write docs in structpointers.rst
|
||||
- fix support for (expression) array index dereferencing "barray[2]^^" where barray is ^^bool[10]
|
||||
- fix support for (assigntarget) array index dereferencing "barray[2]^^" where barray is ^^bool[10]
|
||||
- fix support for (assigntarget) array index dereferencing "array[2].value" where array is struct pointers
|
||||
- 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 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 make sizeof(^^type) parse correctly (or maybe replace it immediately with sys.SIZEOF_POINTER)
|
||||
- add ?. null-propagation operator (for expression and assignment)?
|
||||
@@ -71,8 +70,6 @@ STRUCTS and TYPED POINTERS
|
||||
- 6502 asm symbol name prefixing should work for dereferences too.
|
||||
- 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)
|
||||
- update syntax highlighting files
|
||||
- write docs
|
||||
|
||||
|
||||
Future Things and Ideas
|
||||
|
||||
@@ -5,6 +5,7 @@ Variables and Values
|
||||
====================
|
||||
|
||||
Because this is such a big subject, variables and values have their own chapter.
|
||||
Structs and pointers are in a separate chapter again: :ref:`pointers`.
|
||||
|
||||
|
||||
Variables
|
||||
@@ -349,7 +350,7 @@ a dynamic location in memory: currently this is equivalent to directly referenci
|
||||
memory at the given index. In contrast to a real array variable, the index value can be the size of a word.
|
||||
Unlike array variables, negative indexing for pointer variables does *not* mean it will be counting from the end, because the size of the buffer is unknown.
|
||||
Instead, it simply addresses memory that lies *before* the pointer variable.
|
||||
See also :ref:`pointervars`
|
||||
See also :ref:`pointervars` and the chapter about it :ref:`pointers`.
|
||||
|
||||
**LSB/MSB split word and str arrays:**
|
||||
|
||||
@@ -572,13 +573,14 @@ without defining a memory-mapped location, you can do so by enclosing the addres
|
||||
@($d020) = 0 ; set the c64 screen border to black ("poke 53280,0")
|
||||
@(vic+$20) = 6 ; you can also use expressions to 'calculate' the address
|
||||
|
||||
This is the official syntax to 'dereference a pointer' as it is often named in other languages.
|
||||
You can actually also use the array indexing notation for this. It will be silently converted into
|
||||
the direct memory access expression as explained above. Note that unlike regular arrays,
|
||||
the index is not limited to an ubyte value. You can use a full uword to index a pointer variable like this::
|
||||
|
||||
pointervar[999] = 0 ; set memory byte to zero at location pointervar + 999.
|
||||
|
||||
More information about *typed pointers* can be found in the chapter :ref:`pointers`.
|
||||
|
||||
|
||||
Converting/Casting types into other types
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -1,56 +1,12 @@
|
||||
%import textio
|
||||
%import strings
|
||||
|
||||
; Animal guessing game where the computer gets smarter every time.
|
||||
; Note: this program can be compiled for multiple target systems.
|
||||
|
||||
main {
|
||||
|
||||
str userinput = "x"*80
|
||||
|
||||
sub start() {
|
||||
db.init()
|
||||
txt.print_uw(db.first)
|
||||
txt.nl()
|
||||
cx16.r0 = db.first
|
||||
struct Node {
|
||||
^^uword s
|
||||
}
|
||||
|
||||
cx16.r1 = db.first.negative
|
||||
cx16.r0 = db.first.negative.animal
|
||||
txt.print_uw(db.first.negative)
|
||||
txt.nl()
|
||||
txt.print(db.first.negative.animal)
|
||||
txt.nl()
|
||||
txt.print(db.first.positive.animal)
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
||||
db {
|
||||
struct Node {
|
||||
str question
|
||||
str animal
|
||||
^^Node negative
|
||||
^^Node positive
|
||||
}
|
||||
|
||||
^^Node first
|
||||
|
||||
sub init() {
|
||||
first = Node("does it swim", 0, 0, 0)
|
||||
^^Node eagle = Node(0, "eagle", 0, 0)
|
||||
^^Node dolpin = Node(0, "dolpin", 0, 0)
|
||||
first.negative = eagle
|
||||
first.positive = dolpin
|
||||
}
|
||||
}
|
||||
|
||||
arena {
|
||||
; extremely trivial arena allocator (that never frees)
|
||||
uword buffer = memory("arena", 10000, 0)
|
||||
uword next = buffer
|
||||
|
||||
sub alloc(ubyte size) -> uword {
|
||||
defer next += size
|
||||
return next
|
||||
^^Node l1
|
||||
|
||||
l1^^.s[0] = 4242
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<Keywords name="Numbers, suffix1"></Keywords>
|
||||
<Keywords name="Numbers, suffix2"></Keywords>
|
||||
<Keywords name="Numbers, range"></Keywords>
|
||||
<Keywords name="Operators1">@ & &< &> | ^ ~ >> << += -= *= = **= &= |= ^= <<= >>= -> = == != < > <= >= , + ++ - -- * ** / ( ) [ ]</Keywords>
|
||||
<Keywords name="Operators1">@ & &< &> | ^ ~ >> << += -= *= = **= &= |= ^= <<= >>= -> = == != < > <= >= , + ++ - -- * ** ^^ / ( ) [ ]</Keywords>
|
||||
<Keywords name="Operators2"></Keywords>
|
||||
<Keywords name="Folders in code1, open">{ {{</Keywords>
|
||||
<Keywords name="Folders in code1, middle"></Keywords>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<Keywords name="Numbers, suffix1"></Keywords>
|
||||
<Keywords name="Numbers, suffix2"></Keywords>
|
||||
<Keywords name="Numbers, range"></Keywords>
|
||||
<Keywords name="Operators1">@ & &< &> | ^ ~ >> << += -= *= = **= &= |= ^= <<= >>= -> = == != < > <= >= , + ++ - -- * ** / ( ) [ ]</Keywords>
|
||||
<Keywords name="Operators1">@ & &< &> | ^ ~ >> << += -= *= = **= &= |= ^= <<= >>= -> = == != < > <= >= , + ++ - -- * ** ^^ / ( ) [ ]</Keywords>
|
||||
<Keywords name="Operators2"></Keywords>
|
||||
<Keywords name="Folders in code1, open">{ {{</Keywords>
|
||||
<Keywords name="Folders in code1, middle"></Keywords>
|
||||
|
||||
@@ -151,6 +151,8 @@ contexts:
|
||||
storage:
|
||||
- match: (\b(ubyte|byte|word|uword|long|float|str|struct)\b)
|
||||
scope: storage.type.prog8
|
||||
- match: (\^\^)
|
||||
scope: storage.modifier.prog8
|
||||
- match: (\b(const)\b)
|
||||
scope: storage.modifier.prog8
|
||||
support:
|
||||
|
||||
@@ -38,7 +38,7 @@ syn match prog8Directive "\(^\|\s\)%\(zpreserved\|zpallowed\|address\|encoding\|
|
||||
syn match prog8Directive "\(^\|\s\)%\(align\|asmbinary\|asminclude\|breakpoint\)\>"
|
||||
syn match prog8Directive "\(^\|\s\)%\(asm\|ir\)\>"
|
||||
|
||||
syn match prog8Type "\<\%(u\?byte\|u\?word\|float\|str\|bool\|long\)\>"
|
||||
syn match prog8Type "\<\%(u\?byte\|u\?word\|float\|str\|bool\|long\|\^\^\)\>"
|
||||
syn region prog8ArrayType matchgroup=prog8Type
|
||||
\ start="\<\%(u\?byte\|u\?word\|float\|str\|bool\)\[" end="\]"
|
||||
\ transparent
|
||||
|
||||
Reference in New Issue
Block a user