以降の各項では、Forth プログラム内の実行フローの制御用のワードについて説明します。
if、then、else の各コマンドは組み合わされて単純な制御構造を作ります。
表 4-21に条件付き実行フロー制御用のコマンドを示します。
表 4-21 if...else...then コマンド
コマンド |
スタックダイアグラム |
説明 |
---|---|---|
if |
( flag -- ) |
flag が true の場合、このコマンドの後のコードを実行します。 |
else |
( -- ) |
if が false の場合、このコマンドの後のコードを実行します。 |
then |
( -- ) |
if...else...then を終了します。 |
これらのコマンドの書式は次のとおりです。
flag if (true の場合これを実行) else (false の場合これを実行) then (通常どおりに実行を継続) |
または
flag if (true の場合これを実行) then (通常どおりに実行を継続) |
if コマンドはスタックからフラグを 1 つ「消費」します。そのフラグが true (ゼロ以外) であれば、if の後のコマンドが実行されます。true でなければ、(存在する場合) else の後のコマンドが実行されます。
ok : testit ( n -- ) ] 5 > if ." good enough " ] else ." too small " ] then ] ." Done. " ; ok ok 8 testit good enough Done. ok 2 testit too small Done. ok |
] プロンプトは、それが現れる間は、新しいコロン定義の作成の途中であることをユーザーに示します。このプロンプトはセミコロンを入力して定義を終了すると ok に戻ります。
高水準の case コマンドであり、複数の候補のなかから代替実行フローを選択するために用意されています。このコマンドの方が、深く入れ子になった ifthen コマンドよりも読みやすいという利点があります。
表 4-22に条件付き case コマンドを示します。
表 4-22 case文コマンド
case コマンドの使用例を示します。
ok : testit ( testvalue -- ) ] case 0 of ." It was zero " endof ] 1 of ." It was one " endof ] ff of ." Correct " endof ] -2 of ." It was minus-two " endof ] ( default ) ." It was this value: " dup . ] endcase ." All done." ; ok ok 1 testit It was one All done. ok ff testit Correct All done. ok 4 testit It was this value: 4 All done. ok |
(省略可能な) default 句はまだスタックにあるテスト値を使用できますが、その値を削除してはなりません ( . でなく dup .を使用してください)。 of 句が正常に実行されれば、テスト値はスタックから自動的に削除されます。
begin ループは、特定の条件が満たされるまで、同じコマンドの実行を繰り返します。そのようなループのことを条件付きループといいます。
表 4-23に条件付きループの実行制御用のコマンドを示します。
表 4-23 begin(条件付き) ループコマンド
次に 2 つの一般的な形式を示します。
begin any commands... flag until |
および
begin any commands... flag while more commands repeat |
上記の両方の場合とも、所定のフラグ値によってループが終了させられるまで、ループ内のコマンドが繰り返し実行されます。ループが終了すると、通常、実行はループを閉じているワード (until または repeat) の後のコマンドに継続されます。
beginuntil の場合は、until がスタックの一番上からフラグを削除してそれを調べます。フラグが false の場合は、実行は beginのすぐ後に引き継がれて、ループが繰り返されます。フラグの trueの場合は、実行はループから抜け出ます。
beginwhilerepeat の場合は、while がスタックの一番上からフラグを削除して調べます。フラグが true の場合は、whileのすぐ後のコマンドが実行されてループが繰り返されます。repeatコマンドは制御を自動的に begin に戻してループを継続させます。while が現れたときにフラグが false であった場合は、実行はただちにループから抜け出し、制御がループを閉じている repeat の後の最初のコマンドに移ります。
これらのループのいずれについても、「true ならば通り過ぎる」と覚えると忘れないでしょう。
次に簡単な例を示します。
ok begin 4000 c@ . key? until (任意のキーが押されるまで繰り返す) 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 ok |
この例では、ループはまずメモリー位置 4000 から 1 バイトを取り出して表示します。次に、key? コマンドが呼び出され、これが、ユーザーがそれまでにどれかのキーを押していれば true をスタックに残し、そうでない場合は false を残します。このフラグはuntil によって「消費」され、その値が false であった場合は、ループが繰り返されます。キーを押せば、次に呼び出されたとき、key? は true を返し、したがってループは終了します。
Forth の多くのバージョンとは異なり、ユーザーインタフェースの場合は、ループや条件付き制御構造を対話的に使用できます。つまり、まず最初に定義を作成する必要がありません。
do ループ (カウント付きループとも呼ばれます) は、ループの繰り返し回数があらかじめ計算できるときに使用します。do ループは、通常、指定した終了値に達する直前に終了します。
表 4-24に カウント付きループの実行制御用コマンドを示します。
表 4-24 do (カウント付き)ループコマンド
次の画面で、ループの使用方法をいくつか示します。
表 4-25に、前記以外のプログラム実行制御用のコマンドについて説明します。
表 4-25 プログラム実行制御コマンド
abort はプログラムの実行を即時に終了させ、制御をキーボードに返します。abort" は 2 点を除いて abort と同じです。第 1 点は、フラグが true の場合にスタックからフラグを削除し、その後は何もしないで強制終了させることです。もう 1 点は、強制終了が行われたとき、なんらかのメッセージを表示することです。
eval は (アドレスと長さにより指定された) 文字列をスタックから取り出します。次に、キーボードから入力される場合と同様に、その文字列の文字が解釈されます。Forth のテキストファイルをメモリーに読み込んでいる (第 5 章「プログラムの読み込みと実行」を参照) 場合は、eval を使用してそのファイル内の定義をコンパイルできます。