Modula-3: Ordinal types

# Ordinal types

There are three kinds of ordinal types: enumerations, subranges, and `INTEGER`. An enumeration type is declared like this:

        TYPE T = {id_1, id_2, ..., id_n}

where the `id`'s are distinct identifiers. The type `T` is an ordered set of `n` values; the expression `T.id_i` denotes the $'th value of the type in increasing order. The empty enumeration `{ }` is allowed.

Integers and enumeration elements are collectively called ordinal values. The base type of an ordinal value `v` is `INTEGER` if `v` is an integer, otherwise it is the unique enumeration type that contains `v`.

A subrange type is declared like this:

        TYPE T = [Lo..Hi]

where `Lo` and `Hi` are two ordinal values with the same base type, called the base type of the subrange. The values of `T` are all the values from `Lo` to `Hi` inclusive. `Lo` and `Hi` must be constant expressions. If `Lo` exceeds `Hi`, the subrange is empty.

The operators `ORD` and `VAL` convert between enumerations and integers. The operators `FIRST`, `LAST`, and `NUMBER` applied to an ordinal type return the first element, last element, and number of elements, respectively.

Here are the predeclared ordinal types:

        INTEGER   All integers represented by the implementation
        CARDINAL  Behaves just like the subrange [0..LAST(INTEGER)]
        BOOLEAN   The enumeration {FALSE, TRUE}
        CHAR      An enumeration containing at least 256 elements

The first 256 elements of type `CHAR` represent characters in the ISO-Latin-1 code, which is an extension of ASCII. The language does not specify the names of the elements of the `CHAR` enumeration. The syntax for character literals is specified in the section on literals. `FALSE` and `TRUE` are predeclared synonyms for `BOOLEAN.FALSE` and `BOOLEAN.TRUE`.

Each distinct enumeration type introduces a new collection of values, but a subrange type reuses the values from the underlying type. For example:

        TYPE
           T1 = {A, B, C};
           T2 = {A, B, C};
           U1 = [T1.A..T1.C];
           U2 = [T1.A..T2.C];  (* sic *)
           V =   {A, B}

`T1` and `T2` are the same type, since they have the same expanded definition. In particular, `T1.C = T2.C` and therefore `U1` and `U2` are also the same type. But the types `T1` and `U1` are distinct, although they contain the same values, because the expanded definition of `T1` is an enumeration while the expanded definition of `U1` is a subrange. The type `V` is a third type whose values `V.A` and `V.B` are not related to the values `T1.A` and `T1.B`.

    Last modified on Wed Apr  3 09:39:00 PST 1996 by heydon
         modified on Mon Apr 18 15:32:23 PDT 1994 by kalsow