mirror of
https://github.com/KarolS/millfork.git
synced 2025-04-07 11:39:08 +00:00
Some syntax documentation
This commit is contained in:
parent
6e0a750e48
commit
b486436185
@ -2,21 +2,24 @@
|
||||
|
||||
**★ WORK IN PROGRESS ★**
|
||||
|
||||
## Tutorial
|
||||
|
||||
* [Getting started](tutorial/01-getting-started.md)
|
||||
|
||||
* [Basic functions and variables](tutorial/02-functions-variables.md)
|
||||
|
||||
## Compiler usage
|
||||
|
||||
* [Getting started](api/getting-started.md)
|
||||
|
||||
* [Command-line option reference](api/command-line.md)
|
||||
|
||||
* [Target platform reference](api/target-platforms.md)
|
||||
|
||||
## Language reference
|
||||
|
||||
* [Operators](lang/operators.md)
|
||||
* [Syntax](lang/syntax.md)
|
||||
|
||||
* [Types](lang/types.md)
|
||||
|
||||
* [Operators reference](lang/operators.md)
|
||||
|
||||
* [Functions](lang/functions.md)
|
||||
|
||||
* [Inline assembly syntax](lang/assembly.md)
|
||||
|
||||
|
@ -14,6 +14,10 @@ even up to hardware damage.
|
||||
|
||||
* stack overflow: exhausting the hardware stack due to excess recursion, excess function calls or excess stack-allocated variables
|
||||
|
||||
* on ROM-based platforms: writing to arrays
|
||||
|
||||
* on ROM-based platforms: using global variables with an initial value
|
||||
|
||||
* violating the [safe assembly rules](../lang/assembly.md)
|
||||
|
||||
* violating the [safe reentrancy rules](../lang/reentrancy.md)
|
||||
|
@ -35,7 +35,7 @@ The following options are crucial when compiling your sources:
|
||||
|
||||
* `-I DIR;DIR;DIR;...` – specifies the paths to directories with modules to include.
|
||||
|
||||
* `-t PLATFORM` – specifies the target platform (`c64` is the default). Each platform is defined in an `.ini` file in the include directory. For the list of supported platforms, see [Supported platforms](../api/target-platforms.md)
|
||||
* `-t PLATFORM` – specifies the target platform (`c64` is the default). Each platform is defined in an `.ini` file in the include directory. For the list of supported platforms, see [Supported platforms](target-platforms.md)
|
||||
|
||||
You may be also interested in the following:
|
||||
|
@ -1,2 +1,30 @@
|
||||
# Function definitions
|
||||
|
||||
Syntax:
|
||||
|
||||
`[<modifiers>] <return_type> <name> ( <params> ) [@ <address>] { <body> }`
|
||||
|
||||
`asm <return_type> <name> ( <params> ) @ <address> extern`
|
||||
|
||||
* `<modifiers>`: zero or more of the following:
|
||||
|
||||
* `asm` – the function is written in assembly, not in Millfork (doesn't matter for `extern` functions),
|
||||
see [Using assembly within Millfork programs#Assembly functions](./assembly.md#assembly-functions)
|
||||
|
||||
* `inline` – the function should be always inlined,
|
||||
see [Function inlining#Explicit inlining](../abi/inlining.md#explicit-inlining)
|
||||
|
||||
* `interrupt` – the function is a hardware interrupt handler
|
||||
|
||||
* `<return_type>` is a valid return type, see [Types](./types.md)
|
||||
|
||||
* `<params>` is a comma-separated list of parameters, in form `type name`. Allowed types are the same as for local variables.
|
||||
|
||||
* `<address>` is a constant expression that defines where in the memory the function is or will be located.
|
||||
|
||||
* `extern` is a keyword than marks functions that are not defined in the current program,
|
||||
but are likely to be available at certain address in memory.
|
||||
Such functions should be marked as written in assembly and should have their parameters passed through registers.
|
||||
|
||||
* `<body>` is a newline-separated list of either Millfork or assembly statements
|
||||
|
||||
|
@ -1,2 +1,39 @@
|
||||
# Interfacing with external code
|
||||
|
||||
## Calling external functions at a static address
|
||||
|
||||
To call an external function, you need to declare it as `asm extern`. For example:
|
||||
|
||||
```
|
||||
asm void putchar(byte a) @$FFD2 extern
|
||||
```
|
||||
|
||||
The function parameter will be passwed via the accumulator,
|
||||
the function itself is located in ROM at $FFD2. A call like this:
|
||||
|
||||
```
|
||||
putchar(13)
|
||||
```
|
||||
|
||||
will be compiled to something like this:
|
||||
|
||||
```
|
||||
LDA #13
|
||||
JSR $FFD2
|
||||
```
|
||||
|
||||
For more details about how to pass parameters to `asm` functions,
|
||||
see [Using assembly within Millfork programs#Assembly functions](./assembly.md#assembly-functions).
|
||||
|
||||
## Calling external functions at a dynamic address
|
||||
|
||||
To call a function that has its address calculated dynamically,
|
||||
you just need to do the same as what you would do in assembly:
|
||||
|
||||
```
|
||||
asm void call_function(byte a) {
|
||||
JMP (function_address)
|
||||
}
|
||||
```
|
||||
|
||||
where `function_address` is a variable that contains the address of the function to call.
|
@ -52,6 +52,11 @@ Such expressions have the property that the only register they may clobber is Y.
|
||||
|
||||
* `mutable` means an expression than can be assigned to
|
||||
|
||||
## Split-word operator
|
||||
|
||||
Expressions of the shape `h:l` where `h` and `l` are of type byte, are considered expressions of type word.
|
||||
If and only if both `h` and `l` are assignable expressions, then `h:l` is also an assignable expression.
|
||||
|
||||
## Binary arithmetic operators
|
||||
|
||||
* `+`, `-`:
|
||||
@ -103,6 +108,8 @@ These operators (except for `!=`) can accept more than 2 arguments.
|
||||
In such case, the result is true if each comparison in the group is true.
|
||||
Note you cannot mix those operators, so `a <= b < c` is not valid.
|
||||
|
||||
Note that currently in cases like `a < f() < b`, `f()` will be evaluated twice!
|
||||
|
||||
* `==`: equality
|
||||
`byte == byte`
|
||||
`word == word`
|
||||
@ -149,3 +156,16 @@ and fail to compile otherwise. This will be changed in the future.
|
||||
|
||||
There is no `*'=` operator yet.
|
||||
|
||||
## Indexing
|
||||
|
||||
While Millfork does not consider indexing an operator, this is a place as good as any to discuss it.
|
||||
|
||||
An expression of form `a[i]`, where `i` is an expression of type `byte`, is:
|
||||
|
||||
* when `a` is an array: an access to the `i`-th element of the array `a`
|
||||
|
||||
* when `a` is a pointer variable: an access to the byte in memory at address `a + i`
|
||||
|
||||
Those exrpressions are of type `byte`. If `a` is any other kind of expression, `a[i]` is invalid.
|
||||
|
||||
|
||||
|
@ -1 +1,132 @@
|
||||
# Syntax
|
||||
|
||||
For information about types, see [Types](./types.md).
|
||||
For information about literals, see [Literals](./literals.md).
|
||||
For information about assembly, see [Using assembly within Millfork programs](./assembly.md).
|
||||
|
||||
## Comments
|
||||
|
||||
Comments start with `//` and last until the end of line.
|
||||
|
||||
## Declarations
|
||||
|
||||
|
||||
### Variable declarations
|
||||
|
||||
A variable declaration can happen at either top level of a file (*global* variables),
|
||||
or a top level of a function (*local* variables).
|
||||
|
||||
Syntax:
|
||||
|
||||
`[<storage>] <type> <name> [@<address>] [= <initial_value>]`
|
||||
|
||||
* `<storage>` can be only specified for local variables. It can be either `stack`, `static` or nothing.
|
||||
See [the description of variable storage](../abi/variable-storage.md).
|
||||
|
||||
* `<address>` is a constant expression that defines where in the memory the variable will be located.
|
||||
If not specified, it will be located according to the usual allocation rules.
|
||||
`stack` variables cannot have a defined address.
|
||||
|
||||
* `<initial_value>` is a constant expression that contains the initial value of the variable.
|
||||
Only global variables can be initialized that way.
|
||||
The behaviour is undefined when targeting a ROM-based platform.
|
||||
|
||||
### Constant declarations
|
||||
|
||||
`const <type> <name> = <value>`
|
||||
|
||||
TODO
|
||||
|
||||
### Array declarations
|
||||
|
||||
An array is a continuous sequence of bytes in memory.
|
||||
|
||||
Syntax:
|
||||
|
||||
`array <name> [[<size>]] [@<address>] [= <initial_values>]`
|
||||
|
||||
TODO
|
||||
|
||||
### Function declarations
|
||||
|
||||
A function can be declared at the top level. For more details, see [Functions](./functions.md)
|
||||
|
||||
## `import` statements
|
||||
|
||||
TODO
|
||||
|
||||
## Statements
|
||||
|
||||
### Expression statement
|
||||
|
||||
TODO
|
||||
|
||||
### `if` statement
|
||||
|
||||
Syntax:
|
||||
|
||||
```
|
||||
if <expression> {
|
||||
<body>
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
if <expression> {
|
||||
<body>
|
||||
} else {
|
||||
<body>
|
||||
}
|
||||
```
|
||||
|
||||
### `while` and `do-while` statements
|
||||
|
||||
Syntax:
|
||||
|
||||
```
|
||||
while <expression> {
|
||||
<body>
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
do {
|
||||
<body>
|
||||
} while <expression>
|
||||
```
|
||||
|
||||
### `for` statements
|
||||
|
||||
**Warning: `for` loops are a bit buggy.**
|
||||
|
||||
Syntax:
|
||||
|
||||
```
|
||||
for <variable>,<start>,<direction>,<end> {
|
||||
}
|
||||
```
|
||||
|
||||
* `<variable>` – an already defined numeric variable
|
||||
|
||||
* `<direction>` – the range to traverse:
|
||||
|
||||
* `to` – from `<start>` inclusive to `<end>` inclusive, in ascending order
|
||||
(e.g. `0,to,9` to traverse 0, 1,... 9)
|
||||
|
||||
* `downto` – from `<start>` inclusive to `<end>` inclusive, in descending order
|
||||
(e.g. `9,downto,0` to traverse 9, 8,... 0)
|
||||
|
||||
* `until` – from `<start>` inclusive to `<end>` exclusive, in ascending order
|
||||
(e.g. `0,until,10` to traverse 0, 1,... 9)
|
||||
|
||||
* `parallelto` – the same as `to`, but the iterations may be executed in any order
|
||||
|
||||
* `paralleluntil` – the same as `until`, but the iterations may be executed in any order
|
||||
|
||||
There is no `paralleldownto`, because it would do the same as `parallelto`.
|
||||
|
||||
### `asm` statements
|
||||
|
||||
See [Using assembly within Millfork programs](./assembly.md).
|
||||
|
||||
|
36
doc/lang/types.md
Normal file
36
doc/lang/types.md
Normal file
@ -0,0 +1,36 @@
|
||||
# Types
|
||||
|
||||
Millfork puts extra limitations on which types can be used in which contexts.
|
||||
|
||||
## Numeric types
|
||||
|
||||
* `byte` – 1-byte value of undefined signedness, defaulting to unsigned
|
||||
|
||||
* `word` – 2-byte value of undefined signedness, defaulting to unsigned
|
||||
|
||||
* `long` – 4-byte value of undefined signedness, defaulting to unsigned
|
||||
|
||||
* `sbyte` – signed 1-byte value
|
||||
|
||||
* `ubyte` – unsigned 1-byte value
|
||||
|
||||
* `pointer` – the same as `word`, but variables of this type default to be zero-page-allocated
|
||||
and you can index `pointer` variables (not abritrary `pointer`-typed expressions though, `f()[0]` won't compile)
|
||||
|
||||
Functions cannot return types longer than 2 bytes.
|
||||
|
||||
Numeric types can be converted automatically:
|
||||
|
||||
* from a smaller type to a bigger type (`byte`→`word`)
|
||||
|
||||
* from a type of undefined signedness to a type of defined signedness (`byte`→`sbyte`)
|
||||
|
||||
* from a type of defined signedness to a type of undefined signedness (`sbyte`→`byte`)
|
||||
|
||||
## Boolean types
|
||||
|
||||
TODO
|
||||
|
||||
## Special types
|
||||
|
||||
* `void` – a unit type containing no information, can be only used as a return type for a function.
|
@ -1,16 +0,0 @@
|
||||
# Functions and variables
|
||||
|
||||
TODO: write all of this
|
||||
|
||||
## Basic types
|
||||
|
||||
## Defining variables
|
||||
|
||||
## Built-in operators
|
||||
|
||||
### Byte operators
|
||||
|
||||
| a | a | a |
|
||||
| -- | -- | -- |
|
||||
| a | a | a |
|
||||
|
Loading…
x
Reference in New Issue
Block a user