タイプ 2 および 3 では、DO グループ内でステートメントを反復して実行することができます。
|
参照の世代 g は、DO グループの始まりで、 初期値を表す式 (exp1) が計算される直前に、1 回だけ確立されます。 その DO グループ内で参照の世代が h に変更されても、 DO グループの実行は、世代 g から派生した参照を使用して続行します。ただし、DO グループ内でその参照が参照されると、世代 h が参照されます。 DO グループ内で世代 g を解放しようとすると、エラーになります。
最後の繰り返しの完了後に参照を参照した場合、その参照の値は指定でセットした 境界の範囲外の値になっています。 次の条件がアプリケーションに設定された境界に適合する場合は、 前述の内容が真になります。
参照がプログラム制御データ変数であり、 ロケーターでなければ、BY オプションと TO オプションは、 指定では使用できません。
参照がプログラム制御変数であり、ロケーターまたは序数でなければ、UPTHRU オプションと DOWNTHRU オプションは、指定では使用できません。
TO、BY、および REPEAT の指定が省略された場合には、 DO グループは 1 回だけ実行され、参照は値として exp1 を持ちます。 WHILE(exp4) を指定した場合は、 exp4 が真でなければ 1 回も実行されません。
TO exp2 の指定が省略され、BY exp3 が 指定されていると、WHILE オプションまたは UNTIL オプションによって 実行が終了するまで、あるいはほかのステートメントが DO グループの外へ 制御権を移動するまで、実行が繰り返されます。
BY exp3 の指定が省略され、 TO exp2 が指定されていると、exp3 は デフォルトの 1 になります。
BY 0 を指定すると、WHILE または UNTIL オプションによって実行が停止される場合と DO グループの外へ制御が移される場合とを除いて、DO グループの実行は無限に繰り返されます。
UPTHRU が指定されていると、ループ内のステートメントが 実行されたあと、想定し得る次の値で更新される前に、 参照は exp2 と比較されます。 ループは、少なくとも一度実行されます。
UPTHRU は、主に序数の処理にループが使用されているときに使用されますが、 参照が算術変数やロケーター制御変数である場合に、その参照でも使用されます。 参照が序数を示さない場合には、DO グループの実行が行われるたびに参照に加えられる増分は、+1 と見なされます。
DOWNTHRU が指定されていると、ループ内のステートメントが 実行されたあと、参照が想定し得る次の値で更新される前に、 参照は exp2 と比較されます。 ループは、少なくとも一度実行されます。
DOWNTHRU は、主に序数の処理にループが使用されているときに使用されますが、 参照が算術変数やロケーター制御変数である場合に、その参照でも使用されます。 参照が序数を示さない場合には、DO グループの実行が行われるたびに参照に加えられる増分は、-1 と見なされます。
タイプ 3 の DO グループでは、exp1、exp2、および exp3 が計算される順序に依存してはいけません。 したがって、これらの式によって、他の式で使用される値を設定する関数で呼び出さないようにするのが適切と言えます。
DO グループの外から DO グループの中へ制御権を移動することができるのは、 その DO グループがタイプ 1 の DO ステートメントで区切られている場合だけです。 したがって、タイプ 2 とタイプ 3 の DO グループには、ENTRY ステートメントを含むことはできません。 DO グループ内から呼び出したプロシージャーまたは ON ユニットから、 その DO グループへ制御を戻すことはできます。
以降の節では、タイプ 2 およびタイプ 3 の DO グループの 使用について説明します。 DO グループの例は、 基本的な繰り返しの例 ページから記載されています。
タイプ 2 の DO の指定で、WHILE オプションと UNTIL オプションの 両方を使用すると、その DO ステートメントによって、 次に示すように実行が反復されます。
Label: do while (Exp4) until (Exp5) statement-1
·
·
·
statement-n end; Next: statement /* Statement following the do-group */
上記のものは、次のように展開されたものと同等です。
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 */
WHILE オプションが省略されると、 ラベル Label の IF ステートメントは、 ヌル・ステートメントで置き換えられます。 WHILE オプションが省略されると、 ステートメント 1 からステートメント n までが 少なくとも一度は実行されます。
UNTIL オプションを省略したときは、 展開フォーマット内のラベル Label2 の IF ステートメントが GO TO Label ステートメントで 置き換えられます。
1 つの指定で DO グループを実行した場合の結果を、以下に要約して示します。
do Reference = Exp1 to Exp2 by Exp3;
疑似変数ではない変数の場合、前述の例の DO グループ定義によって取られる 処置は、下記の展開と同等です。
E1=Exp1; E2=Exp2; E3=Exp3; V=E1;
変数 V は、参照と同じ属性を持つ、 コンパイラー生成の基底付き変数です。 E1、E2、および E3 は コンパイラー生成の変数です。
DO ステートメント内に複数の指定がある場合、 2 番目の指定も最初の指定とあらゆる点で同じように展開されます。 ただし、DO グループ内のステートメントがプログラム内で実際に重複することはありません。 後続の指定が実行されるのは、先行の指定が終了したあとです。
最後の指定の実行が終了すると、 制御はその DO グループのあとのステートメントに移ります。
TO オプションや BY オプションを使用すれば、 参照を一定の増分 (正または負) で変化させることができます。 一方、TO オプションや BY オプションの代わりに REPEAT オプションを使用すれば、制御変数を非線形に変化させることができます。 REPEAT オプションは、算術タイプ以外の制御変数 (ポインターなど) にも使用することができます。
タイプ 3 の DO 指定で TO オプションと BY オプションの両方を使用すると、 その DO グループの処置は次のように定義されます。
Label: do Variable= Exp1 to Exp2 by Exp3 while (Exp4) until(Exp5); statement-1
·
·
·
statement-m Label1: end; Next: statement
前述の DO グループの定義によって取られる処置は、 次のように展開されたものとまったく同等です。 この展開において、V はコンパイラー生成変数で、Variable と 同じ属性を持ちます。また、E1、E2、および E3 も、 コンパイラー生成変数です。
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
この指定で REPEAT オプションを使用したときは、DO グループの処置は 次のように定義されます。
Label: do Variable= Exp1 repeat Exp6 while (Exp4) until(Exp5); statement-1
·
·
·
statement-m Label1: end; Next: statement
前述の DO グループの定義によって取られる処置は、 次のように展開されたものとまったく同等です。
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
例に示した展開では、さらに次のような規則があります。
タイプ 3 の DO 指定に UPTHRU オプションが含まれる場合、DO グループの処置は、次のようにして定義されます。
Label: do Variable = Exp1 upthru Exp2 while (Exp4) until (Exp5); statement1
·
·
·
statementn Label1: end; Next: statement
上述の DO グループの処置は、次のように展開されたものと同等です。 この展開において、V はコンパイラー生成変数で、 Variable と同じ属性を持ちます。 また、E1 と E2 も、コンパイラー生成変数です。
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
参照が序数を表していれば、ステートメント V = V + 1 は、V = ordinalsucc(V) で置き換えられます。
タイプ 3 の DO 指定に DOWNTHRU オプションが含まれる場合、DO グループの処置は、次のようにして定義されます。
Label: do Variable = Exp1 downthru Exp2 while (Exp4) until (Exp5); statement1
·
·
·
statementn Label1: end; Next: statement
上述の DO グループの処置は、次のように展開されたものと同等です。 この展開において、V はコンパイラー生成変数で、 Variable と同じ属性を持ちます。 また、E1 と E2 も、コンパイラー生成変数です。
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
参照が序数を表していれば、ステートメント V = V - 1 は、V = ordinalpred(V) で置き換えられます。