9. Statements

Statements denote actions. There are elementary and structured statements. Elementary statements are not composed of any parts that are themselves statements. They are the assignment, the procedure call, the return, and the exit statement. Structured statements are composed of parts that are themselves statements. They are used to express sequencing and conditional, selective, and repetitive execution. A statement may also be empty, in which case it denotes no action. The empty statement is included in order to relax punctuation rules in statement sequences.
Statement=[ Assignment | ProcedureCall | IfStatement | CaseStatement | WhileStatement | RepeatStatement | ForStatement | LoopStatement | WithStatement | EXIT | RETURN [Expression] ].

9.1 Assignments

Assignments replace the current value of a variable by a new value specified by an expression. The expression must be assignment compatible with the variable (see App. A). The assignment operator is written as ":=" and pronounced as becomes.
Assignment=Designator ":=" Expression.
If an expression e of type Te is assigned to a variable v of type Tv, the following happens:
  1. if Tv and Te are record types, only those fields of Te are assigned which also belong to Tv (projection); the dynamic type of v must be the same as the static type of v and is not changed by the assignment;
  2. if Tv and Te are pointer types, the dynamic type of v becomes the dynamic type of e;
  3. if Tv is ARRAY n OF CHAR and e is a string of length m <n, v[i] becomes ei for i = 0..m -1 and v[m] becomes 0X.
Examples of assignments (refer to examples in Ch.7):
i := 0
p := i = j
x := i + 1
k := log2(i+j)
F := log2	(* see 10.1 *)
s := {2, 3, 5, 7, 11, 13}
a[i] := (x+y) * (x-y)
t.key := i
w[i+1].name := "John"
t := c

9.2 Procedure calls

A procedure call activates a procedure. It may contain a list of actual parameters which replace the corresponding formal parameters defined in the procedure declaration (see Ch. 10). The correspondence is established by the positions of the parameters in the actual and formal parameter lists. There are two kinds of parameters: variable and value parameters.

If a formal parameter is a variable parameter, the corresponding actual parameter must be a designator denoting a variable. If it denotes an element of a structured variable, the component selectors are evaluated when the formal/actual parameter substitution takes place, i.e. before the execution of the procedure. If a formal parameter is a value parameter, the corresponding actual parameter must be an expression. This expression is evaluated before the procedure activation, and the resulting value is assigned to the formal parameter (see also 10.1).

ProcedureCall=Designator [ActualParameters].
Examples:
WriteInt(i*2+1)  (* see 10.1 *)
INC(w[k].count)
t.Insert("John")  (* see 11 *)

9.3 Statement sequences

Statement sequences denote the sequence of actions specified by the component statements which are separated by semicolons.
StatementSequence=Statement {";" Statement}.

9.4 If statements

IfStatement= IF Expression THEN StatementSequence
{ELSIF Expression THEN StatementSequence}
[ELSE StatementSequence]
END.
If statements specify the conditional execution of guarded statement sequences. The Boolean expression preceding a statement sequence is called its guard. The guards are evaluated in sequence of occurrence, until one evaluates to TRUE, whereafter its associated statement sequence is executed. If no guard is satisfied, the statement sequence following the symbol ELSE is executed, if there is one.

Example:

IF (ch >= "A") & (ch <= "Z") THEN ReadIdentifier
ELSIF (ch >= "0") & (ch <= "9") THEN ReadNumber
ELSIF (ch = " ' ") OR (ch = ' " ') THEN ReadString
ELSE SpecialCharacter
END

9.5 Case statements

Case statements specify the selection and execution of a statement sequence according to the value of an expression. First the case expression is evaluated, then that statement sequence is executed whose case label list contains the obtained value. The case expression must either be of an integer type that includes the types of all case labels, or both the case expression and the case labels must be of type CHAR. Case labels are constants, and no value must occur more than once. If the value of the expression does not occur as a label of any case, the statement sequence following the symbol ELSE is selected, if there is one, otherwise the program is aborted.
CaseStatement=CASE Expression OF Case {"|" Case} [ELSE StatementSequence] END.
Case=[CaseLabelList ":" StatementSequence].
CaseLabelList=CaseLabels {"," CaseLabels}.
CaseLabels=ConstExpression [".." ConstExpression].
Example:
CASE ch OF
  "A" .. "Z": ReadIdentifier
| "0" .. "9": ReadNumber
| "'", '"': ReadString
ELSE SpecialCharacter
END

9.6 While statements

While statements specify the repeated execution of a statement sequence while the Boolean expression (its guard) yields TRUE. The guard is checked before every execution of the statement sequence.
WhileStatement=WHILE Expression DO StatementSequence END.
Examples:
WHILE i > 0 DO i := i DIV 2; k := k + 1 END
WHILE (t # NIL) & (t.key # i) DO t := t.left END

9.7 Repeat statements

A repeat statement specifies the repeated execution of a statement sequence until a condition specified by a Boolean expression is satisfied. The statement sequence is executed at least once.
RepeatStatement=REPEAT StatementSequence UNTIL Expression.

9.8 For statements

A for statement specifies the repeated execution of a statement sequence while a progression of values is assigned to an integer variable called the control variable of the for statement.
ForStatement=FOR ident ":=" Expression TO Expression [BY ConstExpression] DO StatementSequence END.
The statement

FOR v := beg TO end BY step DO statements END

is equivalent to

temp := end; v := beg;
IF step > 0 THEN
WHILE v <= temp DO statements; v := v + step END
ELSE
WHILE v >= temp DO statements; v := v + step END
END

temp has the same type as v. step must be a nonzero constant expression. If step is not specified, it is assumed to be 1.

Examples:

FOR i := 0 TO 79 DO k := k + a[i] END
FOR i := 79 TO 1 BY -1 DO a[i] := a[i-1] END

9.9 Loop statements

A loop statement specifies the repeated execution of a statement sequence. It is terminated upon execution of an exit statement within that sequence (see 9.10).
LoopStatement=LOOP StatementSequence END.
Example:
LOOP
  ReadInt(i);
  IF i < 0 THEN EXIT END;
  WriteInt(i)
END
Loop statements are useful to express repetitions with several exit points or cases where the exit condition is in the middle of the repeated statement sequence.

9.10 Return and exit statements

A return statement indicates the termination of a procedure. It is denoted by the symbol RETURN, followed by an expression if the procedure is a function procedure. The type of the expression must be assignment compatible (see App. A) with the result type specified in the procedure heading (see Ch.10).

Function procedures require the presence of a return statement indicating the result value. In proper procedures, a return statement is implied by the end of the procedure body. Any explicit return statement therefore appears as an additional (probably exceptional) termination point.

An exit statement is denoted by the symbol EXIT. It specifies termination of the enclosing loop statement and continuation with the statement following that loop statement. Exit statements are contextually, although not syntactically associated with the loop statement which contains them.

9.11 With statements

With statements execute a statement sequence depending on the result of a type test and apply a type guard to every occurrence of the tested variable within this statement sequence.
WithStatement=WITH Guard DO StatementSequence
{"|" Guard DO StatementSequence}
[ELSE StatementSequence] END.
Guard=Qualident ":" Qualident.
If v is a variable parameter of record type or a pointer variable, and if it is of a static type T0, the statement

WITH v: T1 DO S1 | v: T2 DO S2 ELSE S3 END

has the following meaning: if the dynamic type of v is T1, then the statement sequence S1 is executed where v is regarded as if it had the static type T1; else if the dynamic type of v is T2, then S2 is executed where v is regarded as if it had the static type T2; else S3 is executed. T1 and T2 must be extensions of T0. If no type test is satisfied and if an else clause is missing the program is aborted.

Example:

WITH t: CenterTree DO i := t.width; c := t.subnode END

Previous Section, Next Section, Contents
Adapted to HTML by Jürgen Geßwein; 8. Juni 1995