# Oberon types

NOTE: for now, this is a design document, not actual implementation. I need to
straighten out how I think about types.

The unit at [comp/oberon/type.fs] define types used when compiling Oberon code,
but also for managing runtime type checks. This unit is built upon [lib/type].

All basic types are straight Integer-category types, but each of them is still
a distictive type, which means that as a general rule, strict type checking is
done. For example, CHAR and BYTE can't be added with "+". BOOLEAN either. As per
specs, only BYTE and INTEGER can be mixed in binary operations.

When [lib/struct] will be refactored to be a proper [lib/type], the RECORD type
will be a straight up lib/struct type, which will make Dusk structs and Oberon
structs interchangeable (yes, it's coming for [comp/c] too, but Oberon first).

## Arrays

Arrays are tricky because Oberon supports runtime length checks. With sized
arrays such as "ARRAY 42 OF INTEGER", we know that length at compile time. With
open arrays such as "ARRAY OF INTEGER", we only know it at run time. But we
*must* know it. LEN() must work on both types of arrays.

For sized arrays, it's easy. It's the same thing as in C. We know the length and
what we work with is a pointer to the first element of the array.

For open arrays, what we must do is to wrap our array into a (size, dataptr)
pair. Open arrays can only be used as procedure parameters, so they're not
permanent constructs, they're something you generate on-the-fly when you call
a procedure.

This is where it gets tricky: how do you pass that pair to your procedure? The
obvious manner is by pushing it to the parameter stack next to your data
pointer.

A big problem with this approach comes when we begin to consider calling Oberon
procedure from Forth. It will be very confusing to have to remember that open
arrays are "worth" two parameters and is likely to be a source of bugs.

Another approach is to say that open arrays need to be passed as a pair struct
in memory, with +00 being the size and +04 being a pointer to the first element
of the array.

It's less error-prone than the first approach, but it's also significant "fluff"
around each such procedure call. Those pairs have to be memory-managed, that's
more fluff.

So I'm thinking that I'll go with the first approach because, anyways, passing
arrays around from/to the Forth world to/from the Oberon world will be tricky
regardless. Let's worry about that interop problem later.
Because these pairs need to be generated on-the-fly but kept around for unknown
time (the procedure could be long-running), I think I'll use [mem/cons].


