dcl j fixed bin (15); do j = 1 to 3; put skip list (j); end; put skip list (j); put skip list ('-----------'); do j = 1 upthru 3; put skip list (j); end; put skip list (j);
Prints:
1 2 3 4 ----------- 1 2 3 3
dcl j fixed bin (31); do j = 3 to 1 by -1; put skip list (j); end; put skip list (j); put skip list ('-----------'); do j = 3 downthru 1; put skip list (j); end; put skip list (j);
Prints:
3 2 1 0 ----------- 3 2 1 1
define ordinal Subjects (Arithmetic, /* 0, starting value is zero when VALUE not specified */ Literature, /* 1 */ Science, /* 2 */ History); /* 3 */ dcl x ordinal Subjects; do x = first(:Subjects:) upthru last(:Subjects:); put skip list (ordinalname(x)); end; put skip list(‘After loop: ’|| ordinalname(x));
Prints:
MATHEMATICS LITERATURE SCIENCE HISTORY After loop: HISTORY
Description
When the control variable is an arithmetic type, the implied BY value is always 1 (increment) for UPTHRU and -1 (decrement) for DOWNTHRU. When the control variable is an ORDINAL type, the next value is its ordinal successor for UPTHRU, and its ordinal predecessor for DOWNTHRU. For details, see the ORDINALSUCC and ORIDINALPRED topics respectively.
For both UPTHRU and DOWNTHRU, the control variable is always compared to the finish value after all the statements in the loop are executed but before the control variable is updated to its next possible value. This ensures that the assigned value for the control variable is never outside of the start/finish range.
This is particularly useful with ordinal types, which have neither a successor value (UPTHRU) nor a predecessor value (DOWNTHRU) for the ordinal control variable. For arithmetic types, UPTHRU/DOWNTHRU can prevent a possible control variable overflow, e.g., where a fixed binary(15) control variable exceeds 32767 at the end of a loop causing an overflow resulting in a possible infinite loop.