Previous Table of Contents Next


11.6. Declarations

There are two basic methods of declaring high or low before the showdown in all High-Low Poker games. They are (1) simultaneous declarations and (2) consecutive declarations.…It is a sad but true fact that the consecutive method spoils the game.

John Scarne’s Guide to Modern Poker

A declaration introduces a name for a constant, a type, a variable, an exception, or a procedure. The scope of the name is the block containing the declaration. A block has the form

   Decls BEGIN S END

where Decls is a sequence of declarations and S is a statement, the executable part of the block. A block can appear as a statement or as the body of a module or procedure. The declarations of a block can introduce a name at most once, although a name can be redeclared in nested blocks, and a procedure declared in an interface can be redeclared in a module exporting the interface. The order of declarations in a block does not matter except to determine the order of initialization of variables.

11.6.1. Types

If T is an identifier and U a type (or type expression because a type expression is allowed wherever a type is required), then

   TYPE T = U

declares T to be the type U.

11.6.2. Constants

If id is an identifier, T a type, and C a constant expression, then

   CONST id: T = C

declares id as a constant with the type T and the value of C. The : T can be omitted, in which case the type of id is the type of C. If T is present, it must contain C.

11.6.3. Variables

If id is an identifier, T a non-empty type other than an open array type, and E an expression, then

   VAR id: T := E

declares id as a variable of type T whose initial value is the value of E. Either := E or : T can be omitted, but not both. If T is omitted, it is taken to be the type of E. If E is omitted, the initial value is an arbitrary value of type T. If both are present, E must be assignable to T.

The initial value is a shorthand that is equivalent to inserting the assignment id := E at the beginning of the executable part of the block. If several variables have initial values, their assignments are inserted in the order they are declared:

   VAR i: [0..5] := j; j: [0..5] := i; BEGIN S END

initializes i and j to the same arbitrary value in [0..5]; it is equivalent to

   VAR i: [0..5]; j: [0..5]; BEGIN i := j; j := i; S END

If a sequence of identifiers share the same type and initial value, id can be a list of identifiers separated by commas. Such a list is shorthand for a list in which the type and initial value are repeated for each identifier:

   VAR v1, ..., vn: T := E

is shorthand for

   VAR v1: T := E; ...; VAR vn: T := E

This means that E is evaluated n times.

11.6.4. Procedures

There are two forms of procedure declaration:

   PROCEDURE id sig = B id
   PROCEDURE id sig

where id is an identifier, sig is a procedure signature, and B is a block. In both cases, the type of id is the procedure type determined by sig. The first form is allowed only in modules; the second form is allowed only in interfaces.

The first form declares id as a procedure constant whose signature is sig, whose body is B, and whose environment is the scope containing the declaration. The parameter names are treated as if they were declared at the outer level of B; the parameter types and default values are evaluated in the scope containing the procedure declaration. The procedure name id must be repeated after the END that terminates the body.

The second form declares id to be a procedure constant whose signature is sig. The procedure body is specified in a module exporting the interface by a declaration of the first form.

11.6.5. Exceptions

If id is an identifier and T a type other than an open array type, then

   EXCEPTION id(T)

declares id as an exception with argument type T. If (T) is omitted, the exception takes no argument. An exception declaration is allowed only in an interface or in the outermost scope of a module. All declared exceptions are distinct.

11.6.6. Opaque Types

An opaque type is a name that denotes an unknown subtype of some given reference type. For example, an opaque subtype of REFANY is an unknown traced reference type; an opaque subtype of UNTRACED ROOT is an unknown untraced object type. The actual type denoted by an opaque type name is called its concrete type.

Different scopes can reveal different information about an opaque type. For example, what is known in one scope only to be a subtype of REFANY could be known in another scope to be a subtype of ROOT.

An opaque type declaration has the form

   TYPE T <: U

where T is an identifier and U an expression denoting a reference type. It introduces the name T as an opaque type and reveals that U is a supertype of T. The concrete type of T must be revealed elsewhere in the program.


Previous Table of Contents Next