mirror of
https://github.com/KarolS/millfork.git
synced 2026-04-22 00:17:03 +00:00
Enumeration types. Stricter type checks.
This commit is contained in:
+19
-5
@@ -43,11 +43,13 @@ Note that you cannot mix `+'` and `-'` with `+` and `-`.
|
||||
|
||||
In the descriptions below, arguments to the operators are explained as follows:
|
||||
|
||||
* `byte` means any one-byte type
|
||||
* `enum` means any enumeration type
|
||||
|
||||
* `word` means any two-byte type, or a byte expanded to a word
|
||||
* `byte` means any numeric one-byte type
|
||||
|
||||
* `long` means any type longer than two bytes, or a shorter type expanded to such length to match the other argument
|
||||
* `word` means any numeric two-byte type, or a byte expanded to a word; `pointer` is considered to be numeric
|
||||
|
||||
* `long` means any numeric type longer than two bytes, or a shorter type expanded to such length to match the other argument
|
||||
|
||||
* `constant` means a compile-time constant
|
||||
|
||||
@@ -128,11 +130,13 @@ Note you cannot mix those operators, so `a <= b < c` is not valid.
|
||||
(the current implementation calls it twice, but do not rely on this behaviour).
|
||||
|
||||
* `==`: equality
|
||||
`enum == enum`
|
||||
`byte == byte`
|
||||
`simple word == simple word`
|
||||
`simple long == simple long`
|
||||
|
||||
* `!=`: inequality
|
||||
`enum != enum`
|
||||
`byte != byte`
|
||||
`simple word != simple word`
|
||||
`simple long != simple long`
|
||||
@@ -152,6 +156,7 @@ and fail to compile otherwise. This will be changed in the future.
|
||||
An expression of form `a[f()] += b` may call `f` an undefined number of times.
|
||||
|
||||
* `=`: normal assignment
|
||||
`mutable enum = enum`
|
||||
`mutable byte = byte`
|
||||
`mutable word = word`
|
||||
`mutable long = long`
|
||||
@@ -189,13 +194,20 @@ While Millfork does not consider indexing an operator, this is a place as good a
|
||||
|
||||
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 an array that has numeric index type: 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 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`.
|
||||
If the zeropage register is enabled, `i` can also be of type `word`.
|
||||
|
||||
An expression of form `a[i]`, where `i` is an expression of a enumeration type, is:
|
||||
|
||||
* when `a` is an array that has index type equal to the type of `i`:
|
||||
an access to the element of the array `a` at the location assigned to the key `i`
|
||||
|
||||
* otherwise: a compile error
|
||||
|
||||
## Built-in functions
|
||||
|
||||
@@ -212,6 +224,8 @@ Other kinds of expressions than the above (even `nonet(byte + byte + byte)`) wil
|
||||
* `hi`, `lo`: most/least significant byte of a word
|
||||
`hi(word)`
|
||||
|
||||
Furthermore, any type that can be assigned to a variable
|
||||
can be used to convert from one type to another of the same size.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -94,6 +94,12 @@ Syntax:
|
||||
then defaults to `default_code_segment` as defined for the platform if the array has initial values,
|
||||
or to `default` if it doesn't.
|
||||
|
||||
* `<size>`: either a constant number, which then defines the size of the array,
|
||||
or a name of a plain enumeration type, in which case changes the type of the index to that enumeration
|
||||
and declares the array size to be equal to the number of variants in that enumeration.
|
||||
If the size is not specified here, then it's deduced from the `<initial_values>`.
|
||||
If the declared size and the size deduced from the `<initial_values>` don't match, then an error is raised.
|
||||
|
||||
TODO
|
||||
|
||||
### Function declarations
|
||||
|
||||
@@ -41,3 +41,33 @@ TODO
|
||||
## Special types
|
||||
|
||||
* `void` – a unit type containing no information, can be only used as a return type for a function.
|
||||
|
||||
## Enumerations
|
||||
|
||||
Enumeration is a 1-byte type that represents a set of values:
|
||||
|
||||
enum <name> { <variants, separated by commas or newlines> }
|
||||
|
||||
The first variant has value 0. Every next variant has a value increased by 1 compared to a previous one.
|
||||
|
||||
Alternatively, a variant can be given a custom constant value, which will change the sequence.
|
||||
|
||||
If there is at least one variant and no variant is given a custom constant value,
|
||||
then the enumeration is considered _plain_. Plain enumeration types can be used as array keys.
|
||||
For plain enumerations, a constant `<name>.count` is defined,
|
||||
equal to the number of variants in the enumeration.
|
||||
|
||||
Assigment between numeric types and enumerations is not possible without an explicit type cast:
|
||||
|
||||
enum E {}
|
||||
byte b
|
||||
E e
|
||||
e = b // won't compile
|
||||
b = e // won't compile
|
||||
b = byte(e) // ok
|
||||
e = E(b) // ok
|
||||
|
||||
Plain enumerations have their variants equal to `byte(0)` to `byte(<name>.count - 1)`.
|
||||
|
||||
Tip: You can use an enumeration with no variants as a strongly checked alternative byte type,
|
||||
as there are no checks no values when converting bytes to enumeration values and vice versa.
|
||||
|
||||
Reference in New Issue
Block a user