1
0
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:
Karol Stasiak 2018-01-18 22:35:25 +01:00
parent 6e0a750e48
commit b486436185
9 changed files with 266 additions and 23 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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
View 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.

View File

@ -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 |