Next: , Previous: , Up: Carnal words   [Contents][Index]


6.30.2 Header methods

新しい 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-executeset-does> は、executecompile, が一致していることを確認するために、 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+clink フィールドを削除できるようにするためのメソッドです。 これらのワードを使用すると意味のある結果が得られます。 通常、 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 に設定します。


Next: Threading Words, Previous: Header fields, Up: Carnal words   [Contents][Index]