A type declaration introduces a new identifier that is a synonym for the declared type. Its general form is
type type_id = type_definition |
A type definition has several forms. It can define an enumeration, a record, a union, a pointer type, a capability type, a string type or name an already declared or basic type optionally preceded by dimension information.
An array type definition is of the form
dimensions type_id |
where a dimension consists of a list, enclosed in brackets, of one or more ranges separated by commas:
[ range, range, ... ] |
There is one range for each array dimension. A range has one of two forms:
expr : expr or expr
In the first form, the expressions specify the lower and upper bounds. In the second form only the upper bound is specified; its lower value is implicitly 1. The first form may take any ordered type whereas the second form is valid only for integers.
Examples of user defined types are (here aliased)
type age = int type side = real type box = [3] side type name = string[20] type point = [2] real type score_array = [0:100] int type grade_array = ['a':'e'] int type address = [3] string [40] # name, street, city type real_matrix = [10,10] real |
( vector_element, vector_element, ... ) |
Each vector element has one of two forms
expr or [ repetition-expr ] expr |
The first form specifies a single value. The second form specifies zero or more identical values. All values in a constructor must have the same type. Some examples of array constructors are
(0,0,0) ([3] 0)
(1,2,0,0,0,6) (1,2,[3] 0,6)
([3] "") ("smith", [2] "jones")
|
The two constructors on the first line have identical values, as do those on the second line. The following array constructors are assignable to 10 x 10 matrices of reals, such as variables of real_matrix.
([10] ([10] 0.0)) ([5] ([10] 0.0), [5] ([10] 1.0)) |
Enumeration types define symbolic literals. Each enumeration type is an ordered type; the ordering among literals is the order in which they are declared. The definition of an enumeration type contains a list of one or more identifiers separated by commas
enum ( id, id, ... ) |
Examples of enumeration types (aliased):
type primary_color = enum(red, blue, yellow) type machine_name = enum(ivy, holly, thyme) |
Although there are few compile-time checks on enumerations in the implementation of MPD, enumerations still provide many benefits when it comes to code readability.
A record type defines a collection of named data values. Its definition contains a list of one or more field definitions separated by semicolons.
rec ( field_definition; field_definition; ... ) |
Each field definition defines one or more field names of the same type:
variable_type variable_name, variable_name, ... |
The size of each field in a record must be determinable at compile time; i.e. array bounds and string lengths must be compile time constants.
type dims = rec( real height, width ) type person = rec( string[10] name; int grade ) type info = rec ( person p; dims m; bool employed ) |
id ( expr, expr, ... ) |
Examples of record constructors are:
dims(3.8, 2.1) dims(1.4, 20.2)
person("karl", 92) person("gene", 90)
info(person("smith", 78), dims(7.3, 2.9), false)
|
A union type is a collection of other types, each of which has a name. Its form is similar to that of records, but unlike records, the value of a union is just one of its named fields. It seems that the current implementation use records as the implementation of unions, and there usefulness is thus rather limited.
union ( field_definition; field_definition, ... ) |
The field definitions are the same as for records. Examples of unions are (aliased). Use of unions results in a warning from the compiler.
type circle = union( real radius, circumference ) type uperson = union( string[10] name; int id ) |
A variable whose type is a union may be assigned only by assigning to a field in the union. Thus, there are no special constructors for union types.
Pointer types define references to data objects. They have two forms:
ptr ptr_type or ptr any |
The first for defines a pointer to an object of a specific data type while the second form defines a pointer to an object of any type.
type pint = ptr int type ppint = ptr ptr int type pp2int = ptr pint #same as previous type pr = ptr rec(int i1, i2) type pany = ptr any type p7int = ptr [7] int |
Mutually recursive record types are allowed, as in
type r1 = rec( char a; ptr r2 p2) type r2 = rec( char b; ptr r1 p1)w |
The generic pointer type, ptr any, can reference a value of any type. Such a pointer can be assigned to and copied, but it cannot be dereferenced. The pointer literal null is used to indicate a pointer value that points to no valid object. It can be used for all pointer types. The address-of operator @, returns the address of a variable, which can be assigned to a pointer.