- 上記の関数呼び出しを次のように書くことにしました。
lbstk2(0,1); PLIMM(P1E, lbstk1(0,0)); JMP(12); LB0(lbstk1(0,0)); lbstk3(0);
- これは次のような意味を持ちます。
- lbstk2(j, sz); : 新規にラベル用の連続した番号をsz個発行し、その番号のうち一番小さいものをスタックにつみます。使用するスタックはj番目のスタックです(lbstk03ではスタックを4本持っていて、0~3を指定できます)。
- 上記例でj=0としたのは、関数コール用のスタックとしてj=0を使っているからです。
- この命令自身は、ラベルの発行を促す以上の意味を持たないので、出力ソースには現れません(消滅します)。
- lbstk1(j, ofs) : スタック[j]から一番上のラベル番号を取得します。popはしません。peekです。その数値にofsを加えラベル番号とし、lbstk1(j, ofs)の記述と置換して出力します。
- lbstl3(j); : スタック[j]から一番上のラベル番号をpopし、値を読み捨てます。この命令もスタック状態を制御する以上の意味を持たないので、出力ソースには現れません(消滅します)。
- このような機構により、以下のように完全に同一の記述を何度書いても問題なくなりました。
lbstk2(0,1); PLIMM(P1E, lbstk1(0,0)); JMP(12); LB0(lbstk1(0,0)); lbstk3(0);
lbstk2(0,1); PLIMM(P1E, lbstk1(0,0)); JMP(12); LB0(lbstk1(0,0)); lbstk3(0);
- ということで、これはマクロ化されて、 CALL(12); とだけ書くことになっています。
#define CALL(label) lbstk2(0,1); PLIMM(P1E, lbstk1(0,0)); JMP(label); LB0(lbstk1(0,0)); lbstk3(0)
- このスタック操作は、ソースの書き換えの際にラベル番号を求めるために仮想的に行うものであって、アプリの実行時に行うわけではありません。