Rational Developer for System z
Enterprise PL/I for z/OS, Version 3.8, 言語解説書

タイプ 2 およびタイプ 3

タイプ 2 および 3 では、DO グループ内でステートメントを反復して実行することができます。

構文図を読む構文図をスキップするタイプ 2
 
>>-DO--+-WHILE--(--exp4--)--+-------------------+-+--;---------><
       |                    '-UNTIL--(--exp5--)-' |
       '-UNTIL--(--exp5--)--+-------------------+-'
                            '-WHILE--(--exp4--)-'
 
構文図を読む構文図をスキップするタイプ 3
 
                     .-,-----------------.
                     V                   |
>>-DO--reference--=----| specification |-+---------------------><
 
仕様:
 
|--exp1--+------------------------+--+------------------------------------------+--|
         +-TO--exp2--+----------+-+  +-WHILE--(--exp4--)--+-------------------+-+
         |           '-BY--exp3-' |  |                    '-UNTIL--(--exp5--)-' |
         +-BY--exp3--+----------+-+  '-UNTIL--(--exp5--)--+-------------------+-'
         |           '-TO--exp2-' |                       '-WHILE--(--exp4--)-'
         '-REPEAT--exp6-----------'
 
expn
expression n の省略形です。
WHILE (exp4)
DO グループの実行を反復すると、反復前に exp4 が計算され、 必要に応じてビット・ストリングに変換されます。 結果のビット・ストリングのいずれかのビットが 1 であれば、その DO グループが実行されます。 すべてのビットが 0 であるか、ストリングがヌルであれば、 タイプ 2 の DO グループの実行が終了し、 タイプ 3 の場合はこの WHILE オプションを含む指定に対応する実行だけが終了し、 次の指定がある場合には、それが開始されます。
UNTIL (exp5)
DO グループの実行を反復すると、反復後に exp5 が計算され、 必要に応じてビット・ストリングに変換されます。 結果のビット・ストリングのすべてのビットが 0 であるか、 ストリングがヌルであれば、その DO グループの次の繰り返しが実行されます。 いずれかのビットが 1 であれば、タイプ 2 の場合は DO グループの実行が終了し、 タイプ 3 の場合はこの UNTIL オプションを含む指定に対応する実行だけが終了し、 次の指定がある場合には、それが開始されます。
reference
参照として使用できる疑似変数は、SUBSTR、REAL、IMAG および UNSPEC のみです。 どのデータ・タイプでもかまいません。

参照の世代 g は、DO グループの始まりで、 初期値を表す式 (exp1) が計算される直前に、1 回だけ確立されます。 その DO グループ内で参照の世代が h に変更されても、 DO グループの実行は、世代 g から派生した参照を使用して続行します。ただし、DO グループ内でその参照が参照されると、世代 h が参照されます。 DO グループ内で世代 g を解放しようとすると、エラーになります。

最後の繰り返しの完了後に参照を参照した場合、その参照の値は指定でセットした 境界の範囲外の値になっています。 次の条件がアプリケーションに設定された境界に適合する場合は、 前述の内容が真になります。

参照がプログラム制御データ変数であり、 ロケーターでなければ、BY オプションと TO オプションは、 指定では使用できません。

参照がプログラム制御変数であり、ロケーターまたは序数でなければ、UPTHRU オプションと DOWNTHRU オプションは、指定では使用できません。

exp1
参照の初期値を指定します。

TO、BY、および REPEAT の指定が省略された場合には、 DO グループは 1 回だけ実行され、参照は値として exp1 を持ちます。 WHILE(exp4) を指定した場合は、 exp4 が真でなければ 1 回も実行されません。

TO exp2
exp2 は、その指定に制御権が移動したときに計算され、保管されます。 この保管された値は、参照の終了値を示します。 DO グループの始めにテストされた参照の値が範囲内になければ、ただちに、 指定に関して DO グループ内のステートメントの実行が終了します。 その後、次の指定があれば、その実行が開始されます。

TO exp2 の指定が省略され、BY exp3 が 指定されていると、WHILE オプションまたは UNTIL オプションによって 実行が終了するまで、あるいはほかのステートメントが DO グループの外へ 制御権を移動するまで、実行が繰り返されます。

BY exp3
exp3 は、その指定に制御権が移動したときに計算され、保管されます。 この保管された値は、DO グループの実行が反復されるたびに参照に 加算される増分を示しています。

BY exp3 の指定が省略され、 TO exp2 が指定されていると、exp3 は デフォルトの 1 になります。

BY 0 を指定すると、WHILE または UNTIL オプションによって実行が停止される場合と DO グループの外へ制御が移される場合とを除いて、DO グループの実行は無限に繰り返されます。

UPTHRU exp2
exp2 は、その指定に制御権が移動したときに計算され、保管されます。 この保管された値は、参照の終了値を示します。 DO グループの終わりでテストされた参照の値が所定の範囲内になければ、 ただちに、その指定に関して DO グループ内のステートメントの実行が終了します。 その後、次の指定があれば、その実行が開始されます。

UPTHRU が指定されていると、ループ内のステートメントが 実行されたあと、想定し得る次の値で更新される前に、 参照は exp2 と比較されます。 ループは、少なくとも一度実行されます。

UPTHRU は、主に序数の処理にループが使用されているときに使用されますが、 参照が算術変数やロケーター制御変数である場合に、その参照でも使用されます。 参照が序数を示さない場合には、DO グループの実行が行われるたびに参照に加えられる増分は、+1 と見なされます。

DOWNTHRU exp2
exp2 は、その指定に制御権が移動したときに計算され、保管されます。 この保管された値は、参照の終了値を示します。 DO グループの終わりでテストされた参照の値が所定の範囲内になければ、 ただちに、その指定に関して DO グループ内のステートメントの実行が終了します。 その後、次の指定があれば、その実行が開始されます。

DOWNTHRU が指定されていると、ループ内のステートメントが 実行されたあと、参照が想定し得る次の値で更新される前に、 参照は exp2 と比較されます。 ループは、少なくとも一度実行されます。

DOWNTHRU は、主に序数の処理にループが使用されているときに使用されますが、 参照が算術変数やロケーター制御変数である場合に、その参照でも使用されます。 参照が序数を示さない場合には、DO グループの実行が行われるたびに参照に加えられる増分は、-1 と見なされます。

REPEAT exp6
DO グループの実行が反復されるたびに、exp6 が計算され、 参照に割り当てられます。 WHILE または UNTIL オプションによって実行が停止されるまで、 あるいはほかのステートメントが DO グループの外へ制御権を移動するまで、 実行が繰り返されます。

タイプ 3 の DO グループでは、exp1exp2、および exp3 が計算される順序に依存してはいけません。 したがって、これらの式によって、他の式で使用される値を設定する関数で呼び出さないようにするのが適切と言えます。

DO グループの外から DO グループの中へ制御権を移動することができるのは、 その DO グループがタイプ 1 の DO ステートメントで区切られている場合だけです。 したがって、タイプ 2 とタイプ 3 の DO グループには、ENTRY ステートメントを含むことはできません。 DO グループ内から呼び出したプロシージャーまたは ON ユニットから、 その DO グループへ制御を戻すことはできます。

以降の節では、タイプ 2 およびタイプ 3 の DO グループの 使用について説明します。 DO グループの例は、 基本的な繰り返しの例 ページから記載されています。

タイプ 2 WHILE と UNTIL の使用方法

タイプ 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 ステートメントで 置き換えられます。

タイプ 3 を 1 つの指定で使用する場合

1 つの指定で DO グループを実行した場合の結果を、以下に要約して示します。

  1. 参照を指定し、BY、TO、UPTHRU、または DOWNTHRU の いずれかのオプションも指定した場合は、 exp1 の参照への割り当てに先立って、exp1exp2、および exp3 が計算されます。 次に、初期値が参照に割り当てられます。例えば、次のようになります。
      do Reference = Exp1 to Exp2 by Exp3;

    疑似変数ではない変数の場合、前述の例の DO グループ定義によって取られる 処置は、下記の展開と同等です。

      E1=Exp1;
      E2=Exp2;
      E3=Exp3;
      V=E1;

    変数 V は、参照と同じ属性を持つ、 コンパイラー生成の基底付き変数です。 E1E2、および E3 は コンパイラー生成の変数です。

  2. TO オプションがあると、制御変数の値が、 前に計算された TO オプション内の式 E2 と比較されます。
  3. WHILE オプションを指定した場合は、WHILE オプション内の式が計算されます。 その結果が、 であれば、DO グループから制御が離れます。
  4. DO グループ内のステートメントが実行されます。
  5. UNTIL オプションを指定した場合は、 UNTIL オプション内の式が計算されます。 その結果が、 であれば、DO グループから制御が離れます。
  6. UPTHRU オプションが指定されていると、制御変数の値が、前に計算された UPTHRU オプション内の式と比較されます。
  7. DOWNTHRU オプションが指定されていると、制御変数の値が、前に計算された DOWNTHRU オプション 内の式と比較されます。
  8. 参照がある場合は、以下のようになります。
    1. TO オプションまたは BY オプションが指定されていると、 前に計算された exp3 (E3) が参照に加算されます。
    2. REPEAT オプションが指定されていると、 exp6 が計算されて、参照に割り当てられます。
    3. TO、BY、REPEAT のどのオプションも指定していないときは、 DO グループから制御が離れます。
    4. UPTHRU オプションが指定されており、参照が序数を表していれば、現行値の後続値が 参照に割り当てられます。 参照が序数を表していないと、1 が参照に加算されます。
    5. DOWNTHRU オプションが指定され、参照が序数を表していれば、現行値の先行値が 参照に割り当てられます。 参照が序数を表していなければ、そこから 1 が減算されます。
    6. TO、BY、UPTHRU、DOWNTHRU、および REPEAT のオプションのうち 何も指定されていなければ、DO グループから制御が離れます。
  9. 2 へ進みます。

タイプ 3 を 2 つまたはそれ以上の指定で使用する場合

DO ステートメント内に複数の指定がある場合、 2 番目の指定も最初の指定とあらゆる点で同じように展開されます。 ただし、DO グループ内のステートメントがプログラム内で実際に重複することはありません。 後続の指定が実行されるのは、先行の指定が終了したあとです。

最後の指定の実行が終了すると、 制御はその DO グループのあとのステートメントに移ります。

タイプ 3 を TO、BY、REPEAT を指定して使用する場合

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 と 同じ属性を持ちます。また、E1E2、および 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

例に示した展開では、さらに次のような規則があります。

  1. 前述の展開は、1 つの指定の結果だけを示しています。 DO ステートメント内に複数の指定がある場合は、展開フォーマット内のラベル NEXT が 付いているステートメントが、次の指定の最初のステートメントになります。 2 番目の展開も、最初の展開とあらゆる点で同じように展開されます。 しかし、プログラムでは、statement-1 から m は実際には重複しません。
  2. WHILE 文節を省略したときは、それぞれの展開フォーマット内の statement-1 のすぐ前にある IF ステートメントも省略されます。
  3. UNTIL 文節を省略したときは、それぞれの展開フォーマット内の statement-m のすぐあとにある IF ステートメントも省略されます。

タイプ 3 を UPTHRU を指定して使用する場合

タイプ 3 の DO 指定に UPTHRU オプションが含まれる場合、DO グループの処置は、次のようにして定義されます。

  Label:  do Variable = Exp1 upthru Exp2 while (Exp4) until (Exp5);
statement1

·
·
·
statementn Label1: end; Next: statement

上述の DO グループの処置は、次のように展開されたものと同等です。 この展開において、V はコンパイラー生成変数で、 Variable と同じ属性を持ちます。 また、E1E2 も、コンパイラー生成変数です。

  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 を DOWNTHRU を指定して使用する場合

タイプ 3 の DO 指定に DOWNTHRU オプションが含まれる場合、DO グループの処置は、次のようにして定義されます。

  Label:  do Variable = Exp1 downthru Exp2 while (Exp4) until (Exp5);
statement1

·
·
·
statementn Label1: end; Next: statement

上述の DO グループの処置は、次のように展開されたものと同等です。 この展開において、V はコンパイラー生成変数で、 Variable と同じ属性を持ちます。 また、E1E2 も、コンパイラー生成変数です。

  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) で置き換えられます。


Terms of use | Feedback

This information center is powered by Eclipse technology. (http://www.eclipse.org)