Modula-3: For statements

# For

A `FOR` statement has the form:

        FOR id := first TO last BY step DO S END

where `id` is an identifier, `first` and `last` are ordinal expressions with the same base type, `step` is an integer-valued expression, and `S` is a statement. "`BY step`" is optional; if omitted, `step` defaults to `1`.

The identifier `id` denotes a readonly variable whose scope is `S` and whose type is the common basetype of `first` and `last`.

If `id` is an integer, the statement steps `id` through the values `first`, `first+step`, `first+2*step`, `...`, stopping when the value of `id` passes `last`. `S` executes once for each value; if the sequence of values is empty, `S` never executes. The expressions `first`, `last`, and `step` are evaluated once, before the loop is entered. If `step` is negative, the loop iterates downward.

The case in which `id` is an element of an enumeration is similar. In either case, the semantics are defined precisely by the following rewriting, in which `T` is the type of `id` and in which `i`, `done`, and `delta` stand for variables that do not occur in the `FOR` statement:

        VAR
          i := ORD(first); done := ORD(last); delta := step;
        BEGIN
          IF delta >= 0 THEN
            WHILE i <= done DO
              WITH id = VAL(i, T) DO S END; INC(i, delta)
            END
          ELSE
            WHILE i >= done DO
              WITH id = VAL(i, T) DO S END; INC(i, delta)
            END
          END
        END

If the upper bound of the loop is `LAST(INTEGER)`, it should be rewritten as a `WHILE` loop to avoid overflow.

    Last modified on Wed Apr  3 09:39:06 PST 1996 by heydon
         modified on Mon Apr 18 14:03:17 PDT 1994 by kalsow