From 775707801ce5e4db123a3352b6ea2a607a7b97cc Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Sat, 9 Jun 2018 00:05:17 +0200 Subject: [PATCH] Documentation improvements --- docs/abi/undefined-behaviour.md | 5 +++++ docs/lang/operators.md | 10 ++++++++-- docs/lang/syntax.md | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/docs/abi/undefined-behaviour.md b/docs/abi/undefined-behaviour.md index ee49e1f7..15bb5eb8 100644 --- a/docs/abi/undefined-behaviour.md +++ b/docs/abi/undefined-behaviour.md @@ -30,4 +30,9 @@ even up to hardware damage. * violating the [safe reentrancy rules](../lang/reentrancy.md) +* when using modifying operators: calling non-pure functions in the left-hand-side index expression (like in `a[f()] += b`). +Currently, such functions may be evaluated either once or twice. This might be fixed in the future. + +* when using modifying operators: calling functions on the right-hand-side index expression than modify any of the variables used on the left hand side + The above list is not exhaustive. diff --git a/docs/lang/operators.md b/docs/lang/operators.md index 12349d16..456a5af3 100644 --- a/docs/lang/operators.md +++ b/docs/lang/operators.md @@ -10,7 +10,7 @@ Further improvements to the compiler may increase the number of acceptable combi Certain expressions require the commandline flag `-fzp-register` (`.ini` equivalent: `zeropage_register`) to be enabled. They will be marked with (zpreg) next to them. -The flag is enabled by default, but you can disable it if you need it. +The flag is enabled by default, but you can disable it if you need to. ## Precedence @@ -121,7 +121,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! +**WARNING:** Currently in cases like `a < f() < b`, `f()` may be evaluated an undefined number of times +(the current implementation calls it twice, but do not rely on this behaviour). * `==`: equality `byte == byte` @@ -144,6 +145,9 @@ and fail to compile otherwise. This will be changed in the future. ## Assignment and in-place modification operators +**WARNING:** Unlike other languages, Millfork does not provide any guarantees about how many times the left hand side will be evaluated. +An expression of form `a[f()] += b` may call `f` an undefined number of times. + * `=`: normal assignment `mutable byte = byte` `mutable word = word` @@ -188,6 +192,8 @@ An expression of form `a[i]`, where `i` is an expression of type `byte`, is: Those expressions are of type `byte`. If `a` is any other kind of expression, `a[i]` is invalid. +If the zeropage register is enabled, `i` can also be of type `word`. + ## Built-in functions * `not`: negation of a boolean expression diff --git a/docs/lang/syntax.md b/docs/lang/syntax.md index 9f431e4d..33d6c6d4 100644 --- a/docs/lang/syntax.md +++ b/docs/lang/syntax.md @@ -36,6 +36,24 @@ If not specified, it will be located according to the usual allocation rules. Only global variables can be initialized that way. The behaviour is undefined when targeting a ROM-based platform. +For every variable `x` larger than a byte, extra subvariables are defined: + +* if `x` is of type `word` or `pointer`: + + * constituent bytes, from low to high: `x.lo`, `x.hi` + +* if `x` is of type `farword`: + + * constituent bytes, from low to high: `x.b0`, `x.b1`, `x.b2` + + * partial words: `x.loword` (=`x.b1:x.b0`), `x.hiword` (=`x.b2:x.b1`) + +* if `x` is of type `long`: + + * constituent bytes, from low to high: `x.b0`, `x.b1`, `x.b2`, `x.b3` + + * partial words: `x.loword` (=`x.b1:x.b0`), `x.hiword` (=`x.b3:x.b2`) + ### Constant declarations `const = `