' word は、 ワードの実行トークン(execution token)(XT)を提供します。 XT は、
ワードのインタープリター機能(interpretation semantics)表すセルです。 これは execute で実行できます:
' + .s 1 2 rot execute .
XT は C の関数ポインターに似ています。 ただし、 パラメーターがスタックで渡されるため、もう少し柔軟になります:
: map-array ( ... addr u xt -- ... )
\ addr で始まり u 個の要素を含む配列のすべての要素に対して
\ xt ( ... x -- ... ) を実行します
{ xt }
cells over + swap ?do
i @ xt execute
1 cells +loop ;
create a 3 , 4 , 2 , -1 , 4 ,
a 5 ' . map-array .s
0 a 5 ' + map-array .
s" max-n" environment? drop .s \ 下記比較初期値用に整数最大値を得る
a 5 ' min map-array . \ 最初の要素は、 environment? で取得した整数最大値と比較
生成するより消費する要素が 1 つ多いワードの XT に対して map-array を使用できます。 理論的には、他の XT でも使用できますが、 スタック効果は配列のサイズに依存するため、理解するのが困難です。
XT はセルサイズであるため、 メモリーに保存し、 他のセルと同様にスタック上で操作できます。 compile, を使用して XT
をワードにコンパイルすることもできます:
: foo1 ( n1 n2 -- n ) [ ' + compile, ] ; see foo1
compile, は標準ではコンパイル機能(compilation semantics)がないため、 上記は標準ではないけれども、 良い
Forth システムでは動作します。 うまくいかなかったモノついては、 以下を使用してください
: [compile,] compile, ; immediate : foo1 ( n1 n2 -- n ) [ ' + ] [compile,] ; see foo1
' は、 デフォルトでコンパイル機能(compilation semantics)を持つワードです。
そのワードのインタープリター機能(interpretation semantics)を実行すると、 その次のワードを構文解析(parse)します。
: foo ( -- xt ) ' ; see foo : bar ( ... "word" -- ... ) ' execute ; see bar 1 2 bar + .
コンパイル中にワードを解析(parse)し、 その XT をコンパイルして、 実行時にスタックにプッシュされるようにしたいことがよくあります。
['] はこれを行います:
: xt-+ ( -- xt ) ['] + ; see xt-+ 1 2 xt-+ execute .
多くのプログラマーは、 ' とそれが解析(parse)するワードを 1 つの単位として認識し、 コンパイル時に [']
のように動作することを期待し、 実際の動作に混乱する傾向があります。 あなたがもしそうなら、 Forth システムは ' を 1
つの単位として捉えているだけであり、
それが解析(parse)ワードであるとはまったく考えていないことを覚えておいてください(この問題でプログラマーの便宜を図る試みは、 通常、
さらにひどい落とし穴につながります。
State-smartness—Why it is evil and How to Exorcise it)。
XT の作成および実行は、 インタープリターの状態には影響を受けないことに注意してください。 つまり、 コンパイル状態で '
を実行した場合でも、 インタープリター機能(interpretation semantics)が得られます。 そして、 そこでの状態が何であれ、
execute は XT によって表されるコード(つまり、' で生成された XT
の場合はインタープリター機能(interpretation semantics))を実行します。
こちらも参照ください: Tokens for Words