# 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]
        ].

- Assignments
- Procedure calls
- Statement sequences
- If statements
- Case statements
- While statements
- Repeat statements
- For statements
- Loop statements
- Return and exit statements
- With statements

## 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 Definition of terms). 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 Variable declarations):

`i := 0`
`p := i = j`
`x := i + 1`
`k := log2(i+j)`
`F := log2` | (* see Formal parameters *)
`s := {2, 3, 5, 7, 11, 13}`
`a[i] := (x+y) * (x-y)`
`t.key := i`
`w[i+1].name := "John"`
`t := c`

## 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 section Procedure types). 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 Formal parameters).

      ProcedureCall = Designator [ActualParameters].

Examples:

`WriteInt(i*2+1)` | (* see Formal parameters *)
`INC(w[k].count)`
`t.Insert("John")` | (* see Modules *)

## Statement sequences

Statement sequences denote the sequence of actions specified by the component statements which are separated by semicolons.

      StatementSequence = Statement {";" Statement}.

## 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;

## 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

## 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

## 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.

## For statements

A for statement specifies the repeated execution of a statement sequence for a fixed number of times 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 non-zero 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

## 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 Return and exit statements).

      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.

## 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 Definition of terms) with the result type specified in the procedure heading (see section Procedure declarations).

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.

## 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