This is one of the
STIPPLE Documentation pages.
STIPPLE Type Declarations
The syntax for define declarations is:
-
type_declaration
-
define new_type_name
{ [parameter_name ,...]
eol
indent
type_clause
{ generate_clause }
outdent
-
type_clause
-
identical_type_clause
-
synonym_type_clause
-
enumeration_type_clause
-
range_type_clause
-
record_type_clause
-
variant_type_clause
-
new_type_name
-
parameter_name
-
generate_clause
-
generate generate_name
,... eold
-
generate_name
-
All define declarations must follow any module,
import, and export declarations.
Each define declaration automatically introduces a
number of object and routine declarations. In addition,
each type clause has the ability to generate a number
of optional routines at the programmer's request. These
optional routines are generated by listing them by name
after the generate keyword. These optional routines are
listed completely in the appropriate appendix. Each of
the type clauses is discussed in the sub-sections that
follow.
The identical Type Declaration
The syntax of the identical type declaration is:
-
identical_type_declaration
-
identical type_reference eol
-
type_reference
-
type_name {
[ type_reference
,... ] }
-
type_name
-
The identical declaration creates a new type,
called new_type_name, that is the same as
other_type_reference in every way (very similar
to a macro.) Objects of type new_type_name and
other_type_reference are indistinguishable from
one another. Internally, the compiler converts
all references to new_type_name to
other_type_reference. No objects or procedures
are introduced by the identical declaration.
Some examples of the identical declaration are:
define length
identical unsigned
define width
identical unsigned
define my_table
identical table[unsigned, unsigned]
Since there are no new routines and objects introduced
by the identical type clause, there is no associated
appendix for identical.
The synonym Type Declaration
The syntax of the synonym type declaration is:
-
synonym_type_clause
-
synonym other_type_reference eol
-
other_type_reference
-
type_reference
-
type_name {
[ type_reference
,... ] }
-
type_name
-
The synonym type declaration creates a new type,
called new_type_name, that has all of the same
operations as other_type_name. Conceptually, the
synonym declaration makes duplicates of all objects
and procedure declarations of type other_type_name
that are accessible to the current module. The
synonym type declaration is not symmetric; if a
new operation is defined for new_type_name it is
not directly accessible to objects of type
other_type_name.
For each synonym declaration, two conversion
routines with the following signatures are introduced:
procedure other_type_name_convert@new_type_name
takes new_type_name
returns other_type_name
#: This routine takes an object of type
#, {new_type_name} and returns an
#, object of type {other_type_name}.
procedure new_type_name_convert@other_type_name
takes other_type_name
returns new_type_name
#: This routine takes an object of type
#, {other_type_name} and returns an
#, object of type {new_type_name}.
These two conversion routines simply take their
argument in one type and return it in another type.
When in-line compiler optimization is enabled,
there is no code generated by either of these routines.
Some examples of the identical declaration follow:
type apples
synonym unsigned
type oranges
synonym unsigned
The compiler will emit an error message whenever an
an attempt is made to add a variable of type apples
to a variable of type oranges.
Appendix ? lists all of the objects and routines
introduced by the synomym declaration.
The enumeration Type Declaration
The syntax of the enumeration type declaration is:
-
enumeration_type_clause
-
enumeration eol
indent
{ enumeration_name eol }+
outdent
-
enumeration_name
-
The enumeration type declaration defines a new
immutable type consisting of a list of objects.
Each enumeration_name in the declaration defines
an object named enumaeration_name@new_type_name.
The enumeration type declaration can not be
parameterized.
The following is an example of an enumeration type
declaration:
define primary_color
enumeration
red
green
blue
The list of all objects and routines introduced by
the enumeration declaration are described in appendix
??.
The range Type Declaration
The syntax of the range type declaration is:
-
range_type_clause
-
range other_type_name
from from_object_reference
to to_object_ref eol
-
other_type_name
-
from_object_reference
-
to_object_reference
-
The range declaration defines a new type that can
take on values between from_object_reference and
to_object_reference. While the range declaration
can be parameterized, there are very few situations
in which it makes sense to do so. The range
declaration requires that other_type_name have
the to_int operator be defined with the following
signature:
procedure new_type_name_convert@other_type_name
takes other_type_name
returns new_type_name
#: This routine will convert its input from
#, {other_type_name} to {new_type_name}
#, and return it.
procedure other_type_name_convert@new_type_name
takes new_type_name
returns other_type_name
#: This routine will convert its input from
#, {new_type_name} to {other_type_name}
#, and return it.
All of the objects and routines provided by the range type
declaration are described in appendix ??.
The record Type Declaration
The syntax of the record type declaration is:
-
record_type_clause
-
record eol
indent
{ field_clause }+
outdent
-
field_clause
-
field_name field_type_reference eol
-
field_name
-
field_type_reference
-
type_reference
-
type_name {
[ type_reference
,... ] }
-
type_name
-
It is an error to have duplicate field names in a
record type declaration.
For each field in the record, two implicit access routines
are defined:
procedure field_name_get@new_type_name
takes new_type_name
returns field_type_reference
#: This routine returns the value of the {field_name}
#, field of {new_type_name}.
procedure field_name_set@new_type_name
takes new_type_name, field_type_reference
returns_nothing
#: This routine sets the {field_name} field of
#, {new_type_name} to field_type.
All of the objects and routines provided by the
record type declaration are described in appendix ??.
The variant type declaration
The syntax of the variant type declaration is:
-
variant_type_clause
-
variant tag_name tag_type_name eol
indent
{ field_clause }+
outdent
-
tag_name
-
tag_type_name
-
field_clause
-
field_name field_type_reference eol
-
field_name
-
field_type_reference
-
type_reference
-
type_name {
[ type_reference
,... ] }
-
type_name
-
The variant declaration defines a tagged variant
object. A tagged variant object has a tag and an
object reference. The tag value specifies the type
of the object reference.
The tag name and all variant field names must be
unique within a variant declaration; duplicate
names will cause a compiler error. If the tag type
is already defined, it must be from an enumeration
type and there must be a one-to-one correspondence
between the variant field names and the enumeration
names; any mismatched variant field names and/or
enumeration names will cause a compilation error.
Alternatively, if the tag type is not already defined,
the compiler will define it as an enumeration type
that has the variant field names as the enumeration
name.
All of the objects and routines provided by the variant
type declaration are described in appendix ??.
The routine Type Declaration
The syntax for the routine type declaration is
quite elaborate and follows below:
-
routine_type_clause
-
procedure_type_clause
-
iterator_type_clause
-
procedure_type_clause
-
procedure eol
indent
{ routine_types_clause }
{ needs_clause }
takes_clause
returns_clause
{ signals_clause }
outdent
-
iteratory_type_clause
-
iterator eol
indent
{ routine_types_clause }
{ needs_clause }
takes_clause
yields_clause
returns_clause
{ signals_clause }
outdent
-
routine_types_clause
-
routine_types eol
indent
{ named_routine_type_clause }+
outdent
-
named_routine_type_clause
-
named_procedure_type_clause
-
named_iterator_type_clause
-
named_procedure_type_clause
-
procedure procedure_name eol
indent
takes_clause
returns_clause
{ signals_clause }
outdent
-
named_iterator_type_clause
-
iterator iterator_name eol
indent
takes_clause
returns_clause
yields_clause
{ signals_clause }
outdent
-
procedure_name
-
iterator_name
-
needs_clause
-
needs eol
indent
{ typed_object_or_routine }+
outdent
-
typed_object_or_routine
-
needs_object_clause
-
needs_procedure_clause
-
needs_iterator_clause
-
needs_object_clause
-
object object_name
@ type_name_eol
-
object_name
-
needs_procedure_clause
-
procedure procedure_name
@ needs_type_name eol
indent
takes_clause
returns_clause
{ signals_clause }
outdent
-
needs_iterator_type_clause
-
iterator iterator_name @
needs_type_name eol
indent
takes_clause
returns_clause
yields_clause
{ signals_clause }
outdent
-
needs_type_name
-
takes_clause
-
takes { type_reference
}+ eol
-
takes_nothing eol
-
returns_clause
-
returns { type_reference
}+ eol
-
returns_nothing eol
-
returns_never eol
-
yields_clause
-
yields { type_reference
}+ eol
-
yields_nothing eol
-
signals_clause
-
signals eol
indent
{ signal_name_clause }+
outdent
-
signal_name_clause
-
signal_name { (
type_reference ,...
) }+ eol
-
signal_name
-
type_reference
-
type_name { [
type_name ,...
] }+
-
type_name
-
The routine type declaration is used to specify
the types of routine variables. Routine variables
can reference either procedures or iterators.
Routines can also be parameterized. The takes
clause specifies the input argument types (and
hence implicitly the number inputs.) The returns
clause specifies the return value types. A no_return
clause specifies that the procedure will never return.
The yields clause specifies iterator yield value types.
Only iterators are permitted to have a yields clause.
The signals clause specifies the names of each signal
that the procedure may signal in addition to any signal
value types returned with the signal. The needs clause
specifies any objects or procedures needed for a
parameterized procedure.
In general, STIPPLE requires that types exactly
match when assignment takes place. Procedure
variables are the exception to this rule. For a
procedure variable, all of the signature clauses,
except the signals clause, must exactly match. For
the signals clause, a routine, A, with fewer signals
can be assigned to a procedure variable, V, with
more signals provided that whatever signals are
defined in procedure A exactly match corresponding
ones in V.
{Variadic clauses are missing.}
Consider the following routines:
define binary_with_overflow
procedure
takes integer, integer
returns integer
signals
overflow
underflow
define binary_without_oveflow
procedure
takes integer, integer
returns integer
The following code fragment provides a simple
example the procedure variable assignment rules:
overflow:: binary_with_overflow
no_overflow:: binary_without_overflow
overflow := overflow # Legal
no_overflow := no_overflow # Legal
overflow := no_overflow # Legal
no_overflow := overflow # Illegal
The following is an example of some
parameterized procedure types:
define sum_routine[type]
procedure
takes vector[type]
returns type
needs
object zero@type
procedure add@type
takes type, type
returns type
signals
overflow
underflow
From here you can go to either the next chapter on
STIPPLE Object and Routine Declarations or
back to the
table of contents.
Copyright (c) 1991 --
Wayne C. Gramlich. All rights reserved.