1
0
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:
Karol Stasiak
2018-07-20 22:46:53 +02:00
parent ff93775cbe
commit c4c1bf00f2
28 changed files with 826 additions and 178 deletions
+19 -5
View File
@@ -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.
+6
View File
@@ -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
+30
View File
@@ -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.