例として、 以下の簡単な VM 命令の記述を使用します:
sub ( i1 i2 -- i ) i = i1-i2;
最初の行には、 VM 命令の名前 (sub
) とそのスタック効果 (i1 i2 -- i
) を指定します。
最初の行以外の記述の残りの部分は単なる C 言語コードです。
スタック効果では、 sub
がデータ・スタックから 2 つの整数を取得し、 それらを C 言語の変数 i1
と
i2
に格納することを指定します(右端の項目 (i2
) が、 スタックのトップです: i1
をスタックにプッシュし、 次に i2
をスタックにプッシュすると、 結果のスタック状態は i1 i2
になります)。
そしてその後、 その後 1 つの整数 (i
) をスタックにプッシュします(右端の項目がスタックの一番上になります)。
スタック項目の型とスタックを知るにはどうすればよいでしょうか? Vmgen は、 Fortran と同様にプレフィックスを使用します。 Fortran とは対照的に、 あなたは最初にプレフィックスを定義する必要があります:
\E s" Cell" single data-stack type-prefix i
これは、 型 Cell
(mini.h では long
として定義)を参照するプレフィックス i
を定義し、 デフォルトでは data-stack
を参照します。 また、 この型が 1
つのスタック項目(single
)を占めることも指定します。 型プレフィックスは変数名の一部です。
data-stack
を使用する前に、 この方法で data-stack
を定義する必要があります:
\E stack data-stack sp Cell
この行は、 スタック・ポインター sp
を使用するスタック data-stack
を定義し、 各項目の基本タイプは
Cell
です。 他の型は 1 つまたは 2 つの Cell
に収まる必要があり(型の幅が single
か
double
かによって異なります)、 型キャスト・マクロ(see VM engine)を使用して
data-stack
にアクセスするときに Cell との間でキャストされます。 Vmgen 製インタープリターではスタックは、
デフォルトでは、 より低いアドレスに向かって伸長します(see Stack growth direction)。
スタック・プレフィックスを使用して、 スタック項目のデフォルト・スタックをオーバーライドできます。 たとえば、 以下の命令について考えてみましょう:
lit ( #i -- i )
VM 命令 lit
は、 命令ストリームから(プレフィックス #
で示される) 項目 i
を取得し、
それを(デフォルトの)データ・スタックにプッシュします。 スタック・プレフィックスは変数名の一部ではありません。
スタック・プレフィックスは以下のように定義されています:
\E inst-stream stack-prefix # \E data-stack stack-prefix S:
この定義は、 スタック・プレフィックス #
が「スタック inst-stream
」を指定することを定義します。
命令ストリーム(inst-stream
)は通常のスタックとは振る舞いが少し異なるため、 事前に定義済であり、
あなたが定義する必要はありません。
命令ストリームには命令とその直接引数(immediate arguments)が含まれるため、
引数が命令ストリームからのものであることを指定することは、 直接引数であることを示しています。 もちろん、 命令ストリーム引数は、 スタック効果の
--
の左側にのみ出現できます。 複数の命令ストリーム引数がある場合、 (あなたの直観どおり)左端が最初の引数になります。