The steps involved in converting STIPPLE source code into an executable are shown below:
Translating STIPPLE Source into an ExecutableTranslating STIPPLE source code into an executable is a three step process:
Additional Compiler ModesThe additional compiler modes are:
There is a one-to-one correspondence between routine objects and the code that implements them. In STIPPLE, there are two kinds of routines -- procedures and iterators. Procedures implement the standard abstraction of subroutines and functions. Iterators implement an abstract looping capability (see Why have iterators.)
Routines have two kinds of variables - argument variables, which contain the values passed into the procedure by the caller, and local variables, which contain temporary values used by the procedure. Both kinds of variables only contain a pointers to objects. Each variable is strongly typed and is only permitted to point to objects of the same strong type. All routine variables are initialized when a procedure is called. The argument variables are initialized from values supplied by the caller. All local variables are initialized to point to an appropriate initial object (initial objects are described shortly.)
Composite objects consist of collections of pointers to other objects. Like variables, each of the pointers in a composite object has a strong type and is only permitted to point to objects of the same strong type. Also, like local variables, when a composite object is created, all of its pointers are initialized to point to the appropriate initial objects (initial objects are described in the next paragraph.)
For each distinct object type, there is exactly one instance of the object type that is called the initial object. Since all variables and fields inside of composite objects are initialized to point to the appropriate initial object, STIPPLE has no need for NULL pointers (see Why initial objects.)
While you might expect initial objects to be read-only (immutable), it turns out that they are object just like any other object. While modifying initial objects is considered poor practice, there is no way for STIPPLE to enforce read-only initial objects.
STIPPLE's variable and composite object initialization strategy, in conjunction with garbage collection and infinite recursion detection, ensures referential integrity for programs written entirely in STIPPLE. Thus, a pure STIPPLE program can not `dump core.'
A STIPPLE program is logically decomposed into a sequence routine invocations and simple assignments. A simple assignment assigns the result of an expression evaluation to a variable. For example,
a := b + cis logically equivalent to
a := add@signed32(b, c)
Similarly,
d[e] := f + gis logically equivalent to
store1@vector[signed32](d, e, add@signed32(f, g))As a final example, the figure below shows the state transitions for three variables, a, b, and c, for the following code fragment:
b := 2 c : = 2 a := b + c
Simple assignments example
It should be noted that there is an implementation technique that permits the STIPPLE compiler to store the actual integer values in the variables, rather than pointers to the values. Despite this implementation technique, it must be emphasized that conceptually the STIPPLE data model always stores pointers to objects in variables.
{64-bit types and complex numbers need to be added.}
With the exception of the string type, all STIPPLE base types are immutable. An immutable type is one where the internal object state can not be changed by any operation. Conversely, a mutable type is one where the internal state of an object can be changed via some operation. Thus, immutable objects are read-only and mutable ones are read-write. The only base type that is mutable is the string base type.
All of the floating point number type operations have overflow and underflow detection; whereas the integer base type operations do not have either.
{Range types have not been implemented yet.}
Range types can be constructed from any type that supports the less_than and greater_than ordering operators. This includes all base types and enumeration types. User defined types that define the ordering operators are also permitted in range constructors. All range types constructed from immutable types are themselves immutable; conversely, range types constructed from mutable types are themselves mutable.
The notation for parameterization is to enclose type parameters in square brackets. For example,
The reason for introducing parameterization here is so that type equality can be properly defined in the type equality section below.
This section has some example declarations of STIPPLE declarations. It should be noted that STIPPLE uses indentation to indicate nesting as described in the lexical issues chapter. In STIPPLE, all procedure objects have a strong type called a signature. A procedure signature is derived from its definition by removing the procedure name and argument names, and alphabetizing both the signal and needs names. For example, the most complicated routine declaration is a parameterized iterator with exceptions as shown below:9
procedure name iterator[parameter1, ..., parametern] takes arg_name1 arg_type1 arg_namen arg_type2 ... yields yield_type1, yield_type2, ... returns return_type1, return_type2, ... signals signal_name1 signal_type11, signal_type12, ... signal_name2 signal_type21, signal_type22, ... ... needs needs_name1 needs_type1 needs_name2 needs_type2 ...This iterator has the following signature:
iterator takes arg_type1, arg_type2, ... yields yield_type1, yield_type2, ... returns return_type1, return_type2, signals signal_name1 signal_type11, signal_type12, ... signal_name2 signal_type21, ..., signal_type22, ... ... needs needs_name1 needs_type1 needs_name2 needs_type2 ...
Two routine types are equal if they have exactly the same signature. Two non-routine types are conformant if they are equal or there is a chain of identical declarations that make the types equal. A routine type A is conformant with a routine type B, if all of the types in A are conformant with B and every signal in A is also defined in B.
{Ends too abruptly}