テキスト・インタープリター(text interpreter)は、 現在の入力デバイスからの入力を処理する無限ループです。 インタープリターの実装上でコンパイルされた Forth コードを実行する内部インタープリター(inner interpreter)(see Engine)とは対照的に、 これは外部インタープリター(outer interpreter)とも呼ばれます24。
テキスト・インタープリターは、 インタープリター状態(interpret state) と コンパイル状態(compile
state)の 2 つの状態のいずれかで動作します。 現在の状態は、 それにふさわしい名前の変数である state
によって定義されます。
このセクションでは、 テキスト・インタープリターがインタープリター状態にあるときに、 ユーザー入力デバイス(キーボード)からの入力処理についてどのように振る舞うかについて説明することから始めます。 これは Forth システムが動き始めた時のモードです。
テキスト・インタープリターは、 入力バッファー(input buffer)25と呼ばれるメモリー領域で動作します。 この領域には、 RET キーを押したときにキーボードからの入力が保存され、 入力バッファーの先頭から開始して、 先頭の空白文字達(デリミタ(delimiters)と呼ばれる)をスキップし、 空白文字、 またはバッファーの終わりに達するまで文字列(空白以外の文字のシーケンス)をパースします。 文字列をパースした後、 以下の2つの試行を行います:
上記両方の試行が失敗した場合、 テキスト・インタープリターは入力バッファーの残りを破棄し、 そして、 エラー・メッセージを発行して、そして、
さらなる入力を待ちます。 いずれかの試行が成功すると、 テキスト・インタープリターは入力バッファー全体が処理されるまでパース処理を繰り返し、
全体が処理された時点でステータス・メッセージ “ ok
” を出力し、 そして、 さらなる入力を待ちます。
テキスト・インタープリターは、 >IN
(“to-in”(トゥーイン)と発音します)と呼ばれる変数を更新することにより、
入力バッファー内の位置を追跡します。 >IN
の値は 0 で始まり、 入力バッファーの先頭からのオフセットが 0 であることを示します。
オフセット >IN @
から入力バッファーの末尾までの領域は、 パース領域(parse
area)と呼ばれます26。 以下の例は、
テキスト・インタープリターが入力バッファーをパースする際に >IN
がどのように変化するかを示しています:
: remaining source >in @ /string cr ." ->" type ." <-" ; immediate 1 2 3 remaining + remaining . : foo 1 2 3 remaining swap remaining ;
これらの結果はそれぞれ以下のようになります:
->+ remaining .<- ->.<-5 ok ->swap remaining ;-< ->;<- ok
>IN
の値は、 テキスト・インタープリターによって実行される入力バッファー内のワードによって変更することもできます。 これは、
ワードがテキスト・インタプリタをだまして、 入力バッファーの一節をスキップしたり27、 一節を 2
回パースしたりすることができることを意味します。 例:
: lat ." <<foo>>" ; : flat ." <<bar>>" >IN DUP @ 3 - SWAP ! ;
flat
が実行されると、 以下の出力が生成されます28(訳注:ユーザーが flat と打ち込と、 入力バッファーには flat があり、 ワード flat
の実行が初まったときは >IN は flatの t の次を指している。 そこから 3 戻ると >IN が 指すのは flat の l で、
そこからテキスト・インタープリターがパースを再開すると、 テキスト・インタープリターに見えるのは lat である。 よって lat が実行されて
<<foo>> が出力される):
<<bar>><<foo>>
この手法を使用すると、 ワードのパースにおける相互運用性の問題(interoperability problems)の一部を回避できます。 もちろん、 ワードのパースは可能な限り避けた方が良いです。
テキスト・インタープリターの振る舞いに関する 2 つの重要な注意事項:
テキスト・インタープリターがコンパイル状態にある場合、 その振る舞いは以下のように変化します:
state
が変更され、 テキスト・インタープリターはインタプリタ状態に戻ります。
ok
” ではなく “ compiled
” を出力します。
テキスト・インタープリターがキーボード以外の入力デバイスを使用している場合、 その振る舞いは以下のように変化します:
ok
” や “ compiled
” メッセージは出力されません。
これについて詳しくは、 Input Sources をご覧ください。
>in
( – addr ) core “to-in”
uvar
変数 – a-addr は、 入力バッファーの先頭からパース領域の先頭までの char
オフセットを格納するセルへのアドレスです。
source
( – addr u ) core “source”
現在の入力バッファーのアドレス addr と長さ u を返します
tib
( – addr ) core-ext-obsolescent “t-i-b”
#tib
( – addr ) core-ext-obsolescent “number-t-i-b”
uvar
変数 – a-addr は、 端末の入力バッファー内の文字数を含むセルのアドレスです。
時代遅れ(OBSOLESCENT): source
はこのワードの機能を置き換えます。
interpret
( ... – ... ) gforth-0.2 “interpret”
このセクションは Introducing the Text Interpreter の拡大バージョンです
テキスト・インタープリターがキーボードからの入力を処理している時、
このメモリー領域はターミナル入力バッファー(terminal input buffer (TIB))と呼ばれ、 (既に廃止されていますが)
ワード TIB
および ワード #TIB
によってアドレス指定されます
言い換えると、 テキスト・インタープリターは、 パース領域が空になるまで、 パース領域からの文字列をパースすることによって、 入力バッファーの内容を処理します
これがワードのパースの仕組みです
研究課題: 3
を 4
に置き換えたらどうなるでしょうか?