Next: , Previous: , Up: Forth Tutorial   [Contents][Index]


3.18 General Loops

無限ループは非常に単純です:

: endless ( -- )
  0 begin
    dup . 1+
  again ;
endless

(Gforth の場合、) Ctrl-C を押してこのループを終了します。 begin は実行時に何も行わず、 againbegin にジャンプします。

任意の場所に 1 つの出口があるループは以下のようになります:

: log2 ( +n1 -- n2 )
\ logarithmus dualis of n1>0, rounded down to the next integer
  assert( dup 0> )
  2/ 0 begin
    over 0> while
      1+ swap 2/ swap
  repeat
  nip ;
7 log2 .
8 log2 .

実行時には while はフラグを1つ消費します。 フラグが 0 の場合、 repeat の後ろへ飛んで実行が継続されます。 フラグがゼロ以外の場合、 実行は while の後ろから継続されます。 Repeat は、 again と全く同じように、 begin に戻ります。

Forth には、 1+ など、多数の 組み合わせ/省略形 があります。 しかし、 2/ は 組み合わせ/省略形 ではありません。 これは引数を 1 ビット右にシフトし、 Gforth の (Gforth 0.7 以降の) / と同様、 常に負の無限大方向に向かって小数点以下を丸める除算(フロア除算)と見なされますが、 他の多くの Forth システムの / とは異なります。

-5 2 / . \ -2 or -3
-5 2/ .  \ -3

assert( は標準Forthのワードではありませんが、 Gforth 以外のシステムでも compat/assert.fs を含めることで取得できます。 それが何をするかは、 以下のように試してみることで確認できます。

0 log2 .

以下は、 最後に出口があるループです:

: log2 ( +n1 -- n2 )
\ logarithmus dualis of n1>0, rounded down to the next integer
  assert( dup 0 > )
  -1 begin
    1+ swap 2/ swap
    over 0 <=
  until
  nip ;

Until はフラグを消費します。 フラグがゼロの場合は begin から実行が継続され、 それ以外の場合は until の後から実行が継続されます。

研究課題(assignment): 最大公約数を計算する定義を書いてみましょう。

こちらも参照ください: Simple Loops