新しい Gforth ワード・ヘッダーはオブジェクト指向であり、 以下のメソッド(メソッド・セレクター)をサポートします:
.hm label method overrider field execute set-execute >cfa opt: opt-compile, set-optimizer >hmcompile, to: (to) set-to >hmto extra: >hmextra >int: name>interpret set->int >hm>int >comp: name>compile set->comp >hm>comp >string: name>string set-name>string >hm>string >link: name>link set-name>link >hm>link
これらのワードの多くは定着(stable)した Gforth ワードではありませんが、 Gforth には後述する定着した高レベルのワードがあります。
以下を使用すると、 ワードのヘッダー・メソッドを確認できます
.hm
( nt – ) gforth-1.0 “dot-h-m”
nt のヘッダー・メソッドを出力します
オーバーライダー(overrider)(セッター)ワードは、 最新の定義のメソッド実装を変更します。 クォーテーションまたはクロージャーは、 完了時に以前の最新の定義を復元するため、 最新のものとはみなされず、 以下のようなことができます:
: my2dup over over ; [: drop ]] over over [[ ;] set-optimizer
execute
メソッドは、 パフォーマンス上の理由から、 実際にはヘッダー・メソッド・テーブルではなくヘッダーの >cfa
フィールドに格納されます。 また、 他のメソッドは xt を呼び出すことによって実装されますが、 ネイティブ・コード・アドレスを通じて実装されます。
このメソッドを設定する大まかな方法は以下のとおりです
set-execute
( ca – ) gforth-1.0 “set-execute”
ca のネイティブ・コードにジャンプするように現在のワードを変更します。 また、 compile,
実装を最も一般的な(そして最も遅い)実装に変更します。 より効率的な compile,
実装が必要な場合は、 後で
set-optimizer
を呼び出します。
set-execute
で使用するコード・アドレスを取得するには、 docol:
または
>code-address
などのワードを使用できます。 See Threading Words
set-execute
の代わりに、 xt を受け取る set-does>
(see User-defined Defining Words)もあります。
さらに、 低レベルの code-address!
と definer!
があります。 (see Threading Words)
opt-compile,
メソッドは、 ほとんどの Gforth エンジンで動く compile,
です(gforth-itc
は代わりに ,
を使用します)。 set-optimizer
を使用して、
現在のワードに対する compile,
のより効率的な実装を定義できます((see User-defined compile,
))。 注意: 最終結果は postpone literal postpone execute
と同等でなければならないことに注意してください。
set-optimizer
の使用例として、 以下の constant
の定義を考えてみましょう:
: constant ( n "name" -- ; name: -- n ) create , ['] @ set-does> ; 5 constant five : foo five ; see foo
Forth システムは、 定数の値を変更してはならないことを認識せず、 単に create
されたワード (>body
で変更可能)として見て、 foo
は最初に five
のボティのアドレスをスタックにプッシュし、
その次にそこから値を取得します。 set-optimizer
を使用すると、 constant
の定義を以下のように最適化できます:
: constant ( n "name" -- ; name: -- n ) create , ['] @ set-does> [: >body @ postpone literal ;] set-optimizer ;
いまや、 foo
には、 five
の呼び出しではなく、 即値(literal)の 5 が含まれるようになりました。
注意: set-execute
と set-does>
は、execute
と compile,
が一致していることを確認するために、 set-optimizer
自体を実行することに注意してください。
あなた独自のオプティマイザーを追加するには、 後で追加する必要があります。
defer!
(別名 (to)
メソッド(see User-defined to
and defer@
)は、
defer
で定義されたワードおよび類似のワードに対して defer!
を実装します。 ですが、 これは to
の核心(core)でもあります。 defer!
/(to)
メソッドの一般的なスタック効果は ( val xt
-- )
です。 ここで xt は格納されているワードを示し、 val はそこに格納されている(適切な型の)値です。
たとえば、 以下のように fvalue
を実装できます:
: fvalue-to ( r xt -- ) >body f! ; : fvalue ( r -- ) create f, ['] f@ set-does> ['] fvalue-to set-to ; 5e fvalue foo : bar foo 1e f+ to foo ; see bar
set-optimizer
を使用して、 生成されたコードを改善できます:
: compile-fvalue-to ( xt-value-to -- ) drop ]] >body f! [[ ; : fvalue-to ( r xt -- ) >body f! ; ' compile-fvalue-to set-optimizer : fvalue ( r -- ) create f, ['] f@ set-does> [: >body ]] literal f@ [[ ;] set-optimizer ['] fvalue-to set-to ; 5e fvalue foo : bar foo 1e f+ to foo ; see bar
実際には、 Gforth には、 +TO
など、 実装するための追加の工夫がいくつかあります。
Set-defer@
(see User-defined to
and defer@
) を使用すると、
defer
のようなワードに対して defer@
(see Deferred Words)
メソッドのバリエーションを実装できます。
>hmextra
フィールドは、 追加のデータをヘッダー・メソッド・テーブルに保存する必要がある場合に使用されます。 特に、 それは
set-does>
に渡す xt を保存し(そして does>
は set-does>
を呼び出し)、
そして、 ;abi-code
の後のコードのアドレスを保存します。
これらのメソッドはすべて、 nt ではなく xt を使用しますが、 オーバーライド・ワード(override words)は最新の定義で機能します。
これは、 たとえば、 同義語(synonym)に対して set-optimizer
を使用した場合、
その効果はおそらくあなたが意図したものとは異なることを意味します。 ワードの xt を compile,
する場合、
新たに設定された同義語(synonym)ではなく、 元のワードの opt-compile,
実装が使用されます。
以下のメソッド達は nt を消費します。
name>interpret
メソッドは、 同義語(synonym)や類似のワードを除くほとんどのワードに対して noop
として実装されます。
set->int
( xt – ) gforth-1.0 “set-to-int”
現在のワードの name>interpret (nt -- xt2 )
メソッドの実装を xt に設定します。
name>compile
メソッドは、 nt のコンパイル機能(compilation semantics)を生成します。
set->comp
で変更することでコンパイル機能を変更できますが、 name>compile
のスタック効果のため、
目的のコンパイル機能の xt をプッシュするだけというほど単純ではありません。 一般に、 コンパイル機能の変更は避ける必要があり、 変更する場合は、
immediate
または interpret/compile:
などの高レベル・ワードを使用してください(See Combined Words)。
set->comp
( xt – ) gforth-1.0 “set-to-comp”
現在のワードの name>compile ( nt -- w xt2 )
メソッドの実装を xt に設定します。
immediate?
( nt – flag ) gforth-1.0 “immediate?”
ワード nt がデフォルト以外のコンパイル機能(compilation semantics)を持っている場合は true (これは即時性(immediacy)の定義と完全には一致しませんが、 多くの人はワード語を「即時」(immediate)と呼ぶときはこれを意味しています)。
Name>string
および Name>link
は、 noname ヘッダーから name と >f+c
と link
フィールドを削除できるようにするためのメソッドです。 これらのワードを使用すると意味のある結果が得られます。 通常、
noname
を使用する場合を除き、 これらのメソッドの実装を変更することはありませんが、
あなたがそれでも必要とするなら以下をご覧ください
set-name>string
( xt – ) gforth-1.0 “set-name-to-string”
現在のワードの name>string ( nt -- addr u )
メソッドの実装を xt に設定します。
set-name>link
( xt – ) gforth-1.0 “set-name-to-link”
現在のワードの name>link (nt1 -- nt2|0 )
メソッドの実装を xt に設定します。