無限ループは非常に単純です:
: endless ( -- )
0 begin
dup . 1+
again ;
endless
(Gforth の場合、) Ctrl-C を押してこのループを終了します。 begin は実行時に何も行わず、
again は begin にジャンプします。
任意の場所に 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