SICP 読み (308) 5.5 翻訳系

この数日、5.5.2 節以降をニラんでるんですが、ワケワカ。仕方が無いので compile に吸わせてみた。
以下は出力されたリストの内 statements 部分のみ。しかも参照なナニを修正してます。

 (assign val (op make-compiled-procedure) (label entry6) (reg env)) 
 (goto (label after-lambda7)) 
entry6 
 (assign env (op compiled-procedure-env) (reg proc)) 
 (assign env (op extend-environment) (const (n)) (reg argl) (reg env)) 
 (save continue) 
 (save env) 
 (assign proc (op lookup-variable-value) (const =) (reg env))
 (assign val (const 1)) 
 (assign argl (op list) (reg val))
 (assign val (op lookup-variable-value) (const n) (reg env)) 
 (assign argl (op cons) (reg val) (reg argl)) 
 (test (op primitive-procedure?) (reg proc)) 
 (branch (label primitive-branch11)) 
compiled-branch12 
 (assign continue (label after-call13)) 
 (assign val (op compiled-procedure-entry) (reg proc)) 
 (goto (reg val)) 
primitive-branch11 
 (assign val (op apply-primitive-procedure) (reg proc) (reg argl))
after-call13 
 (restore env) 
 (restore continue) 
 (test (op false?) (reg val)) 
 (branch (label false-branch9)) 
true-branch8 
 (assign val (const 1)) 
 (goto (reg continue)) 
false-branch9 
 (assign proc (op lookup-variable-value) (const *) (reg env)) 
 (save continue) 
 (save proc) 
 (assign val (op lookup-variable-value) (const n) (reg env)) 
 (assign argl (op list) (reg val)) 
 (save env) 
 (save argl) 
 (assign proc (op lookup-variable-value) (const -) (reg env)) 
 (assign val (const 1)) 
 (assign argl (op list) (reg val))
 (assign val (op lookup-variable-value) (const n) (reg env)) 
 (assign argl (op cons) (reg val) (reg argl)) 
 (test (op primitive-procedure?) (reg proc)) 
 (branch (label primitive-branch14)) 
compiled-branch15 
 (assign continue (label after-call16)) 
 (assign val (op compiled-procedure-entry) (reg proc)) 
 (goto (reg val)) 
primitive-branch14 
 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) 
after-call16 
 (restore argl) 
 (assign argl (op cons) (reg val) (reg argl)) 
 (restore env) 
 (assign val (op lookup-variable-value) (const factorial) (reg env)) 
 (assign argl (op cons) (reg val) (reg argl)) 
 (restore proc) 
 (restore continue) 
 (test (op primitive-procedure?) (reg proc)) 
 (branch (label primitive-branch17)) 
compiled-branch18 
 (assign val (op compiled-procedure-entry) (reg proc)) 
 (goto (reg val)) 
primitive-branch17 
 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) 
 (goto (reg continue)) 
after-call19 
after-if10 
after-lambda7 
 (perform (op define-variable!) (const factorial) (reg val) (reg env)) 
 (assign val (const ok))

これを手続き定義見ながらリバースですか。キッツいな。でもこれは中身を読んでいく上で良い材料ではないかと思います。

サワリのみ

compile は define 認定で compile-definition に制御が移る。そこでは var に factorial がセットされて get-value-code

(lambda (n) (if (= n 1) 1 (* (factiroal (- n 1)) n)))

を compile に吸わせた戻りがセットされる。compile-definition に渡される target は val で linkage は next になっている。compile-definition が戻すのは基本的に end-with-linkage が戻す式になるはずですが、linkage が next という事はケツに何も付加されないと勝手読みして上記の式の末端を見てみると一応合っている感じ。
もう少し書いておくと compile-definition の中の preserving な seq2 は

((env val) (val)
 ((perform (op define-variable!)
	   (const factorial)
	   (reg val)
	   (reg env))
  (assign val (const ok))))

になっているハズです。難関はその前の get-value-code です。セットされたリストを見てて、つい動作を追い掛けてしまいかけて (以下略
おおまかには compile-lambda -> compile-lambda-body -> compile-sequence → compile-if -> compile-application なカンジなんですが、これを一通り見ていくと何とか 5.5.4 あたりのソレが見えてくるのか。

追記

これってテキスト 356p から 357p のナニじゃんか (とほほ