─DO─┬───────────┬─┬─────────────┬─;─┬───────────────┬END─┬──────┬;── └─repetitor─┘ └─conditional─┘ │┌─────────────┐│ └─name─┘ │ ││ └┴─instruction─┴┘ repetitor : ─┬ ─n ame = expri ─┬ ── ── ── ── ┬─ ┬─ ── ── ── ─┬ ─┬ ── ── ── ── ─┬ ─┬ ── ── │ └T O ─e xprt ┘ └B Y ─e xprb ┘ └F OR ─e xprf ┘ │ ├─ ─F OREVER ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ─┤ └─ ─e xprr ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ── ─┘ conditional : ── ─┬ ─W HILE ─e xprw ── ┬─ ── ─ └─ UNTIL ─e xpru ── ┘
DO is used to group instructions together and optionally to execute them repetitively. During repetitive execution, a control variable (name) can be stepped through some range of values.
Syntax Notes:
o
Simple DO Group:
If neither repetitor nor conditional is given, the construct merely groups a number of instructions together. These are executed once. Otherwise, the group of instructions is a repetitive DO loop, and they are executed according to the repetitor phrase, optionally modified by the conditional phrase.
In the following example, the instructions are executed once.
Example:
/* The two instructions between DO and END will both *//* be executed if A has the value 3. */ If a=3 then Do a=a+2 Say 'Smile!' End
Simple Repetitive Loops:
If repetitor is omitted but there is a conditional or the repetitor is FOREVER, the group of instructions will nominally be executed forever, that is, until the condition is satisfied or a REXX instruction is executed that ends the loop (for example, LEAVE).
In the simple form of a repetitive loop, exprr is evaluated immediately (and must result in a nonnegative whole number), and the loop is then executed that many times.
Example:
/* This displays "Hello" five times */ Do 5 say 'Hello' end
Note that, similar to the distinction between a command and an assignment, if the first character of exprr is a symbol and the second is an "=" character, the controlled form of repetitor is expected.
Controlled Repetitive Loops:
The controlled form specifies a control variable, name, which is assigned an initial value (the result of expri, formatted as though 0 had been added). The variable is then stepped (that is, the result of exprb is added at the bottom of the loop) each time the group of instructions is run. The group is run repeatedly while the end condition (determined by the result of exprt) is not met. If exprb is positive or zero, the loop will be terminated when name is greater than exprt. If negative, the loop is terminated when name is less than exprt.
The expri, exprt, and exprb options must result in numbers. They are evaluated once only, before the loop begins and before the control variable is set to its initial value. The default value for exprb is 1. If exprt is omitted, the loop is run indefinitely unless some other condition terminates it.
Example:
Do I=3 to -2 by -1 /* Would display: */ say i /* 3 */ end /* 2 */ /* 1 */ /* 0 */ /* -1 */ /* -2 */
The numbers do not have to be whole numbers.
Example:
X=0.3 /* Would display: */ Do Y=X to X+4 by 0.7 /* 0.3 */ say Y /* 1.0 */ end /* 1.7 */ /* 2.4 */ /* 3.1 */ /* 3.8 */
The control variable can be altered within the loop, and this may affect the iteration of the loop. Altering the value of the control variable is not normally considered good programming practice, though it may be appropriate in certain circumstances.
Note that the end condition is tested at the start of each iteration (and after the control variable is stepped, on the second and subsequent iterations). Therefore, the group of instructions can be skipped entirely if the end condition is met immediately. Note also that the control variable is referred to by name. If, for example, the compound name A.I is used for the control variable, altering I within the loop causes a change in the control variable.
The processing of a controlled loop can be bounded further by a FOR phrase. In this case, exprf must be given and must evaluate to a nonnegative whole number. This acts just like the repetition count in a simple repetitive loop, and sets a limit to the number of iterations around the loop if no other condition terminates it. Similar to the TO and BY expressions, it is evaluated once only-when the DO instruction is first executed and before the control variable is given its initial value. Like the TO condition, the FOR condition is checked at the start of each iteration.
Example:
Do Y=0.3 to 4.3 by 0.7 for 3 /* Would display: */ say Y /* 0.3 */ end /* 1.0 */ /* 1.7 */
In a controlled loop, the name describing the control variable can be specified on the END clause. This name must match name in the DO clause in all respects except case (note that no substitution for compound variables is carried out); a syntax error results if it does not. This enables the nesting of loops to be checked automatically, with minimal overhead.
Example:
Do K=1 to 10 ... ... End k /* Checks that this is the END for K loop */
┴╓: The values taken by the control variable may be affected by the NUMERIC settings, since normal REXX arithmetic rules apply to the computation of stepping the control variable.
Conditional Phrases (WHILE and UNTIL):
Any of the forms of repetitor (none, FOREVER, simple, or controlled) can be followed by a conditional phrase, which may cause termination of the loop. If you specify WHILE or UNTIL, exprw or expru, respectively, is evaluated each time around the loop using the latest values of all variables (and must evaluate to either 0 or 1). The group of instructions is repeatedly processed either while the result is 1 or until the result is 1.
For a WHILE loop, the condition is evaluated at the top of the group of instructions; for an UNTIL loop, the condition is evaluated at the bottom, before the control variable has been stepped.
Example:
Do I=1 to 10 by 2 until i>6 say i end /* Will display: 1, 3, 5, 7 */
┴╓: The processing of repetitive loops can also be modified by using the LEAVE or ITERATE instructions.