Next: , Previous: , Up: Locals   [Contents][Index]


6.22.1 Gforth locals

ローカル変数は以下のように定義できます

{: local1 local2 ... -- comment :}

or

{: local1 local2 ... :}

or

{: local1 local2 ... | ulocal0 ulocal1 -- comment :}

例えば、 以下のように使います

: max {: n1 n2 -- n3 :}
 n1 n2 > if
   n1
 else
   n2
 endif ;

ローカル変数定義とスタック・コメントは、 類似するよう意図しています。 ローカル変数定義は、 多くの場合、 ワードのスタック・コメントを置き換えます。 ローカル変数の順序はスタック・コメント内の順序に対応し、 -- 以降はすべて実際はコメントです。

この類似性には 1 つ欠点があります。 ローカル変数宣言とスタック・コメントを混同しやすく、 バグが発生し、 見つけにくくなります。 ただし、 この問題は適切なコーディング規約によって回避できます。 同じプログラム内で両方の表記法を使用しないでください。 そうする場合は、 追加の手段を使用して区別する必要があります。 例えば、 場所によって区別します。

ローカルの名前の前に型指定子を付けることができます。 たとえば、浮動小数点値の場合は F: です:

: CX* {: F: Ar F: Ai F: Br F: Bi -- Cr Ci :}
\ 複素数の掛け算
 Ar Br f* Ai Bi f* f-
 Ar Bi f* Ai Br f* f+ ;

Gforth は現在、 セル型指定子(W:, WA:, W^)や、 2倍長整数型指定子(D:, DA:, D^)や、 浮動小数点数型指定子(F:, FA:, F^)と、 さまざまなフレーバーの xt 型指定子(xt:, xta:)、 をサポートしています:

valueフレーバー(value-flavoured)

(see Values) valueフレーバーのローカル変数(W:D: などで定義)はその値を生成し、 TO で変更できます。

varueフレーバー(vaLue ではなくて vaRue)

(see Varues) varueフレーバーのローカル変数 foo (WA: などで定義) は、 addr foo を使用してアドレスを取得できること(変数のスコープを離れると無効になります)を除いて、 valueフレーバーのローカル変数とまったく同じように振る舞います。 現時点ではパフォーマンスに違いはありませんが、 長期的には、 valueフレーバーのローカル変数はレジスタに常駐できるため、 大幅に高速になるでしょう。

variableフレーバー

(see Variables) variableフレーバーのローカル変数(W^ などで定義)はそのアドレスを生成します(変数のスコープを離れると無効になります)。 たとえば、 標準のワード emit は、 以下のように variableフレーバーのローカル変数(C^ char*) と type で定義できます:

: emit {: C^ char* -- :}
    char* 1 type ;
deferフレーバー(defer-flavoured)

(see Deferred Words) (XT: または XTA: と指定した) defer フレーバーのローカル変数 xt を execute します。 action-of を使用すると、 defer フレーバーのローカル変数から xt を取得できます。 ローカル変数が xta: で定義されている場合、 addr を使用して、 xt が保存されているアドレス(ローカル変数のスコープの終わりまで有効)を取得できます。 たとえば、 標準のワード execute は、 以下のように defer フレーバーのローカル変数で定義できます:

: execute {: xt: x -- :}
  x ;

型指定子のないローカル変数は W: ローカル変数として扱われます。 以下を使用して addr の使用を許可または禁止できます:

default-wa: ( ) gforth-experimental “default-wa:”

型指定子なしで定義されたローカル変数で addr を許可します。 言い換えれば、 型指定子無しでローカル変数定義したときは wa: 型指定子を指定したのと同じです

default-w: ( ) gforth-experimental “default-w:”

型指定子なしで定義されたローカル変数では addr を禁止します。 言い換えれば、 型指定子なしで定義されたローカル変数は w: 型指定子を指定してローカル変数を定義したのと同じです。

| の後ろで定義されたローカル変数を除いて、 ローカル変数の全てのフレーバーは、 データ・スタックの値または、 (FP ローカル変数の場合) FP スタックの値で初期化されます。 Gforth は | の後ろで定義されたローカル変数を 0 に初期化します。 一部の Forth システムでは初期化されないままになっています。

Gforth は、 ローカル・バッファーとデータ構造体のための角括弧(square bracket)表記をサポートしています。 これらのローカル変数は variableフレーバーのローカル変数に似ており、 サイズは定数式として指定します。 宣言は name[ size ] のようになります。 Forth の式 size は宣言中に評価され、 サイズをバイト単位で指定するスタック効果 ( -- +n ) が必要です。 なお、 角括弧 [ は定義された名前の一部です。

ローカルのデータ構造体は、 データ・スタックに渡されたアドレスから size バイトをコピーすることによって初期化されます。 (宣言内の | の後の、)初期化されていないローカルのデータ構造体は消去されず、 以前にローカル・スタックにあったデータをすべて含むだけです。

Example:

begin-structure test-struct
  field: a1
  field: a2
end-structure

: test-local {: foo[ test-struct ] :}
    foo[ a1 !  foo[ a2 !
    foo[ test-struct dump ;

Gforth では、コロン定義内のあらゆる場所でローカル変数を定義できます。 これにより、 以下のような疑問が生じます:


Next: Standard Forth locals, Previous: Locals, Up: Locals   [Contents][Index]