Forth83 にのヘッダについて調べた。このヘッダの形式は今でも小さなシステムに使われている。
F83 Header
日本語の「標準 FORTH」(私が持っているのは1986の初版第3刷)に詳しいのだがForth83 は 31 文字までのワードしか扱えない。Fig-Forth と LFA の位置が違う。NFA の h80 は何の意味があるのだろう?gforth では alias-mask となっている。CFA は通常ワード境界(16bit なら 2byte バウンダリ)で、必要に応じてパディングが入る。
■ gforth での実装されている Forth83 の検索プログラム
短いソースなので、そう読むのに苦労はしない(はず)。動きは関数名が表すとおり。(find-samelen)で $1F を andしているところがマスクして(フラグを無視するために)長さを取得しているところ。cell+と@でリンクフィールドを追っている。
TIB
Forth83 も gforth もTIB(Text Input Buffer) を通して入力するシステムになっている。
Code: と Code
gforth の cross 環境ではプリミティブを定義するのに Code: と Code がある。プリミティブの内部はスレデッドではない。前者はインターナルに使われるワードを定義するものに使われている。なのでちゃんとしたヘッダーがない。Code は普通のプリミティブを定義するのに使われているので、ヘッダがある。通常の環境(cross じゃない環境)にも Code というワードはある。
Threaded Code
Threaded Code の理解が進んだ。まず名称。Forth ではIF〜ELSE〜THENでさえ、別々のワードになっている。C 言語などでは if 〜 else 〜 then は連続したコードになるのでThreaded ではない。
ELSEは IF の後にくるだろうという前提の上で作られており、ELSE 単独で突然出てくることはない。が、つじつまが合えば次のような事もかけてしまう。2個目以降の ELSE はもはや何を意味しているかわからない。
ITC(Indirect Threaded Code)
ITC と略されて最初何のことだかわからなかった。これはワードが Primitive と Threaded Code の2種類あることが一因。Primitive の場合は直接そこへジャンプしないといけない。Threaded Code のときは Threaded になっているコードへのアドレスの並びを順序よく実行する。そのための特別なプリミティブがある(docol)。Indirect にするには docol は 8086 の場合は次のようなコードになる。
また next, はアセンブラで次のようになる。
このとき(Indirect なので) w (実は di レジスタ) にアドレスがセーブされている。これを docol はパラメタとして使う。docol を読むと巧妙に w が使われているのがわかる。
これで Threaded なアドレスの列を実行することが出来たとしよう。あとは通常の Primitive も同じ仕組みで実行できれば良い。そこで、Primitive で実行される実際のアドレスの前に1個のアドレスリストを挟めば形式として Threaded Code と同じになる。通常そのアドレスリストはヘッダ内に CFA として書かれている。
絵がないと何を書いているのかさっぱりわからない。こんどスライドで説明できるようにしよう。