This is one of the STIPPLE Documentation pages.

STIPPLE Overview

This chapter gives a basic overview of STIPPLE language concepts, including the data and type models.

The STIPPLE Compiler and Linker

STIPPLE source files are edited using either a plain text editor (e.g. vi or EMACS) or a word processor (e.g. Interleaf or Frame.) For STIPPLE to work with a word processor, two filters must be provided. The first filter takes a word processor file and converts it into a standardized character stream for the compiler. The second filter takes compiler diagnostics and either directly displays them or merges them back into the source file. For the UNIX version of the STIPPLE compiler, the filter choice is selected by the source file suffix.

The steps involved in converting STIPPLE source code into an executable are shown below:

Stipple Translation Steps

  Translating STIPPLE Source into an Executable
								
Translating STIPPLE source code into an executable is a three step process:
Interface Extractaction
Each source file is run through the compiler to produce a corresponding interface file. This step is repeated until all source files have corresponding interface files.

Object File Compilation
Each source file is run through the compiler along with any needed interface files to produce a single object file. This step is repeated until all source files have an associated object file.

Linking
All of the interface and object files are run through the STIPPLE linker to generate a single executable.
The compiler supports some additional modes that are shown in the figure below:

Additional

  Additional Compiler Modes
								
The additional compiler modes are:
Documentation mode.
In documentation mode, the compiler takes a source file and produces interface documentation.

Porting mode.
In porting mode, the compiler takes a source file and emits an ANSI-C source file that corresponds to the source.

Translation mode.
In translate mode, the compiler takes a source file and a translation table file and produces a translated version of the source code and updates the translation table file. Thus, source code written in English can be translated into French and vice versa.

Basic Data Model

For a STIPPLE program, the data model is that all data is represented as strongly typed objects that reside in a garbage collected heap. The objects are either: Most STIPPLE implementations will special case routine objects and exclude them from garbage collection.

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 + c
								
is logically equivalent to
	a := add@signed32(b, c)
								

Similarly,

	d[e] := f + g
								
is 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 Asssignments Example
  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.

STIPPLE Types

STIPPLE provides a rich variety of types and type constructors to the programmer. This section gives an overview to STIPPLE types.

Base Types

STIPPLE provides the following base types:
logical
logical value {true@logical, false@logical}

integer
32-bit signed integer {-2147483648 ... 2147483647}

unsgined
32-bit unsigned integer {0 ... 4294967295}

character
32-bit character

float
32-bit floating point number

string
Variable length string of characters. The string implementation is very efficient at storing strings of 8-bit and 16-bit charcters.

{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.

Giving a Type a New Name

{No type renamining operations have been implemented yet.} P> New types can be created from an existing type by giving the type a new name.
identical
The new type is indistinguishable from the old type (e.g. length and width.)

synonym
The new type has all the same operations as the old type, but is a distinct type that requires conversion to be used with the old type. (e.g. apples and oranges.)

Constrained Types

A constrained type is a type which has a restricted set of values. The following constrained type constructors are supported in STIPPLE:
enumeration
An ordered sequence of named items. (e.g. {red, green, blue})

range
A constrained range of objects. (e.g. {-1 º 1})
Enumeration types are always immutable.

{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.

Composite types

The following composite type constructors are supported in STIPPLE:
record
A named sequence of typed fields.

variant
A tagged variant.
All composite types are mutable.

Parameterized types

STIPPLE supports parameterized (i.e. generic) types and routines. Parameterization enables code reuse in a strongly typed environment. While in many programming languages the terms parameter and argument are used as synonyms, in STIPPLE they are not. In STIPPLE, the term parameter always refers to type parameterization, whereas argument always refers to a routine argument.

The notation for parameterization is to enclose type parameters in square brackets. For example,

vector[integer]
The type vector parameterized with the type integer.

vector[float]
The type vector parameterized with the type float.

vector[vector[integer]]
The type vector parameterized with the type vector[integer].

table[character, integer]
The type table parameterized with the types character and integer.

table[integer, vector[integer]]
The type table parameterized with types integer and vector[integer].

The reason for introducing parameterization here is so that type equality can be properly defined in the type equality section below.

Routine types

{This section is a little too terse.}

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
		...
								

Type Equality and Conformance

In STIPPLE, two non-routine types are equal if they have the same name. If there are any parameters, the parameters types must be the same and in the same order.

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}


From here you can go to either the next chapter on lexical issues or back to the table of contents.
Copyright (c) 1991 -- Wayne C. Gramlich. All rights reserved.