- 前説
- コンパイラが吐く言語は、仮想的なスタックマシーンへの命令とする。
- うーん。レジスタなマシーンはパタヘネでやったからわかるんだけど、スタックマシーンは初体験。
- 慎重に振舞いを確認してみる。
(lambda () (if (= x y) (f (g x)) (h x y (h 1 2))))
ARGS 0 ; move 0 arguments from stack to env (これなんのために?)
GVAR X ; push a gloval variable's name [X]
GVAR Y ; push a gloval variable's name [Y X]
GVAR = ; push a gloval variable's name (function) [= Y X]
; =は判定結果をスタックにおいて返るのであろう。
CALL 2 ; go to start of function(n args), saving return point [(result of (= x y))]
FJUMP L1 ; go to label if top-of-stack is nil; pop stack [nil/non-nil] -> []
GVAR X ; push a gloval variable's name [X]
GVAR G ; push a gloval variable's name (function) [G X]
CALL 1 ; go to start of function(n args), saving return point [(result of (g x))]
GVAR F ; push a gloval variable's name (function) [F (result of (g x))]
CALL 1 ; go to start of function(n args), saving return point [(result of (f (g x)))]
JUMP L2 ; go to label (don't pop stack)
L1: GVAR X ; [X]
GVAR Y ; [Y X]
CONST 1 ; [1 Y X]
CONST 2 ; [2 1 Y X]
GVAR H ; [H 2 1 Y X]
CALL 2 ; [(result of (H 1 2)) Y X]
GVAR H ; [H (result of (H 1 2)) Y X]
CALL 3 ; [(result of (H X Y (H 1 2)))]
L2: RETURN - なるほど。わかった。
- コンパイラは、interpと同様の条件分岐構造にて、コードを生成していく処理を実行していく形式。
次回は、23.1 A properly Tail-Recursive Lisp Compiler。
こつこつ。
0 件のコメント:
コメントを投稿