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 の引数になるためのナニがアレ。ってか、駄目だ。なんか腹立つ。