2008/07/13

[Forth] コンパイル時にスタックをいじると

"LET OVER LAMBDA" のサンプルで出てきた Forth のコードの話。

処理系は gforth で。

普通に 5 から 1 までを表示するコード。ちゃんと begin 〜 again の中に if 〜 then がはいっている。

: countdown
begin
dup 1 < if drop exit [ .s ] then
dup .
1-
again ;

5 countdown

これを、コンパイル中にスタックをいじってみるたりすると、begin 〜 if 〜 again 〜 then なんて順番で書けたりする。普通の言語ならコンパイルエラーだが、これはちゃんと動作する。

: countdown2
begin
dup 1 >= if dup . 1-
[ rot drop 2swap 0 -rot ]
again
then
drop ;

5 countdown2

次の部分で again のジャンプ先と if で偽だった場合のジャンプ先を入れ替えている。LOL のサンプルでは [ swap ] だったけど gforth では begin も if ともに 2 つの値をスタックに積むようで、さらにダミーの 0 が間に入っていたいりするので強引にいれかえるコードになってしまった。ん? 3つの値をつむのか。

[ rot drop 2swap 0 -rot ]

Forth ではこんなふうに文法さえ無視することができる。もちろん Forth だから文法なんかじゃなくて、begin も again も if も then も単なる word(関数)でしかないのだけどね。

こんなことができたりするから Forth はたまらない。

あれ? コードに色が付かない。。。

0 件のコメント: