石原 博の覚書

電子工作に関する日々の覚書を記載します

Forthの制御構造(BEGIN AGAIN)

2021-04-29 10:47:17 | 日記
Forthの面白さは、BEGIN AGAINやIF ELSE THENなどの制御構造のコンパイルもForthで書かれているところだと思う。
F83の場合、SEEでデコンパイル出来るし、VIEW BEGIN や VIEW IF として、制御用のワードの定義を見ることが出来る。

BEGIN AGAINの例 (無限ループ)
: TEST 0 BEGIN 1 + DUP . AGAIN ;

SEE TEST
: TEST 0 1 + DUP . BRANCH -10 ; ok

→コンパイルすると、BEGIN も AGAIN も消えて単純なBRANCHになっていることがわかる。


制御用のワードBEGINを見てみよう。
VIEW BEGIN すると、KERNEL80.BLK 内の BEGIN の定義を見ることが出来る
1 : BEGIN ?
? 10 : ?
TRUEをスタックに積んで 5 :
なんのことはない。結局TRUEと現在のアドレスをスタックに積んでいるだけ。


AGAINは
10 : AGAIN COMPILE BRANCH ? BRANCHワードを書き込んで、?
11 : ? SWAPしてTRUEとアドレスを交換し、?CONDITION

1 : ?CONDITION (S f -- )
2 NOT ABORT" Conditionals Wrong" ;
スタックトップがTRUEじゃなければ、アボート

6 : スタックトップのアドレスを書き込む

これも結局フラグをチェックして、スタックに積まれていたアドレスに分岐(BRANCH)しているだけなことがわかる。

デコンパイルした結果の下線部分がその結果となっている。
: TEST 0 1 + DUP . BRANCH -10 ; ok
          ^^^^^^^^^^^^
(注意)
 SEEでは分岐先が相対アドレス表記になっているが、実際は絶対アドレスが入っている。
 FIG-ForthやF79では実際にも相対アドレスであったが、F83から絶対アドレスに変わっているみたい


制御構造には、BEGIN ... UNTIL もある。これは条件が成立するまでループであるが、
BEGIN AGAINとほとんど変わらない。
9 : UNTIL COMPILE ?BRANCH ?
AGAINのBRANCHが、?BRANCHにかわっただけ。 (?BRANCHはスタックトップが0なら分岐というワード)