DO Statement using UPTHRU and DOWNTHRU

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.

Examples

UPTHRU arithmetic
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
DOWNTHRU arithmetic
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
UPTHRU ordinal
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