. navigate
 Navigate
3. Program Structure left arrow
x
right arrow 5. Expressions
Red Reference Manual
4.

TYPES

Types and Subtypes
Use     Specifying     Relationship     Language-Defined and User-Defined
Type Equiv & Comparison     Subtype Equiv & Comparison     Range
Variables & Constants     Var & Const Decl     Overview of Built-in
Type & Subtype Decl     Abbrev     New Type     New Indirect Type
Type & Subtype Inquiry, Predicates & Assertions
Subtype Inquiry     Type Inquiry     Attributes    



4.   TYPES


4.1  TYPES AND SUBTYPES

Types and subtypes are used to specify the properties of data items. These properties control both the values that a data item may have, and the operators, functions, and procedures that may be applied to it.

Data properties may be divided into two groups: type properties, which must be known during translation; and constraint properties, which need not be known during translation, but which must be known when a data item is created. The type of a data item is the collection of all type properties. The subtype of a data item is the collection of all properties, both type and constraint properties. The subtype of a data item is said to belong to its type. Typically, many subtypes, each with a different set of constraint values, will belong to the same type. The two most common constraints on types are range constraints (which limit the range of values of data items having the subtype) and size constraints (which specify the size of data items having the subtype).



EXAMPLES

1) Types

type example

2) Subtypes

subtype example




4.1.1  USE OF TYPES AND SUBTYPES

A subtype must be specified wherever a data item is to be created, such as a variable declaration. A type or a subtype must be specified for each formal parameter. Invocation of a deferred unit with formal parameters is permitted only if the type of each actual parameter ls the same as the type specified (or the type to which the specified subtype belongs) for the corresponding formal parameter. Verifying that types are the same is called type checking; since types consist only of properties that are known during translation, all type checking is done during translation (see Section 4.1.5).



EXAMPLES

type example




4.1.2  SPECIFYING TYPES AND SUBTYPES

For some types, the only type property is their names. Examples are:

type property example

Other types require additional properties. These properties, for all types but arrays, are given in a comma-separated list enclosed in square brackets, called the type property list. For example,

type property list example

is an enumeration type for the values 'a, 'b, and 'c.

When no additional constraints are needed on a type at the time of data creation, the subtype specification of the data looks the same as the type specification of the data. For example,

no additional constraints example

When additional constraints are needed, they are specified in a comma-separated list enclosed in parentheses, called the constraint property list. For example,

additional constraints example

In some cases, the properties of a type may themselves include types. For example,

type in type example

This nesting allows types to be constructed based upon other types. For example,

type based on type example

Subtype constraints are specified by placing constraint property lists after the types and any types contained within the type. For example,

subtype constraint example

Array types and array subtypes are written in a special form. For example,

array form example



RULES

When a specification which could be either a type or a subtype (e.g., BOOL or ENUM['a, 'b] is used in a context where either a type or a subtype is permitted (e.g., for a formal parameter), the specification is interpreted as a type.



EXAMPLES

type specification example




4.1.3  RELATIONSHIP BETWEEN TYPES AND SUBTYPES

Given a subtype, the type to which it belongs can be found by deleting all constraint property lists. For example,

type relationship example




4.1.4  LANGUAGE-DEFINED AND USER-DEFINED TYPES

The language defines a flexible and useful set of types. These types are summarized in Section 4.3. Detailed rules are given in Appendix C.

In some cases, type and subtype specifications will be quite long. For this reason, a convenient abbreviation facility is provided (see Section 4.4.1). Users can also define the abstract types which are specifically needed for their applications. This capability is provided by the type declaration (see Section 4.4.2) together with the capsule declaration (see Chapter 8).



4.1.5  TYPES, TYPE EQUIVALENCE AND TYPE COMPARISON

user-defined type diagram
C - identifier   G - enum literal
10 - type   12 - subtype   18 - abbrev invocation   26 - expression


type comparison diagram
10 - type

Type equivalence rules are used to determine if two types are the same. Type checking is the comparison of two types using the type equivalence rules. Types are checked implicitly for assignment (see Section 6.1) and for invocation of deferred units (see Section 3.3). Types are checked explicitly for type comparisons. All type checking occurs at translation time.



RULES

Types

The result of elaborating a type comparison is a boolean which is true if type 5 is the same as type 6.

To determine if two types are the same, the types are first expanded and then compared.

A type is expanded in the following cases.

  1. If the type contains any abbreviation invocations (see Section 4.4.1), each abbreviation invocation is replaced by the type which is the result of the invocation.

  2. For record or union types, any components of the form

    type components

    are replaced by

    type components replaced

  3. Any TYPEOF forms are replaced by their result type (see Section 4.5.2).

  4. Any references to type generic parameters are replaced by their replacement elements (see Section 11.3.1).



NOTES

    Built-in types are described in Section 4.3. TYPEOF is described in Section 4.5.2.

    Type checking is simplified by the fact that all indirect types are new types and, thus, not expanded into their underlying types. This means that type expansion does not result in cycles.



EXAMPLES

1) Expanding abbreviations

expand abbreviations example

2) Expanding components

expand components example example



4.1.6  SUBTYPES, SUBTYPE EQUIVALENCE AND SUBTYPE COMPARISON

subtype equivalence diagram
C - identifier   10 - type   12 - subtype   14 - range   18 - abbrev invocation   22 - user-defined subtype   26 - expression


subtype comparison diagram
12 - subtype

Subtype equivalence rules are used to determine if two subtypes are the same. Two subtypes can be explicitly compared for equality using a subtype comparison.



RULES

Subtypes

Identifier 1 must be the name of a built-in type. Abbreviation invocation 1 must produce a UNION subtype with no subtype constraint. Abbreviation invocation 2 must produce a subtype. Identifier 4 must be associated with a generic parameter that has a subtype generic constraint (see 11.3.2).


Subtype Comparison

The result of elaborating a subtype comparison is a boolean which is true if subtype 6 is the same as subtype 7.

Two subtypes are the same if their types are the same and if the values of the corresponding constraints in the constraint property lists are equal. Subtype comparison is only permitted for subtypes whose constraints have types for which = is defined.



NOTES

    Built-in types are described in Section 4.3. SUBTYPEOF and INDEXOF are described in Section 4.5.1.

    Subtypes are compared for equality at translation time whenever possible; otherwise, comparison will be performed at run time.

    Two subtypes are implicitly compared for equality when an actual parameter is compared to a formal parameter, specified by subtype, and bound by VAR or READONLY (see Section 7.3). If the comparison produces the value false during implicit comparisons, the X-SUBTYPE exception is raised.



4.1.7  RANGE

type range diagram
26 - expression


A range represents a contiguous sequence of values of some type.



RULES

Expression 1 and expression 2 must have the same type.

If expression 1 is less than expression 2, the range represents all successive values beginning with the lowest value (expression 1) and ending with the highest value (expression 2). If expression 1 and expression 2 have the same value, the range represents only that value. If expression> 2 is less than expression 1, the range represents no values.



NOTES

     Ranges with no values are useful when defining index variables (see Section 6.5), since they allow zero elaborations of a repeat statement body, and when defining arrays (see Section 4.3,  Appendix C.7), since they allow empty arrays. Ranges are used for constraint properties of integer, enumeration, and floating point subtypes, for case statement value labels (see Section 6.4), and for slicing (see Section 5.3).



EXAMPLES

range example




4.2  VARIABLES AND CONSTANTS

Each variable or constant has a subtype which is known when it is created and does not change during its lifetime. There are two kinds of variables, defined variables and dynamic variables. The value of a variable may be both accessed and modified. The value of a constant may be accessed but not directly modified. At creation, all constants must be initialized to some value and each variable is either initialized to some value or is uninitialized. Variables and constants are data items and are further described in Section 5.1.



NOTES

     Defined variables are specified in the following ways:

  1. a variable declaration (declared variable) (see Section 4.2.1).

  2. an OUT formal parameter (parameter variable) (see Section 7.3).

  3. a VAR formal parameter (parameter variable) (see Section 7.3).

  4. a repeat statement with a for phrase (index variable) (see Section 6.5).

    Definitions of declared variables, OUT parameter variables, and index variables create new variables. Definitions of VAR parameter variables associate new names with existing variables.

    There are also dynamic variables which are not defined but, rather, created by elaboration of the ALLOC statement (see Section 4.4.3).

    Constants are defined in the following ways:

  1. a constant declaration (declared constant) (see Section 4.2.1).

  2. a CONST formal parameter (parameter constant) (see Section 7.2).

    Definitions of declared constants and parameter constants create new constants.



4.2.1  VARIABLE OR CONSTANT DECLARATION

variable and constant declaration diagram
C - identifier   12 - subtype   26 - expression   80 - location specification

These declarations define variables and constants.



RULES

Each identifier is defined as a variable (VAR declaration) or a constant (CONST declaration) in the scope in which the declaration is local.

If no subtype is specified for a constant, the subtype of the constant becomes the subtype of the initialization expression. Initialization is performed by assignment (:=).

Elaboration of a variable declaration results in the creation of a variable. If an initialization phrase is present, the variable is initialized to the value given by elaborating the expression in the initialization phrase. Elaboration of a constant declaration results in the creation and initialization of a constant.



NOTES

    Some variables are automatically initialized, even when initialization is not explicitly specified. These are variables of indirect types and ACT, MAILBOX, DATA_LOCK, and FILE types. Automatic initialization can also be established for user-defined types (see Section 13.3).

    Location specifications are used for machine-dependent representations and are described in Section 12.3.



EXAMPLES

variable and constant declaration example




4.3  OVERVIEW OF BUILT-IN TYPES

This section gives a brief overview of the types which are built into the language, along with their subtypes, procedures, and functions. A more detailed presentation of each of the types is given in Appendix C.

If a value can be assigned to a variable (i.e., if the := procedure is defined), the type of the variable is said to be assignable. Note that assignment is used in the following cases:

  1. assignment statements (see Section 6.1);

  2. initialization (see Section 4.2.1);

  3. CONST formal parameters (see Section 7.3);

  4. OUT formal parameters (see Section 7.3);

The relational operators are =, /=, <. >, <=, >= (See Section 5.2).



Boolean

Type: BOOL
Subtype: BOOL
Unary: NOT
Binary: AND, OR, XOR, =, /=
Assignable: yes
Literals: see Section 2.3.9



Integer

Type: INT
Subtype: INT(min..max)
Unary: +, -
Binary: +, -, *, DIV, **, MOD, relational operators
Function: ABS, SUCC, PRED
Assignable: yes
Literals: see Section 2.3.6



Floating Point

Type: FLOAT
Subtype: FLOAT(precision, min..max)
Unary: +, -
Binary: +, -, *, /, **, relational operators
Function: ABS, FLOOR
Assignable: yes
Literals: see Section 2.3.6
Precision is the minimum number of decimal digits to be represented.



Enumeration

Type: ENUM[enum-literal1, enum-literal2,...,enum-literaln]
Subtype: ENUM[enum-literal1, enum-literal2,...,enum-literaln]
              or
              ENUM[enum-literal1, enum-literal2,...,enum-literaln](min..max)(exp)
Binary: relational operators, &
Function: SUCC, PRED, POS
Assignable: yes
Literals: see Section 2.3.7
Enumeration values are ordered as they appear in the type property list, with the leftmost being lowest. A range constraint in an enumeration subtype restricts values from the set of all possible values (in the type) to the set of legal values for this subtype.



Record

Type: RECORD[comp1:type1, comp2:type2,...,compn:typen]
Subtype: RECORD[comp1:subtype1, comp2:subtype2,...,compn:subtypen]
Binary: =, /=
Component Selection: record_var.comp
Assignable: yes, if all components are assignable
Constructor: see Section 5.6
Successive components having the same type can also be written as

record example



Union

Type: UNION[comp1:type1, comp2:type2,...,compn:typen]
Subtype: UNION[comp1:subtype1, comp2:subtype2,...,compn:subtypen]
              or
              UNION[comp1:subtype1, comp2:subtype2,...,compn:subtypen](min..max)
Binary: =, /=
Component Selection: union_var.comp
Tag Inquiry: union_var.TAG Assignable: yes, if all components are assignable
Constructor: see Section 5.6
A union type consists of multiple components, only one of which may be accessed at any point in the lifetime of a union variable of this type. If a subtype constraint is present, variables with that subtype can have only the component whose name is specified in the subtype constraint as an enumeration value. For example,

union example

The tag inquiry returns the name (as an enumeration value) of the component currently accessible. The component which is present in a union may change over the lifetime of the union variable. Successive union components having the same type can also be written as

record example



Array

Type: ARRAY dim-type1, dim-type2,...,dim-typen OF comp-type
Subtype: ARRAY dim-subtype1, dim-subtype2,...,dim-subtypen OF comp-subtype
Binary: & (concatenation for one-dimensional array), =, /=
Component Selection: array-var (position1, position2,...positionn)
                                array-var(min..max) (slicing for one-dimensional array)
Assignable: yes, if component type is assignable
Constructor: see Section 5.6
The dimensions must be integer or enumeration types or subtypes.



Set

Type: SET[type]
Subtype: SET[subtype]
Unary: NOT (complement)
Binary: AND (intersection), OR (union), XOR (symmetric difference), IN (membership),
           relational operations (subset relations)
Assignable: yes
Constructor: see Section 5.6
The type contained in the type property list can only be INT or an enumeration type.



String

Type: STRING[type]
Subtype: STRING[subtype]
Binary: & (concatenation), relational operations
Component Selection: string-var (position)
                                 string-var(min..max)
Assignable: yes
Literals: see Section 2.3.8
The type contained in the type property list must be an enumeration type.



Fixed Point

The first quarterly review of the DoD common language effort has emphasized the lack of a consensus on the military's requirement for a fixed point facility. The fixed point described in Steelman is actually a scaled integer facility. It seems that more discussion is necessary before a decision is reached by the military on the fixed point facility necessary for most applications. When this determination is reached, the design can be built into this language. Some of the possible design alternatives for fixed point are discussed in the companion Rationale document.



NOTES

    There are, besides the basic types discussed above, some other built-in types designed for special purposes. The MAILBOX, DATA_LOCK and ACT types are described in Chapter 10. The LATCH type is described in Appendix C.13. FILE types are described in Appendix C.14. Pointers are not a language type but are instead provided via the indirect form of the type declaration (see Section 4.4.3).




4.4  DECLARATION OF SUBTYPES AND TYPES

Two kinds of declarations can be used for subtypes and types, the abbreviation declaration and the type declaration. Both are deferred declarations.

An abbreviation declaration defines an abbreviation. Invocation of an abbreviation produces the type or subtype specified in the declaration of the abbreviation. An abbreviation is particularly useful when a type or subtype with a long specification is needed in several places in a program. As with all deferred units, an abbreviation can be parameterized. This permits a single abbreviation to be used to abbreviate a set of related subtypes.

A type declaration defines a new type distinct from all other types. The user can create an abstract data type by placing the type declaration within a capsule declaration, together with a set of procedures and functions which operate on actual parameters of the defined type. Since a type is a deferred unit, it may be parameterized (parameters are used to specify the constraint property list of subtypes of the new type) and may be generic (the translation time property list serves as the type property list). There are two basic forms of the type declaration: a direct type declaration and an indirect type declaration. Variables and constants having an indirect type can be used to reference dynamically allocated variables.


4.4.1  ABBREVIATION

abbreviation diagram
C - identifier   10 - type   12 - subtype   52 - formal parameters   53 - actual parameters
66 - formal trans time properties   67 - actual trans time properties


When a long type or subtype specification is needed in several places in a program, an abbreviation for that type or subtype can be defined using the abbreviation declaration. Use of abbreviations can contribute to program reliability by ensuring that all uses of the abbreviation produce the same type or subtype. If the specification is changed, then only the abbreviation need be modified.



RULES

The identifier in an abbreviation declaration is defined to be an abbreviation in the scope in which its declaration appears.

Only CONST formal parameters may be used in an abbreviation declaration. An abbreviation declaration which abbreviates a type may not have any formal parameters.

Elaboration of an abbreviation invocation consists of elaborating the actual parameters, binding the actual parameters to the formal parameters of the named subtype abbreviation (see Section 7.3), and elaborating the type or subtype in the abbreviation declaration. The result of the invocation is the elaborated type or subtype. If the specification following the : could be a type or a subtype, then the result of an invocation can be used as either a type or a subtype. Abbreviations are assumed to be normal (see Section 7.2.1).



NOTES

    An abbreviation declaration is a closed scope. The formal parameters are defined in this scope. Since an abbreviation declaration cannot have an imports list, no variable names may be used within the subtype.

    The only legal use of the abbreviation is in an abbreviation invocation. If the abbreviation is parameterized, the identifier may not be used without parameters as a type.

    Recursive cycles involving only abbreviations are illegal since the resulting specification would be infinite.

    Abbreviations can be overloaded (see Section ll.2) and can be generic (see Section 11.3).



EXAMPLES

abbreviation declaration example



4.4.2  DECLARING AND USING A NEW TYPE

declare new type diagram
C - identifier   12 - subtype   23 - indirect type decl   52 - formal parameters   53 - actual parameters
66 - formal trans time properties   67 - actual trans time properties   78 - representational specification

A type declaration defines a new type, distinct from all other types. For example, the declaration

      TYPE bits(n : INT) : ARRAY INT(1..n) OF BOOL;

defines a new type

      bits

Since the type declaration is a deferred declaration, it defines a deferred unit (a type) which can be invoked. Invocation of a type produces a subtype of that type. For example,

      bits(5)

is a subtype of the type bits. The actual parameter list forms the constraint property list of the subtype. For example, for the subtype bits(5), the constraint property list is (5). The formal parameters of a type are also used to define the attributes of subtypes of that type (see Section 4.5.3).

Each subtype of a type is defined in terms of the subtype specified in the type declaration, which is called the underlying subtype. For example, the underlying subtype of bits(5) is

      ARRAY INT(1..5) OF BOOL

Each underlying subtype of a new type will belong to a type called the underlying type. For example, the underlying type of bits is ARRAY INT OF BOOL. Each variable (or constant) of some user-defined subtype has a component variable (or constant) called the underlying variable (or underlying constant) of the underlying subtype. The standard component selector .ALL is used to access the underlying variable or constant explicitly.

Several operations are automatically defined for each new type: access to the underlying variable or constant; access to components (if any), equality, and assignment. No other operations are automatically defined for a new type. The essential operation on which all other operations are based is .ALL qualification. Given a variable (or constant) with some new type, .ALL qualification produces the underlying variable (or constant). For example, given

      VAR a : bits(5);

then

      a.ALL

is the underlying variable of a and has subtype ARRAY INT(1..5) OF BOOL.

If the underlying type has components (e.g., is an array, record or union), then a component selector operation is automatically defined for the new type in terms of the component selection operation of the underlying type. For example,

      a(i)

can be written instead of

      a.ALL(i)

If the underlying type is assignable, then assignment is also defined for the new type in terms of the assignment for the underlying type. For example, given

      VAR b,c : bits(5);

then

      b := c;

can be written instead of

      b.ALL := c.ALL

If equality is defined for the underlying type, then equality is also defined for the new type in terms of equality for the underlying type. For example,

      b = c

can be written instead of

      b.ALL = c.ALL

A new abstract type can be created by placing a type declaration in the body of a capsule. Operations for the new abstract type are user-defined by procedures and functions defined in the same capsule. The operations take parameters and/or produce results of the abstract type. These operations are implemented using .ALL or component select to access the underlying variables and constants. One important property of an abstract data type is that it is possible to change the underlying type without affecting any users of the abstract type. To achieve this, users of the abstract type must be denied access to the underlying variables of the abstract type. This is accomplished by not exporting either .ALL qualification or any of the selector operations that are automatically defined.



RULES

The identifier in a direct type declaration is defined to be a type name in the scope in which the type declaration appears. If there is no formal translation time property list, then this identifier is the type. If there is a formal translation time properly list, then the types consist of the type identifier together with an actual translation time property list.

Only CONST formal parameters may be used in a type declaration.

Elaboration of a user-defined subtype consists of elaborating the actual parameters, binding the actual parameters to the formal parameters of the named type (see Section 7.3), and elaborating the subtype. The result of a user-defined subtype is a subtype of the invoked type, whose constraint property list is the actual parameter list of the invocation. The underlying subtype of this result subtype is the elaborated subtype.

Each newly defined type has the following operations automatically defined:

  1. Assignment (:=) is defined in terms of assignment for the underlying type. If the underlying type is not assignable, the defined type is not assignable.

  2. Equality <=) is defined in terms of equality for the underlying type. If equality ls not available for the underlying type, then it is not available for the defined type.

  3. Component selection, it the underlying type has components.

  4. .ALL qualification, which allows access to underlying variables and constants.

Types are assumed to be normal (see Section 7.2.1).



NOTES

    A new type is invoked to produce a subtype of that new type. Unlike an abbreviation, if the type ia parameterized (and has no type property list), the identifier may be used without parameters as a type. If no parameter list is present in the type declaration, the defined type has only s single subtype. If a formal parameter list is present, the defined type has one or more subtypes.

    A type declaration is a closed scope. The formal parameter names are defined in this scope. Since a type declaration cannot have an imports list, no variable names may be used within the subtype.

    Users can define their own assignment (:=) procedure, equality (=) function, and selection functions for new types. A user definition of assignment, equality, or of selection will override the automatically provided assignment (see Chapter 13), equality (eee Section 4.1.5), or selection (see Section 13.4) It is also possible to define initialization and finalization operations which are automatically invoked at the beginning and end (respectively) of the lifetime of a data item having e user-defined type (see Section 13.3).

    The type declaration, when used in a generic declaration (see Section 11.3), can be used to create a family of types. Any actual translation time property list serves as the type property list.

    Representation specifications are used for machine-dependent programs and are described in Section 12.2.



EXAMPLES

1) New string types

new string example

1) An abstract data type -- stacks

abstract data type stacks example



4.4.3  DECLARING AND USING A NEW INDIRECT TYPE

declare new indirect type diagram
C - identifier   12 - subtype   26 - expression   28 - variable   52 - formal parameters   53 - actual parameters
66 - formal trans time properties   78 - representational specification

A variable having an indirect type (called an indirect variable) is a pointer. The value of an indirect variable is either nil or a reference to some dynamic variable (i.e., it 'points' to the dynamic variable). For example, in

      TYPE t : PTR STRING(ASCII) (5);
      VAR x,y : t;

The variables x and y are indirect variables that can either have the value nil or can point to some dynamic variable with subtype STRING(ASCII) (5). All indirect variables are automatically initialized to have value nil. There is also a literal for the value nil. For example,

      x := NIL;

sets the value of x to be nil.

A dynamic variable is created by elaboration of an allocation statement. For example, elaboration of

      ALLOC y PTR := "ABCDE";

creates a new dynamic variable with subtype STRING(ASCII) (5), initializes it to have the value "ABCDE", and sets y to point to this dynamic variable. Note that dynamic variables, unlike other variables, are not defined or named.

Dynamic variables are referenced via indirect variables. As with direct types, .ALL qualification and component selection operations (if the underlying dynamic variable has components) are automatically defined. These operations are permitted only if the value of the indirect variable is not nil. The operations provide access to the referenced dynamic variable or its components (i.e., they are 'dereferencing' operations). For example,

dynamic variable example

The lifetime of a dynamic variable is different than that of other variables. A dynamic variable exists as long as there is some way of accessing it. This means that the lifetime of a dynamic variable is not coupled to the elaboration of a scope.

As is the case for direct types, assignment (:=) is also automatically defined for indirect types. The assignment operation for indirects, however, is a "sharing" assignment. For example,

dynamic variable example

The equality operators (=, /=) are also automatically defined for indirect types. For example,

equality for indirect types example

As is the case for all data types, the subtype of a dynamic variable need not be known until the dynamic variable is created. Constraints on a dynamic variable, which are to be resolved at creation time, are specified via an allocation statement. For example,

allocation constraints

Dynamic variables can contain components having indirect types which reference other dynamic variables. This means that recursive data structures, and data structures having cycles, can be created. For example,

recursive data structures

ln addition to indirect variables, it is also possible to define indirect constants. Like all constants, an indirect constant must be initialized and its value may not be changed. The value of the dynamic variable which it references may, however, be changed.

When creating an abstract data type and its subtype, the programmer must ensure that the implementation of the abstract type is invisible to the user. This permits the implementation to be changed without affecting those parts of a program which use the abstract type. The programmer who implements an abstract type should be able to change the underlying type from a direct type to an indirect type (and vice versa), without affecting the users of the abstract type. For example, an abstract stack data type could be implemented using either an array (a direct type) or a linked list (achieved via an indirect type). For this reason, it is important that when a type is exported from a capsule used to realize an abstract data type, it should not be possible to detect outside the capsule whether the exported type was a direct or an indirect type.

As mentioned above, a dynamic variable exists as long as there is some way to access it. Detecting when there is no longer any way to access a dynamic variable, and reclaiming the storage that was used for it, usually involves a process called garbage collection. in some cases, the overhead of full garbage collection can be avoided and a simpler, and less costly, strategy used. For cases where this is impossible, the user can avoid garbage collection costs by the use of the FREE procedure. If v is an indirect variable that points to some dynamic variable, and there are no other pointers to that dynamic variable, then

      FREE(v):

reclaims the storage for that dynamic variable and sets the value of v to nil. If there were other pointers to the dynamic variable, the X_FREE exception is raised (this prevents the problem of dangling pointers). Although this avoids the cost of garbage collection, it introduces some cost in checking that there are no other pointers. For those cases where even this cost is unacceptable, it is possible to inhibit the generation of code for doing this checking by suppressing the X_FREE exception (see Appendix B).



RULES

Indirect Type Declaration

The identifier in an indirect type declaration is defined to be a type name in the scope ln which the indirect type declaration appears. Indirect types are referenced using the same rules (both syntax and semantics) as for direct types (see Section 4.4.2).

Only CONST formal parameters may be used.

Indirect types are invoked using the same syntax as direct types (see Section 4.4.2). Elaboration of a user-defined subtype consists of elaborating the actual parameters and binding the actual parameters to the formal parameters 1 of the named type (see Section 7.3).

The result of a user-defined subtype is a subtype of the invoked type, whose constraint property list is the actual parameter list of the invocation.

The value of an indirect variable or constant is either nil or a reference to some underlying dynamic variable. All indirect variables are automatically initialized to have the value nil.

The following operations are automatically defined for each indirect type:

  1. Assignment (:=) is a sharing assignment. If the indirect subtypes of left hand side and right hand side are not equal, the X_SUBTYPE exception is raised.

  2. Equality (=) is defined to produce true if both of its actual parameters are nil, or if both reference the same dynamic variable.

  3. Component selection, if the underlying type has components. If the value of the variable or constant is nil when component selection is applied to the variable or constant, the X_NIL exception ls raised.

  4. .ALL qualification which gives access to the underlying dynamic variable. If the value of the variable or constant is nil when .ALL qualification is applied to the variable or constant, the X_NIL exception is raised.

Types are assumed to be normal (see Section 7.2.1).


Allocation Statement

The variable must have an indirect type on which .ALL qualification is available.

Elaboration of the allocation statement consists of:

  1. elaborating the variable;
  2. elaborating the actual parameters;

  3. binding the actual parameters to the formal parameters 2 in the indirect type declaration associated with the type of the variable;

  4. elaborating the subtype in the indirect type declaration;

  5. allocating a dynamic variable having that subtype;

  6. if initialization is specified, initializing the newly created dynamic variable (using :=); and

  7. setting the variable named in the allocation statement to be a reference to the newly created dynamic variable.

The dynamic variable must have an assignable type if initialization is specified in an allocation statement.



NOTES

     Because indirect types are always new types, and therefore named, the type equivalence rules are simplified (see Section 4.1.5).

    An indirect type declaration is a closed scope. The formal parameter names (of both formal parameter lists) are defined in this scope. Since a type declaration cannot have an imports list, no variable names may be used within the subtype.

    Representation specifications are used for machine-dependent programs and are described in Section 12.2.



EXAMPLES

1) Indirect string types

indirect string example


2) Defines symbol tables which can hold symbols of different lengths

varying length symbol table example



4.5  TYPE AND SUBTYPE INQUIRY, PREDICATES AND ASSERTIONS

Since a formal parameter can specify a type, rather than a subtype, a deferred unit with a formal parameter can be invoked with actual parameters having any subtype belonging to that type. Although this flexibility is often quite useful, there are cases where it is desirable to further limit either the values or subtypes that actual parameters are permitted to have (in order to exclude values which are not meaningful for the deferred unit). In many cases, these limitations also allow the translator to produce more efficient code.

Some limitations can be achieved by specifying a subtype (rather than a type) for a formal parameter. A finer degree of control can be achieved by including an assertion at the beginning of the body of the deferred unit. Assertions concerning subtypes are supported by language facilities for inquiring about the type, subtype and subtype properties of a data item. These features are discussed in the following subsections.

Inquiry is also useful for several other purposes, including specifying the subtype of local data items of a procedure or function and accessing array index bounds.




4.5.1  SUBTYPE INQUIRY

RULES

If exp is any expression, then the result of elaborating

      SUBTYPE(exp)

is the subtype of that expression.

If exp is an expression for an n-dimensional array, and i is a manifest integer expression whose value is between one and n, then the result of elaborating

      INDEXOF(exp, 1)

is the 1'th index subtype of the array. The form

      TYPE bits(n : INT) : ARRAY INT(1..n) OF BOOL;

is equivalent to

      INDEXOF(exp, 1)



EXAMPLES

subtype inquiry example




4.5.2  TYPE INQUIRY

RULES

If exp is an expression, then the result of elaborating

      TYPE(st)

is the type to which that subtype belongs (see Section 4.1.3).



NOTES

     Elaborations of TYPEOF takes place during translation.




4.5.3  ATTRIBUTES

In addition to inquiry of an entire subtype, it is also possible to inquire about specific subtype constraints, called attributes.


RULES

The attributes of built-in types are listed in Appendix C.

Each formal parameter of a user-defined type is an attribute of that type. The identifier which is the name of the formal parameter is used as the attribute name.


Attribute Inquiry

attribute inquiry diagram
C - identifier   12 - subtype   26 - expression

Attribute inquiry allows attribute values to be accessed.


RULES

The identifier must be the name of an attribute of the specified subtype or of the subtype of the specified expression.

Elaboration of attribute inquiry produces the value of that attribute.



EXAMPLES

attribute inquiry example






Types and Subtypes
Use     Specifying     Relationship     Language-Defined and User-Defined
Type Equiv & Comparison     Subtype Equiv & Comparison     Range
Variables & Constants     Var & Const Decl     Overview of Built-in
Type & Subtype Decl     Abbrev     New Type     New Indirect Type
Type & Subtype Inquiry, Predicates & Assertions
Subtype Inquiry     Type Inquiry     Attributes    

3. Program Structure left arrow
x
right arrow 5. Expressions


Overview

Requirements
     Strawman
     Woodenman
     Tinman
     Ironman
     Steelman

RED Reference
RED Rationale

Types in RED
Time/Life Computer Languages
Memories

Site Index

Overview             Reference ToC             Rationale ToC             Site Index



Home   Favorites   Map

IME logo Copyright © 2009, Mary S. Van Deusen