Gforth を使用すると、 複合ワード(combined words)、 つまりインタープリター機能(interpretation semantics)とコンパイル機能(compilation semantics)を任意に組み合わせたワードを定義できます。
interpret/compile:
( interp-xt comp-xt "name" – ) gforth-0.2 “interpret/compile:”
この機能は、 TO
と S"
を実装するために導入されました。 このようなワードは、
たとえ小さなかわいいものであっても定義しないことをお勧めします。 なぜなら、 ワードによっては、
いくつかの文脈でワードの両方の部分を理解するのが困難になるからです。 たとえば、 あなたがコンパイル部分の実行トークンを取得したいとすると、 代わりに、
2つのワードを定義します。 1つはインタープリター機能部分を具体化するもで、 もう一つはコンパイル機能部分を具体化するものです。 それら完成したら、
あなたのユーザーの便宜のために interpret/compile:
を使用して、 それらを組み合わせた複合ワード(combined
word)を定義できます。
この機能を使用して、 ワードのデフォルトのコンパイル機能(compilation semantics)の最適化実装を提供してみるとしましょう。 たとえば、 以下のように定義します:
:noname foo bar ; :noname POSTPONE foo POSTPONE bar ; interpret/compile: opti-foobar
上記は以下の最適化バージョンです:
: foobar foo bar ;
残念ながら、 これは [compile]
では正しく動きません。 なぜなら、 [compile]
では、 すべての
interpret/compile:
ワードのコンパイル機能がデフォルトでは無いと想定しているためです。 つまり、
[compile] opti-foobar
はコンパイル機能をコンパイルしますが、 [compile] foobar
はインタープリター機能をコンパイルします。
state-smart ワードを使用して、interpret/compile:
によって提供される機能をエミュレートしようとする人もいます(実行途中に STATE
をチェックする場合、 ワードは state-smart
になります)。 たとえば、foobar
を以下のようにコーディングしようとします:
: foobar STATE @ IF ( compilation state ) POSTPONE foo POSTPONE bar ELSE foo bar ENDIF ; immediate
これは foobar
がテキスト・インタープリターによってのみ処理される場合には機能しますが、 他のコンテキスト('
や
POSTPONE
など)では機能しません。 たとえば、 ' foobar
は、 元の foobar
のインタープリター機能ではなく、 state-smart ワードの実行トークンを生成します。 この実行トークンを(EXECUTE
で直接、
または COMPILE,
で間接的に)コンパイル状態において実行(execute)すると、 結果は期待したものになりません(つまり、
foo bar
は実行されません)。 state-smart ワードは良くないアイディアです。 対策は、
こんなの書かない事!です20。
このトピックに関する議論の詳細は M. Anton Ertl,
State
-smartness—Why
it is Evil and How to Exorcise it, EuroForth ’98. をご覧ください。