Types 2 and 3 provide for the repetitive execution of the statements within the do-group.
|
The generation, g, of a reference is established once at the beginning of the do-group, immediately before the initial value expression (exp1) is evaluated. If the reference generation is changed to h in the do-group, the do-group continues to execute with the reference derived from the generation g. However, any reference to the reference inside the do-group is a reference to generation h. It is an error to free generation g in the do-group.
If a reference is made to a reference after the last iteration is completed, the value of the variable is the value that was out of range of the limit set in the specification. The preceding is true if the following conditions apply to the limit set in the application:
If reference is a program-control data variable, but is not a locator, the BY and TO options cannot be used in specification.
If reference is a program-control variable, but is not a locator or an ordinal, the UPTHRU and DOWNTHRU options cannot be used in specification.
If TO, BY, and REPEAT are all omitted from a specification, there is a single execution of the do-group, with the reference having the value of exp1. If WHILE(exp4) is included, the single execution does not take place unless exp4 is true.
If TO exp2 is omitted from a specification, and if BY exp3 is specified, repetitive execution continues until it is terminated by the WHILE or UNTIL option, or until another statement transfers control out of the do-group.
If BY exp3 is omitted from a specification, and if TO exp2 is specified, exp3 defaults to 1.
If BY 0 is specified, the execution of the do-group continues indefinitely unless it is halted by a WHILE or UNTIL option, or control is transferred to a point outside the do-group.
If UPTHRU is specified, the reference is compared to exp2 after the statements in the loop are executed, but before the reference is updated with the next value it can assume. The loop is executed at least once.
UPTHRU is used primarily when processing ordinals using loops; however, it can also be used for a reference which is an arithmetic or locator control variable. If the reference is not an ordinal, the increment to be added to the reference after each execution of the do-group is assumed to be +1.
If DOWNTHRU is specified, the reference is compared to exp2 after the statements in the loop are executed, but before the reference is updated with the next value it could assume. The loop is executed at least once.
DOWNTHRU is used primarily when processing ordinals using loops; however, it can also be used for a reference which is an arithmetic or locator control variable. If the reference is not an ordinal, the increment to be added to the reference after each execution of the do-group is assumed to be -1.
In Type 3 do-groups, you should not rely on the order in which exp1, exp2 and exp3 are evaluated. Consequently, it is best if none of these expressions invoke functions that set values used in the other expressions.
Control can transfer into a do-group from outside the do-group only if the do-group is delimited by the DO statement in Type 1. Consequently, Type 2 and 3 do-groups cannot contain ENTRY statements. Control can also return to a do-group from a procedure or ON-unit invoked from within that do-group.
The following sections give more information about using Type 2 and Type 3 DO groups. Examples of DO groups begin in Examples of basic repetitions.
If a Type 2 DO specification includes both the WHILE and UNTIL option, the DO statement provides for repetitive execution as defined by the following:
Label: do while (Exp4) until (Exp5) statement-1
·
·
·
statement-n end; Next: statement /* Statement following the do-group */
The above is equivalent to the following expansion:
Label: if (Exp4) then; else go to Next; statement-1
·
·
·
statement-n Label2: if (Exp5) then; else go to Label; Next: statement /* Statement following the do-group */
If the WHILE option is omitted, the IF statement at label Label is replaced by a null statement. Note that if the WHILE option is omitted, statements 1 through n are executed at least once.
If the UNTIL option is omitted, the IF statement at label Label2 in the expansion is replaced by the statement GO TO Label.
The following sequence of events summarizes the effect of executing a do-group with one specification:
do Reference = Exp1 to Exp2 by Exp3;
For a variable that is not a pseudovariable, the action of the do-group definition in the preceding example is equivalent to the following expansion:
E1=Exp1; E2=Exp2; E3=Exp3; V=E1;
The variable V is a compiler-created based variable with the same attributes as the reference. E1, E2, and E3 are compiler-created variables.
If the DO statement contains more than one specification, the second expansion is analogous to the first expansion in every respect. However, the statements in the do-group are not actually duplicated in the program. A succeeding specification is executed only after the preceding specification has been terminated.
When execution of the last specification terminates, control passes to the statement following the do-group.
The TO and BY options let you vary the reference in fixed positive or negative increments. In contrast, the REPEAT option, which is an alternative to the TO and BY options, lets you vary the control variable nonlinearly. The REPEAT option can also be used for nonarithmetic control variables (such as pointer).
If the Type 3 DO specification includes the TO and BY options, the action of the do-group is defined by the following:
Label: do Variable= Exp1 to Exp2 by Exp3 while (Exp4) until(Exp5); statement-1
·
·
·
statement-m Label1: end; Next: statement
The action of the previous do-group definition is equivalent to the following expansion. In this expansion, V is a compiler-created variable with the same attributes as Variable; and E1, E2, and E3 are compiler-created variables:
Label: E1=Exp1; E2=Exp2; E3=Exp3; V=E1; Label2: if (E3>=0)&(V>E2)|(E3<0)&(V<E2) then go to Next; if (Exp4) then; else go to Next; statement-1
·
·
·
statement-m Label1: if (Exp5) then go to Next; Label3: V=V+E3; go to Label2; Next: statement
If the specification includes the REPEAT option, the action of the do-group is defined by the following:
Label: do Variable= Exp1 repeat Exp6 while (Exp4) until(Exp5); statement-1
·
·
·
statement-m Label1: end; Next: statement
The action of the previous do-group definition is equivalent to the following expansion:
Label: E1=Exp1; V=E1; Label2: ; if (Exp4) then; else go to Next; statement-1
·
·
·
statement-m Label1: if (Exp5) then go to Next; Label3: V=Exp6; go to Label2; Next: statement
Additional rules for the sample expansions are as follows:
If the Type 3 DO specification includes the UPTHRU option, the action of the do-group is defined by the following:
Label: do Variable = Exp1 upthru Exp2 while (Exp4) until (Exp5); statement1
·
·
·
statementn Label1: end; Next: statement
The action of the previous do-group is equivalent to the following expansion. In this expansion, V is a compiler-generated variable with the same attributes as Variable; and E1 and E2 are compiler-generated variables:
Label: E1 = Exp1; E2 = Exp2; V = E1; Label2: if (Exp4) then; else go to next; statement1
·
·
·
statementn Label1: if (Exp5) then go to Next; if V >= E2 then go to Next; V = V + 1; go to Label2; Next: statement
If the reference is an ordinal, the statement V = V + 1 is replaced by V = ordinalsucc(V).
If the Type 3 DO specification includes the DOWNTHRU option, the action of the do-group is defined by the following:
Label: do Variable = Exp1 downthru Exp2 while (Exp4) until (Exp5); statement1
·
·
·
statementn Label1: end; Next: statement
The action of the previous do-group is equivalent to the following expansion. In this expansion, V is a compiler-generated variable with the same attributes as Variable; and E1 and E2 are compiler-generated variables:
Label: E1 = Exp1; E2 = Exp2; V = E1; Label2: if (Exp4) then; else go to Next; statement1
·
·
·
statementn Label1: if (Exp5) then go to Next; if V <= E2 then go to Next; V = V - 1; go to Label2; Next: statement
If the reference is an ordinal, the statement V = V - 1 is replaced by V = ordinalpred(V).