1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-06-26 06:29:28 +00:00

On the way to 1.0: Document multi-value assignment/return values

This commit is contained in:
dschmenk 2017-06-01 13:07:52 -07:00
parent 45500004dd
commit 3415077a2a

View File

@ -365,7 +365,29 @@ byte[64] txtfile = "UNTITLED"
### Function Definitions
Functions are defined after all constants, variables and data. Function definitions can be `export`ed for inclusion in other modules and can be forward declared with a `predef` type in the constant and variable declarations. Functions can take parameters, passed on the evaluation stack, then copied to the local frame for easy access. They can have their own variable declarations, however, unlike the global declarations, no data can be predeclared - only storage space. A local frame is built for every function invocation and there is also a limit of 254 bytes of local storage. Each parameter takes two bytes of local storage, plus two bytes for the previous frame pointer. If a function has no parameters or local variables, no local frame will be created, improving performance. Functions always return a value; a function can specify a value to return or, if no return value is specified, a default of 0 will be returned.
Functions are defined after all constants, variables and data. Function definitions can be `export`ed for inclusion in other modules and can be forward declared with a `predef` type in the constant and variable declarations. Functions can take parameters, passed on the evaluation stack, then copied to the local frame for easy access. They can have their own variable declarations, however, unlike the global declarations, no data can be predeclared - only storage space. A local frame is built for every function invocation and there is also a limit of 254 bytes of local storage. Each parameter takes two bytes of local storage, plus two bytes for the previous frame pointer. If a function has no parameters or local variables, no local frame will be created, improving performance. Functions always return a single value by default.
```
def myfunc(a, b) // Two parameters and defaults to one returned value
```
The number of values to return can be set by appending the number of values after the function definition with the '#' syntax, such as:
```
def myfuncA(a, b)#3 // Two parameters and three returned values
```
A definition with no parameters but with return values can be written as:
```
def myfuncB#2 // No parameters and two returned values
```
A pre-defined definition should include the same number of parameters and return values as the definition:
```
predef myfuncA(a, b)#3
```
A value used as a function pointer doesn't have the parameter/return value count associated with it. It can be overridden in-line:
```
word funcptr = @myfuncA
funcptr(2, 4)#3
```
If fewer values are returned, the remaining values will be padded with zero. It is an error to return more values than specified. Returning zero paramaters is ok, and can save some stack clean-up if the definition is called stand-alone (i.e. as a procedure).
Note: there is no mechanism to ensure caller and callee agree on the number of parameters. Historically, programmers have used Hungarian Notation (http://en.wikipedia.org/wiki/Hungarian_notation) to embed the parameter number and type in the function name itself. This is a notational aid; the compiler enforces nothing.
@ -394,6 +416,23 @@ byte numchars
numchars = 0
```
Multi-value assignments are written with lvalues separated by commas, and the same number of rvalues separated by commas:
```
a, b, c = 2, 4, 6
```
Definitions can return values that contribute to the rvalue count:
```
def myfuncC(p1, p2)#2
return p1+p2, p1-p2
end
a, b, c = 2, myfuncC(6, 7) // Note: myfuncA returns 2 values
```
A quick way to swap variables could be written:
```
a, b = b, a
```
Expressions can be built up with constants, variables, function calls, addresses, and pointers/arrays. Comparison operators evaluate to 0 or -1 instead of the more traditional 0 or 1. The use of -1 allows binary operations to be applied to other non-zero values and still retain a non-zero result. Any conditional tests check only for zero and non-zero values.
There are four basic types of data that can be manipulated: constants, variables, addresses, and functions. Memory can only be read or written as either a byte or a word. Bytes are unsigned 8-bit quantities, words are signed 16-bit quantities. Everything on the evaluation stack is treated as a word. Other than that, any value can be treated as a pointer, address, function, character, integer, etc. There are convenience operations in PLASMA to easily manipulate addresses and expressions as pointers, arrays, structures, functions, or combinations thereof. If a variable is declared as a byte, it can be accessed as a simple, single dimension byte array by using brackets to indicate the offset. Any expression can calculate the indexed offset. A word variable can be accessed as a word array in the same fashion. In order to access expressions or constants as arrays, a type identifier has to be inserted before the brackets. a `.` character denotes a byte type, a `:` character denotes a word type. Along with brackets to calculate an indexed offset, a constant can be used after the `.` or `:` and will be added to the base address. The constant can be a defined const to allow for structure style syntax. If the offset is a known constant, using the constant offset is a much more efficient way to address the elements over an array index. Multidimensional arrays are treated as arrays of array pointers.