SICP 読み (317) 5.5 翻訳系
うーん。今年の冬休みはあまりゆっくり勉強できなんだ。今日まで家事に稼働をとられて、SICP 方面は gdgd です。
(compile '(* (factorial (- n 1)) n) 'val 'return)
を再度手動で。ってこの書きだしは昨年末の最終版です。
なんとか分かりやすく整理しながら、なんですが ...
とりあえず
一番下の層にある (- n 1) からヤってみる。ってこれ今日の深夜にナニしてるな。とは言え出力微妙なので再検討。まず proc-code は
((env) (proc) ((assign proc (op lookup-variable-value) (const -) (reg env))))
で operand-codes が
(((env) (val) ((assign val (op lookup-variable-value) (const n) (reg env)))) (() (val) ((assign val (const 1)))))
になるんですが、これがサラに preserving で連結される。昨晩のナニと repeat yourself なので流したいんですが、このあたりがバグってる可能性があるだけに。
とその前に target は val で linkage は next で良いはず、を前提に compile-procedure-call をナニ。
昨晩のソレによればラベルが以下
- primitive-branch9
- compiled-branch10
- after-call11
で compile-linkage は after-call11 で。
compile-procedure-call
この手続きは条件分岐が無いんで target と linkage の値次第。ってここで年越しだ。(とほほ
年明けた
スデに酔っぱらいなのもあり preserving な検討中心ってコトで compile-procedure-call は面倒なんで評価器に吸わせて以下
((proc argl) (env proc argl continue val) ((test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch1)) compiled-branch2 (assign continue (label after-call3)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch1 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call3))
これ、ラベルがナニですが面倒臭いので operand-codes も自動変換で。
((env) (val argl) ((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))))
上二つを (proc continue) で preserving なんですが、引数なリストは operand-codes を変換したナニの次が compile-procedure-call の順なんですが、seq2 (compile-procedure-call のソレ) の needs と seq1 (operand-codes) の modifies はマッチするのが無いので単純 append になる。単純 append ってもねぇ。
ええと、seq1 の needed と seq2 の needed から seq1 の modified を引いたナニを、なんですが、seq1 で argl が modify されますんで以下でしょうか
((env proc) (env proc argl continue val) ((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-branch1)) compiled-branch2 (assign continue (label after-call3)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch1 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call3))
多分大丈夫。(何
次は一番てっぺんの proc-code と (env continue) で preserving です。これ、
((env) (proc) ((assign proc (op lookup-variable-value) (const -) (reg env))))
の modified に (env continue) は無いので append で良いのかなぁ。なんか同じトコをループしている雰囲気満点。さくっと以下で良いのかなぁ
((env) (env proc argl continue val) ((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-branch1)) compiled-branch2 (assign continue (label after-call3)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch1 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call3))
これが factorial の引数になるためのナニがアレ。ってか、駄目だ。なんか腹立つ。