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-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:
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.
The value or reference obtained by evaluating the assignment is, in this case, that of the fictitious variable.
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.
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.
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;
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.
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 = 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 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-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.
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 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 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 | 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-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.
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:
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.
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.
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
the following rules apply:
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.
The execution of a procedure call proceeds in the following steps, where 1 and 2 are performed only if the procedure has parameters.
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.
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.
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:
The state of the object after the evaluation is either "detached" (a) or "terminated" (b). Cf. chapter 7.
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 = 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:
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 = 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
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
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-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:
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 = emptyA dummy statement executes no operation. It may serve to place a label.
Example L: begin statements; John: end