Chapter 4:
STATEMENTS

    statement
        =  { label : }  unconditional-statement
        |  { label : }  conditional-statement
        |  { label : }  for-statement

    unconditional-statement
        =  assignment-statement
        |  while-statement
        |  goto-statement
        |  procedure-statement
        |  object-generator
        |  connection-statement
        |  compound-statement
        |  block
        |  dummy-statement
        |  activation-statement

The units of operation within the language are called statements. They are normally executed consecutively as written. The sequence of operations may for instance be broken by goto-statements, which define their successor explicitly, or by sequencing procedure calls, which define their successor implicitly. It may be shortened by conditional statements, which may cause certain statements to be skipped. It may be lengthened by for-statements and while-statements which cause certain statements to be repeated.

In order to make it possible to define an explicit dynamic succession, statements may be provided with labels.

Since sequences of statements may be grouped together into compound statements and blocks the definition of statement must necessarily be recursive. Also since declarations, described in chapter 5, enter fundamentally into the syntactic structure, the syntactic definition of statements must suppose declarations to be already defined.

Assignment statements

    assignment-statement
        =  value-assignment
        |  reference-assignment

    value-assignment
        =  value-left-part  :=  value-right-part

    value-left-part
        =  destination
        |  simple-text-expression

    value-right-part
        =  value-expression
        |  text-expression
        |  value-assignment

    destination
        =  variable
        |  procedure-identifier

    reference-assignment
        =  reference-left-part  :-  reference-right-part

    reference-left-part
        =  destination

    reference-right-part
        =  reference-expression
        |  reference-assignment

Assignment statements serve for assigning the value of an expression to one or several destinations. Assignment to a procedure identifier may only occur within the body of a procedure defining the value of the function designator denoted by that identifier. If assignment is made to a subscripted variable, the values of all the subscripts must lie within the appropriate subscript bounds, otherwise a run-time error will result.

The operator := (read: "becomes") indicates the assignment of a value to the value type variable or value type procedure identifier which is the left part of the value assignment or the assignment of a text value to the text frame referenced by the left part.

The operator :- (read: "denotes") indicates the assignment of a reference to the reference type variable or reference type procedure identifier which is the left part of the reference assignment.

A procedure identifier in this context designates a memory device local to the procedure instance. This memory device is initialised upon procedure entry following the rules given in 5.7. The type associated with a procedure identifier is given as the first symbol of the corresponding procedure declaration.

The value or reference assigned is a (suitably converted) representation of the one obtained by evaluating the right part of the assignment. If the right part is itself an assignment, the value or reference obtained is a copy of its constituent left part after that assignment operation has been completed.

The process is in the general case understood to take place in three steps as follows:

  1. Any expression which is, or is part of, the left part of an assignment is evaluated prior to the evaluation of the right part. Within a particular left part, constituent expressions such as subscript expressions are evaluated in sequence from left to right.
  2. The expression of the ultimate right part is evaluated.
  3. The value or reference of this expression is assigned to its immediately preceding left part. If the left part is itself part of an assignment, the resulting value or reference is assigned to its immediately preceding left part. The process is repeated until the left part list is exhausted. All assignments are performed with any left part expression having values as evaluated in (a).
Note: It is not required that, in multiple assignments, all left parts are of the same type, as long as the appropriate type conversion functions are defined.

If the destination is of type Boolean or character, the value right part must likewise be of type Boolean or character, respectively.

For the description of the text value assignment, see 4.1.2. There is no value assignment operation for objects.

The type of the value or reference obtained by evaluating the right part must coincide with or be subordinate to the type of the left part, with the exceptions mentioned in the following sections.

If a destination is a formal parameter called by name, and the type of the corresponding actual parameter does not coincide with that of the formal specification, then the assignment operation is carried out in two steps.

  1. An assignment is made to a fictitious variable of the type specified for the formal parameter.
  2. An assignment statement is executed whose left part is the actual parameter and whose right part is the fictitious variable.

The value or reference obtained by evaluating the assignment is, in this case, that of the fictitious variable.

Arithmetic assignment

If the type of the arithmetic expression differs from that associated with the destinations, an appropriate conversion function is understood to be automatically invoked. For transfer from real to integer type the conversion function is understood to yield a result which is the largest integral quantity not exceeding E + 0.5 in the mathematical sense (i.e. without rounding error) where E is the value of the expression.

Conversion from integer to short integer is exact within the value range of short integer; outside it constitutes a run-time error. Conversion from long real to real is performed with correct rounding. If the value range of long real exceeds that of real a run-time error may result.

Conversions not mentioned above are performed according to the rules given in 3.5.1.

Note: The value of a real type expression is defined with only finite accuracy.

Note: Consider the statement "X:= i:= Y:= F:= 3.14" where X and Y are real variables, i is an integer variable, and F is a formal parameter called by name and specified real. If the actual parameter for F is a real variable, then X, i, Y and F are given the values 3, 3, 3.14 and 3.14 respectively. If the actual parameter is an integer variable, the respective values are 3, 3, 3.14 and 3.

Text value assignment

Let X be the text variable identified as the result of evaluating the left part (see 3.7) of a text value assignment, and let Y denote the text variable identified by evaluating the corresponding right part. If X references a constant text frame, or X.LENGTH < Y.LENGTH, then the assignment constitutes an error. Otherwise, the value of Y is conceptually extended to the right by X.LENGTH - Y.LENGTH blank characters, and the resulting text value is assigned as the new contents of the text frame referenced by X.

Note: If X==notext, the assignment is legal if and only if Y==notext. The effect on X of the assignment "X := Y" is equivalent to that of "X := copy(Y)", regardless of whether or not X and Y overlap.

The position indicators of the left and the right parts are ignored and remain unchanged.

If X and Y are non-overlapping texts of the same length then, after the evaluation of the value assignment "X:= Y", the relation "X=Y" is true.

A text procedure identifier occurring as a value left part within the procedure body is interpreted as a text variable. The corresponding assignment statement thus implies an assignment to the local procedure identifier.

Text reference assignment

Let X be the text variable which constitutes the left part of a text reference assignment, and let Y denote the variable identified by evaluating the corresponding right part. The effect of the assignment is defined as the four component assignments:

      X.OBJ    :- Y.OBJ;      X.START  := Y.START;
      X.LENGTH := Y.LENGTH;   X.POS    := Y.POS;

Object reference assignment

Let the left part of an object reference assignment be qualified by the class Cl, and let the right part be qualified by Cr. If the right part is itself a reference assignment, Cr is defined as the qualification of its constituent left part. Let V be the value obtained by evaluating the right part. The legality and effect of the reference assignment depend on relationships between Cr, Cl and V.

Case 1.
Cl is the class Cr or outer to Cr: The reference assignment is legal and the assignment operation is carried out.
Case 2.
Cl is inner to Cr: The reference assignment is legal. The assignment operation is carried out if V is none or is an object belonging to the class Cl or a class inner to Cl. If not, the execution of the reference assignment constitutes a run-time error.
Case 3.
Cl and Cr satisfy neither of these relations: The reference assignment is illegal.

Similar rules apply to reference assignments implicit in for-clauses and the transmission of parameters.

Example

Let "point" and "polar" be the classes declared in the example of 5.5.2.

     ref (point) p1, p2; ref (polar) p3;
     p1:- new polar (3,4); p2:- new point (5,6);

Now the statement "p3:-p1" assigns to p3 a reference to the "polar" object which is the value of p1. The statement "p3:-p2" would cause a run-time error.

Conditional statement

    conditional-statement
        =  if-clause { label : } unconditional-statement
           [ else statement ]
        |  if-clause { label : } for-statement

    if-clause
        =  if  Boolean-expression  then

Conditional statements cause certain statements to be executed or skipped depending on the running values of specified Boolean expressions.

Three forms of the conditional statement exist. Let B be a Boolean expression, Su an unconditional statement, Sfor a for-statement and S a statement. Then, in execution of a statement of the form "if B then Su", B is evaluated. If the result is true, Su is executed. If the result is false, Su is not executed. If Su is labelled, and a goto-statement leads to the label, then B is not evaluated, and the computation continues with execution of the labelled statement.

The two remaining forms are explained in terms of the above, as follows.

The conditional statement:   is equivalent to:

if B then Sfor               if B then begin Sfor end

if    B                      if B
then  Su                     then begin Su; goto GAMMA  end;
else  S                      S;
                             GAMMA: ...

If Su, Sfor or S are labelled they are labelled in the equivalent construct.

Note: The effect of a goto-statement leading into a conditional statement follows directly from the above explanation of the execution of a conditional statement.

Examples

         if x>0 then n:=n+1

         if false then abort: terminate_program
         else if s<0 or p<q  then
         else if v>s then a := v-q
         else if v<s-1 then goto abort

While-statement

    while-statement
        =  while  Boolean-expression  do  statement

A while-statement causes a statement to be executed zero or more times.

The evaluation of "while BE do S" is equivalent to

     ALFA: if  BE  then begin  S;  goto ALFA  end

For-statement

    for-statement
        =  for-clause  statement

    for-clause
        =  for  simple-variable  for-right-part  do

    simple-variable
        =  identifier

    for-right-part
        =  := value-for-list-element
           { , value-for-list-element }
        |  :- reference-for-list-element
           { , reference-for-list-element }

    value-for-list-element
        =  value-expression  [ while Boolean-expression ]
        |  text-expression
        |  arithmetic-expression step arithmetic-expression
           until  arithmetic-expression

    reference-for-list-element
        =  reference-expression
           [ while  Boolean-expression ]

The simple variable of the for-clause is called "the controlled variable". The statement following is called "the controlled statement".

A for-clause causes the controlled statement to be executed repeatedly zero or more times. Each execution of the controlled statement is preceded by an assignment to the controlled variable and a test to determine whether this particular for list element is exhausted.

Assignments may change the value of the controlled variable during execution of the controlled statement. Upon exit from the for-statement, the controlled variable has the value given to it by the last (explicit or implicit) assignment operation.

For list elements

The for list elements are considered in the order in which they are written. When one for list element is exhausted, control proceeds to the next, until the last for list element in the list has been exhausted. Execution then continues after the controlled statement.

The effect of each type of for list element is defined below using the following notation:

C:
controlled variable
V:
value expression
R:
reference expression
A:
arithmetic expression
B:
Boolean expression
S:
controlled statement

The effect of the occurrence of expressions as for list elements may be established by textual replacement in the definitions. ALFA and DELTA are considered local to the fictitious block (4.4.3). DELTA is of the same type as A2.

  1. V (value expression)     C := V;
                              S;
                              ... next for list element

  2. A1 step A2 until A3      C     := A1;
                              DELTA := A2;
                              while DELTA*(C-A3) <= 0
                                 do begin
                                    S;
                                    DELTA := A2;
                                    C     := C + DELTA;
                              end while;
                           ... next for list element

  3. V while B         ALFA:  C:= V;
                              if B then begin
                                 S;
                                 goto ALFA; end;
                              ... next for list element

  4. R (reference expression)    C :- R;
                                 S;
                                 ... next for list element

  5. R while B         ALFA:  C :- R;
                              if B then begin
                                 S;
                                 goto ALFA; end;
                              ... next for list element

The controlled variable

The controlled variable cannot be a formal parameter called by name, or a procedure identifier.

To be valid, all for list elements in a for-statement (defined by textual substitution, see 4.4.1) must be semantically and syntactically valid. In particular each implied reference assignment in cases 4 and 5 of 4.4.1 is subject to the rules of 4.1.4 and 4.1.3, and each text value assignment in cases 1 and 3 of 4.4.1 is subject to the rules of 4.1.2.

The controlled statement

The controlled statement always acts as if it were a block, whether it takes this form or not. Hence, labels on or defined within the controlled statement are invisible outside that statement.

Goto-statement

    goto-statement
        =  ( goto | go to )  designational-expression

A goto-statement interrupts the normal sequence of operations, by defining its successor explicitly by the value of a designational expression (i.e. a program point). Thus the next statement to be executed is the one at this program point.

The program point referenced by the designational expression must be visible at the goto-statement (cfr. 5.6.2).

See also 7.3.5.

Examples

         goto  L8
         goto  exit(n+1)
         go to Town(if y<0 then N else N+1)
         goto if Ab<c then L17
                else q(if w<0 then 2 else n)

Procedure statement

    procedure-statement
        =  procedure-identifier-1 [ actual-parameter-part ]

A procedure statement interrupts the normal sequence of operations by invoking (calling for) the execution of a procedure body. Conceptually this may be described in the following terms.

If the procedure has parameters an additional block embracing the procedure body block (cf. 5.4) is created. All formal parameters correspond to variables declared in this (fictitious) block with types as given in the corresponding specifications. Thus formal parameters are non-local to the procedure body, but local to this block. The evaluation of the procedure statement now proceeds as described in 4.6.5.

Actual-formal parameter correspondence

The correspondence between the actual parameters of the procedure statement and the formal parameters of the procedure heading is established as follows. The actual parameter list of the procedure statement must have the same number of entries as the formal parameter list of the procedure declaration heading. The correspondence is obtained by taking the entries of these two lists in the same order.

The type correspondence of formal and actual parameters is governed by the following rules:

Value parameter replacement (call by value)

A formal parameter called by value designates initially a local copy of the value (or array) obtained by evaluating the corresponding actual parameter.

All formal parameters quoted in the value part of the procedure heading as well as value type parameters not quoted in the name part are assigned the values of the corresponding actual parameters, these assignments being considered as performed explicitly before entering the procedure body. The effect is as though an additional block embracing the procedure body were created in which these assignments were made to variables local to this fictitious block with types as given in the corresponding specifications (cf. 4.6.5). As a consequence, variables called by value are to be considered as non-local to the body of the procedure, but local to the fictitious block.

Note: Parameters transmitted by value are evaluated once only, before entry of the procedure body.

A text parameter called by value is a local variable initialised by the statement "FP :- copy(AP)" where FP is the formal parameter, and AP is the variable identified by evaluating the actual parameter. (:- is defined in 4.1.3, and "copy" in 8.3).

Value specification is redundant for a parameter of value type.

There is no call by value option for object reference type parameters and reference type array parameters.

Default parameter replacement (call by reference)

Any formal parameter which is not of value type and which is not quoted in the mode part is said to be called by reference.

A formal parameter called by reference is initially assigned a local copy of the reference obtained by evaluating the corresponding actual parameter. Such assignments are entirely analogous to those described under call by value.

Note: Parameters transmitted by reference are evaluated once before entry of the procedure body.

A reference type formal parameter is a local variable initialised by a reference assignment "FP:- AP" where FP is the formal parameter and AP is the reference obtained by evaluating the actual parameter. The reference assignment is subject to the rules of 4.1.3 and 4.1.4. Since in this case the formal parameter is a reference type variable, its contents may be changed by reference assignments within the procedure body.

Although array, procedure, label and switch identifiers do not designate references to values, there is a strong analogy between references in the strict sense and references to entities such as arrays, procedures (i.e. procedure declarations), program points and switches. Therefore a call by reference mechanism is defined in these cases.

An array, procedure, label or switch parameter called by reference cannot be changed from within the procedure or class body. It thus references the same entity throughout its scope. However, the contents of an array called by reference may well be changed through appropriate assignments to its elements.

For a procedure parameter called by reference, the type associated with the actual parameter must coincide with or be subordinate to that of the formal specification.

Name parameter replacement (call by name)

Call by name is an optional transmission mode available only for parameters to procedures.

Each occurrence of a formal parameter called by name within the procedure body invokes an evaluation of the actual parameter. This evaluation takes place in the context of the procedure statement, i.e. no identifier conflicts can occur (since the procedure body and its variables are invisible).

If the actual and formal parameters are of different arithmetic types, then the appropriate type conversion must take place, irrespective of the context of use of the parameter.

For an expression within a procedure body which is

  1. a formal parameter called by name,
  2. a subscripted variable whose array identifier is a formal parameter called by name, or
  3. a function designator whose procedure identifier is a formal parameter called by name,

the following rules apply:

  1. Its type is that prescribed by the corresponding formal specification.
  2. If the type of the actual parameter does not coincide with that of the formal specification, then an evaluation of the expression is followed by an assignment of the value or reference obtained to a fictitious variable of the latter type. This assignment is subject to the rules of 4.1. The value or reference obtained by the evaluation is the contents of the fictitious variable.

Also, for a formal text parameter called by name, the following rule applies:

Section 4.1 defines the meaning of an assignment to a variable which is a formal parameter called by name, or is a subscripted variable whose array identifier is a formal parameter called by name, if the type of the actual parameter does not coincide with that of the formal specification.

Assignment to a procedure identifier which is a formal parameter is illegal, regardless of its transmission mode.

Note: Each dynamic occurrence of a formal parameter called by name, regardless of its kind, may invoke the execution of a non-trivial expression, e.g. if its actual parameter is a remote identifier, since the actual parameter is evaluated at each occurrence.

Body execution

The execution of a procedure call proceeds in the following steps, where 1 and 2 are performed only if the procedure has parameters.

  1. The formal parameter block instance is created.
  2. Actual parameters corresponding to call by value or call by reference are evaluated as described above and the results are assigned to the corresponding variables of the formal block instance, following the rules in 4.1. Actual parameters corresponding to call by name are treated as described in 4.6.4.
  3. The procedure body is instantiated and starts executing.

The execution of the final statement of the procedure body, unless this statement is itself a goto-statement, concludes with the execution of an implicit goto-statement to the program point immediately following the procedure statement.

Restrictions

For a procedure statement to be defined it is evidently necessary that the operations on the procedure body defined in section 4.6.5 lead to a correct statement. This imposes the restriction on any procedure statement that the kind and type of each actual parameter be compatible with the kind and type of the corresponding formal parameter. The following are some important particular cases of this general rule, and some additional restrictions.

A formal parameter which occurs as a destination within the procedure body and which is called by name can only correspond to an actual parameter which is an identification of a variable (special case of expression).

A formal parameter which is used within the procedure body as an array identifier can only correspond to an actual parameter which identifies an array of the same number of dimensions. In addition if the formal parameter is called by value the local array created during the call has the same subscript bounds as the actual array. Similarly the number, kind and type of any parameters of a formal procedure parameter must be compatible with those of the actual parameter.

Note: The rules stated above are applicable only where formal arrays or procedure calls are actually evaluated during the execution of the procedure body.

Object generator statement

An object generator invokes the generation and execution of an object belonging to the identified class. The object is a new instance of the corresponding (concatenated) class body. The evaluation of an object generator consists of the following actions:

  1. The object is generated and the actual parameters, if any, of the object generator are evaluated. The parameter values and/or references are transmitted.
  2. Control enters the object through its initial begin whereby it becomes operating in the "attached" state (see chapter 7). The evaluation of the object generator is completed:
    case a:
    whenever the basic attribute procedure "detach" of the generated object is executed (see 7.1), or
    case b:
    upon exit through the final end of the object .

The state of the object after the evaluation is either "detached" (a) or "terminated" (b). Cf. chapter 7.

Parameter replacement

In general the correspondence between actual and formal parameters is the same for classes as for procedures.

The call by name option is not available for classes. Procedure, label and switch parameters cannot be transferred to classes.

For further information on the parameter transmission modes, see 5.5.5.

Connection statement

    connection-statement
        =  inspect object-expression
           when-clause { when-clause } [ otherwise-clause ]
        |  inspect object-expression
           do connection-block-2 [ otherwise-clause ]

    when-clause
        =  when class-identifier do connection-block-1

    otherwise-clause
        =  otherwise  statement

    connection-block-1
        =  statement

    connection-block-2
        =  statement

A connection block may itself be or contain a connection statement. This "inner" connection statement is then the largest possible connection statement. Consider the following:

    inspect A when A1 do
          inspect B when B1 do S1           *
                    when B2 do S2           *
                    otherwise S3;           *

The inner connection statement includes the lines that are marked with an asterisk.

The purpose of the connection mechanism is to provide implicit definitions to items 1 and 2 in 5.5.6 for certain attribute identifications within connection blocks.

The execution of a connection statement may be described as follows:

  1. The object expression of the connection statement is evaluated. Let its value be X.
  2. If when-clauses are present they are considered from left to right. If X is an object belonging to a class equal or inner to the one identified by a when-clause, the connection-block-1 of this when-clause is executed, and subsequent when-clauses are skipped. Otherwise, the when-clause is skipped.
  3. If a connection-block-2 is present it is executed, unless X is none in which case the connection block is skipped.
  4. The statement of an otherwise-clause is executed if X is none, or if X is an object not belonging to a class inner to the one identified by any when-clause. Otherwise it is skipped.

A statement which is a connection-block-1 or a connection- block-2 acts as a block, whether it takes the form of a block or not. It further acts as if enclosed by a second fictitious block, called a "connection block". During the execution of a connection block the object X is said to be "connected". A connection block has an associated "block qualification", which is the preceding class identifier for a connection-block-1 and the qualification of the preceding object expression for a connection-block-2.

Let the block qualification of a given connection block be C and let A be an attribute identifier, which is not a label or switch identifier, defined at any prefix level of C. Then any uncommitted occurrence of A within the connection block is given the local significance of being an attribute identification. Its item 1 is the connected object, its item 2 is the block qualification C. It follows that a connection block acts as if its local quantities are those attributes (excluding labels and switches) of the connected object which are defined at prefix levels outer to and including that of C. (Name conflicts between attributes defined at different prefix levels of C are resolved by selecting the one defined at the innermost prefix level.)

Example

Let "Polar" be the class declared in the example of 5.5.2. Then within the connection-block-2 of the connection statement

    inspect new Polar(4,5) do begin ... end

a procedure "plus" is available for vector addition.

Compound statement

    compound-statement
        =  begin  compound-tail

    compound-tail
        =  statement  { ; statement }  end

This syntax may be illustrated as follows: Denoting arbitrary statements and labels, by the letters S and L, respectively, the syntactic unit takes the form:

       L: L: ... begin  S; S; ... S; S end

Note: Each of the statements S may be a complete compound statement or block.

Example

     begin x:=0;
         for y:=1 step 1 until n do x := x + a(y);
         if x>q then goto stop
         else if x>w-2 then goto s;
 aw: st: w:=x+bob
     end

Blocks

    block
        =  subblock
        |  prefixed-block

    subblock
        =  block-head  ;  compound-tail

    block-head
        =  begin  declaration  { ; declaration }

This syntax may be illustrated as follows: Denoting arbitrary statements, declarations, and labels, by the letters S, D, and L, respectively, the syntactic unit takes the form:

    L: L: ... begin D; D; ... D; S; S; ... S; S end

Note: Each of the statements S may be a complete compound statement or block.

Every block automatically introduces a new level of nomenclature. This is realised as follows. Any identifier occurring within the block may through a suitable declaration be specified to be local to the block in question. This means that

  1. the entity represented by this identifier inside the block has no existence outside it, and
  2. any entity represented by this identifier outside the block is invisible inside the block, unless made visible by connection or remote access.

Identifiers (except those representing labels) occurring within a block and not being declared to this block will be non-local to it, i.e. will represent the same entity inside the block and in the level immediately outside it. A label separated by a colon from a statement, i.e. labelling that statement, behaves as though declared in the head of the smallest embracing block.

A label is said to be implicitly declared in this block head. In this context, a procedure body, the statement following a for-clause, or a connection block must be considered as if it were enclosed by begin and end and treated as a block, this block being nested within the fictitious block of 4.6.1 in the case of a procedure with parameters. A label that is not within any block of the program (nor within a procedure body, the statement following a for-clause, or a connection block) is implicitly declared in the implied connection block embracing the program.

Note: System-defined class identifiers used as prefixes within the block as well as identifiers introduced as part of an external head are in this respect treated in the same manner as labels.

Since a statement of a block may itself be a block the concepts local and non-local to a block must be understood recursively. Thus an identifier which is non-local to a block A may or may not be non-local to the block B in which A is a statement. See also 5.6.

Example

   Q:  begin integer i, k; real w;
          for i:=1 step -1 until m do
             for k:=i+1 step 1 until m do begin
                w      := A(i,k);
                A(i,k) := A(k,i);
                A(k,i) := w
             end for i and k
       end  block Q

Prefixed blocks

    prefixed-block
        =  block-prefix  main-block

    block-prefix
        =  class-identifier  [ actual-parameter-part ]

    main-block
        =  block
        |  compound-statement

An instance of a prefixed block is a compound object whose prefix part is an object of the class identified by the block prefix, and whose main part is an instance of the main block. The formal parameters of the former are initialised as indicated by the actual parameters of the block prefix. The concatenation is defined by rules similar to those of 5.5.2.

The following restrictions must be observed:

  1. A class in which reference is made to the class itself through use of this is an illegal block prefix.
  2. The class identifier of a block prefix must refer to a class local to the smallest block enclosing the prefixed block (for system-defined class identifiers, see (2) of 5.5.1).

A program is enclosed by a prefixed block (cf. chapter 10).

Example

Let "hashing" be the class declared in the example of 5.5.3. Then within the prefixed block

  hashing(64) begin
       integer procedure hash(T); text T;
        ... ;
        ...
  end

a "lookup" procedure is available which makes use of the "hash" procedure declared within the main block.

Dummy statement

    dummy-statement
        =  empty
A dummy statement executes no operation. It may serve to place a label.

Example L: begin statements; John: end