Skip to main content

Software > Software Development > IBM REXX Family >

NetRexx

Technical detail

Loop instruction


   loop [label name] [protect termp] [repetitor] [conditional];


instructionlist

[catch [vare =] exception;

instructionlist]...

[finally[;]

instructionlist]

end [name];

where repetitor is one of:

  varc = expri [to exprt] [by exprb] [for exprf]
varo over termo
for exprr
forever

and conditional is either of:

  while exprw
until expru

and name is a non-numeric symbol
and instructionlist is zero or more instructions and expri, exprt, exprb, exprf, exprr, exprw, and expru are expressions.

The loop instruction is used to group instructions together and execute them repetitively. The loop may optionally be given a label, and may protect an object while the instructions in the loop are executed; exceptional conditions can be handled with catch and finally.

loop is the most complicated of the NetRexx keyword instructions. It can be used as a simple indefinite loop, a predetermined repetitive loop, as a loop with a bounding condition that is recalculated on each iteration, or as a loop that steps over the contents of a collection of values.

Syntax notes:

  • The label and protect phrases may be in any order. They must precede any repetitor or conditional.
  • The first instructionlist is known as the body of the loop.
  • The to, by, and for phrases in the first form of repetitor may be in any order, if used, and will be evaluated in the order they are written.
  • Any instruction allowed in a method is allowed in an instructionlist, including assignments, method call instructions, and keyword instructions (including any of the more complex constructions such as if, do, select, or the loop instruction itself).
  • If for or forever start the repetitor and are followed by an '=' character, they are taken as control variable names, not keywords (as for assignment instructions).
  • The expressions expri, exprt, exprb, or exprf will be ended by any of the keywords to, by, for, while, or until (unless the word is the name of a variable).
  • The expressions exprw or expru will be ended by either of the keywords while or until (unless the word is the name of a variable).

Indefinite loops

If neither repetitor nor conditional are present, or the repetitor is the keyword forever, then the loop is an indefinite loop. It will be ended only when some instruction in the first instructionlist causes control to leave the loop.

Example:

  /* This displays "Go caving!" at least once */
loop forever
say 'Go caving!'
if ask='' then leave
end

Bounded loops

If a repetitor (other than forever) or conditional is given, the first instructionlist forms a bounded loop, and the instruction list is executed according to any repetitor phrase, optionally modified by a conditional phrase.

Simple bounded loops

When the repetitor starts with the keyword for, the expression exprr is evaluated immediately (with 0 added, to effect any rounding) to give a repetition count, which must be a whole number that is zero or positive. The loop is then executed that many times, unless it is terminated by some other condition.

Example:

  /* This displays "Hello" five times */
loop for 5
say 'Hello'
end
Controlled bounded loops

A controlled loop begins with an assignment, which can be identified by the '=' that follows the name of a control variable, varc. The control variable is assigned an initial value (the result of expri, formatted as though 0 had been added) before the first execution of the instruction list. The control variable is then stepped (by adding the result of exprb) before the second and subsequent times that the instruction list is executed.

The name of the control variable, varc, must be a non-numeric symbol that names an existing or new variable in the current method or a property in the current class (that is, it cannot be element of an array, the property of a superclass, or a more complex term). It is further restricted in that it must not already be used as the name of a control variable or label in a loop (or do or select construct) that encloses the new loop.

The instruction list in the body of the loop is executed repeatedly while the end condition (determined by the result of exprt) is not met. If exprb is positive or zero, then the loop will be terminated when varc is greater than the result of exprt. If negative, then the loop will be terminated when varc is less than the result of exprt.

The expressions exprt and exprb must result in numbers. They are evaluated once only (with 0 added, to effect any rounding), in the order they appear in the instruction, and before the loop begins and before expri (which must also result in a number) is evaluated and the control variable is set to its initial value.

The default value for exprb is 1. If no exprt is given then the loop will execute indefinitely unless it is terminated by some other condition.

Example:

  loop i=3 to -2 by -1
say i
end
/* Would display: 3, 2, 1, 0, -1, -2 */
Note that the numbers do not have to be whole numbers:

Example:

  x=0.3
loop y=x to x+4 by 0.7
say y
end
/* Would display: 0.3, 1.0, 1.7, 2.4, 3.1, 3.8 */
The control variable may be altered within the loop, and this may affect the iteration of the loop. Altering the value of the control variable in this way is normally considered to be suspect 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). It is therefore possible for the body of the loop to be skipped entirely if the end condition is met immediately.

The execution of a controlled loop may further be bounded by a for phrase. In this case, exprf must be given and must evaluate to a non-negative whole number. This acts just like the repetition count in a simple bounded loop, and sets a limit to the number of iterations around the loop if it is not terminated by some other condition.

exprf is evaluated along with the expressions exprt and exprb. That is, it is evaluated once only (with 0 added), when the loop instruction is first executed and before the control variable is given its initial value; the three expressions are evaluated in the order in which they appear. Like the to condition, the for count is checked at the start of each iteration, as shown in the programmer's model.

Example:

  loop y=0.3 to 4.3 by 0.7 for 3
say y
end
/* Would display: 0.3, 1.0, 1.7 */
In a controlled loop, the symbol that describes the control variable may be specified on the end clause (unless a label is specified, see below). NetRexx will then check that this symbol exactly matches the varc of the control variable in the loop clause (in all respects except case). If the symbol does not match, then the program is in error -- this enables the nesting of loops to be checked automatically.

Example:

  loop k=1 to 10
...
...
end k /* Checks this is the END for K loop */

Note: The values taken by the control variable may be affected by the numeric settings, since normal NetRexx arithmetic rules apply to the computation of stepping the control variable.

Over loops

When the second token of the repetitor is the keyword over, the control variable, varo, is used to work through the sub-values in the collection of indexed strings identified by termo. In this case, the loop instruction takes a 'snapshot' of the indexes that exist in the collection at the start of the loop, and then for each iteration of the loop the control variable is set to the next available index from the snapshot.

The number of iterations of the loop will be the number of indexes in the collection, unless the loop is terminated by some other condition.

Example:

  mycoll=''
mycoll['Tom']=1
mycoll['Dick']=2
mycoll['Harry']=3
loop name over mycoll
say mycoll[name]
end
/* might display: 3, 1, 2 */
Notes:
  1. The order in which the values are returned is undefined; all that is known is that all indexes available when the loop started will be recorded and assigned to varo in turn as the loop iterates.
  2. The same restrictions apply to varo as apply to varc, the control variable for controlled loops (see above).
  3. Similarly, the symbol varo may be used as a name for the loop and be specified on the end clause (unless a label is specified, see below).
In the reference implementation, the over form of repetitor may also be used to step though the contents of any object that is of a type that is a subclass of java.util.Dictionary, such as an object of type java.util.Hashtable. In this case, termo specifies the dictionary, and a snapshot (enumeration) of the keys to the Dictionary is taken at the start of the loop. Each iteration of the loop then assigns a new key to the control variable varo which must be (or will be given, if it is new) the type java.lang.Object.
Conditional phrases

Any of the forms of loop syntax can be followed by a conditional phrase which may cause termination of the loop.

If while is specified, exprw is evaluated, using the latest values of all variables in the expression, before the instruction list is executed on every iteration, and after the control variable (if any) is stepped. The expression must evaluate to either 0 or 1, and the instruction list will be repeatedly executed while the result is 1 (that is, the loop ends if the expression evaluates to 0).

Example:

  loop i=1 to 10 by 2 while i<6
say i
end
/* Would display: 1, 3, 5 */
If until is specified, expru is evaluated, using the latest values of all variables in the expression, on the second and subsequent iterations, and before the control variable (if any) is stepped.[1] The expression must evaluate to either 0 or 1, and the instruction list will be repeatedly executed until the result is 1 (that is, the loop ends if the expression evaluates to 1).

Example:

  loop i=1 to 10 by 2 until i>6
say i
end
/* Would display: 1, 3, 5, 7 */

Note that the execution of loops may also be modified by using the iterate or leave instructions.

Label phrase

The label phrase may used to specify a name for the loop. The name can then optionally be used on

  • a leave instruction, to specify the name of the loop to leave
  • an iterate instruction, to specify the name of the loop to be iterated
  • the end clause of the loop, to confirm the identity of the loop that is being ended, for additional checking.

Example:

  loop label pooks i=1 to 10
loop label hill while j<3
...
if a=b then leave pooks
...
end hill
end pooks

In this example, the leave instruction leaves both loops.

If a label is specified using the label keyword, it overrides any name derived from the control variable name (if any). That is, the variable name cannot be used to refer to the loop if a label is specified.

Protect phrase

The protect phrase may used to specify a term, termp, that evaluates to a value that is not just a type and is not of a primitive type; while the loop construct is being executed, the value (object) is protected -- that is, all the instructions in the loop construct have exclusive access to the object.

Example:

  loop protect myobject while a<b
...
end

Both label and protect may be specified, in any order, if required.

Exceptions in loops

Exceptions that are raised by the instructions within a loop construct may be caught using one or more catch clauses that name the exception that they will catch. When an exception is caught, the exception object that holds the details of the exception may optionally be assigned to a variable, vare.

Similarly, a finally clause may be used to introduce instructions that will always be executed when the loop ends, even if an exception is raised (whether caught or not).

The Exceptions section has details and examples of catch and finally.

Programmer's model -- how a typical loop is executed

This model forms part of the definition of the loop instruction.

For the following loop:

  loop varc = expri to exprt by exprb while exprw
...
instruction list
...
end

NetRexx will execute the following:

     $tempt=exprt+0   /* ($var
iables are internal and   */
$tempb=exprb+0 /* are not accessible.) */
varc=expri+0
Transfer control to the point identified as $start:
$loop:
/* An UNTIL expression would be tested here, with: */
/* if expru then leave */
varc=varc + $tempb
$start:
if varc > $tempt then leave /* leave quits a loop */
/* A FOR count would be checked here */
if \exprw then leave
...
instruction list
...
Transfer control to the point identified as $loop:

Notes:

  1. This example is for exprb >= 0. For a negative exprb, the test at the start point of the loop would use '<' rather than '>'.
  2. The upwards transfer of control takes place at the end of the body of the loop, immediately before the end clause (or any catch or finally clause). The end clause is only reached when the loop is finally completed.

Footnotes:

[1]  Thus, it appears that the until condition is tested after the instruction list is executed on each iteration. However, it is the loop clause that carries out the evaluation.

 

 

 

PreviousTable of contents Next
>
We're here to help
Easy ways to get the answers you need.
E-mail us

or call us at
877-426-3774
Priority code:
104CBW67