SICP 読み (316) 5.5 翻訳系

晩メシごちそうさまの後、23:00 まで死亡。とりあえず作業を再開してみる事に。
現時点では factorial の評価の準備が完了した状態のはず。ここの proc-code は

((env) (proc)
 ((assign proc
	  (op lookup-variable-value)
	  (const factorial)
	  (reg env))))

なんですが、前のエントリで (- n 1) が戻すリストが完成してない事に気づく。よく見てみると (- n 1) の proc-code と preserving してません。

(preserving '(env continue)
	    '((env) (proc)
	      ((assign proc
		       (op lookup-variable-value)
		       (const -)
		       (reg env))))
	    '((proc argl) (env proc val argl continue)
	      ((test (op primitive-procedure?) (reg proc))
	       (branch (label primitive-branch9))
	       compiled-branch10
	       (assign continue (label after-call11))
	       (assign val (op compiled-procedure-entry)
		       (reg proc))
	       (goto (reg val))
	       primitive-branch9
	       (assign val
		       (op apply-primitive-procedure)
		       (reg proc)
		       (reg argl))
	       after-call11)))

む、違うな。まず construct-arglist が戻す

(() (val argl)
 ((assign val (const 1))
  (assign argl (op list) (reg val))))

と preserving しないと駄目だ。

(preserving '(proc continue)
	    '(() (val argl)
	      ((assign val (const 1))
	       (assign argl (op list) (reg val))))
	    '((proc argl) (env proc val argl continue)
	      ((test (op primitive-procedure?) (reg proc))
	       (branch (label primitive-branch9))
	       compiled-branch10
	       (assign continue (label after-call11))
	       (assign val (op compiled-procedure-entry)
		       (reg proc))
	       (goto (reg val))
	       primitive-branch9
	       (assign val
		       (op apply-primitive-procedure)
		       (reg proc)
		       (reg argl))
	       after-call11)))

これも単純 append で良いな。

'((proc) (env proc val argl continue)
  ((assign val (const 1))
   (assign argl (op list) (reg val))
   (test (op primitive-procedure?) (reg proc))
   (branch (label primitive-branch9))
   compiled-branch10
   (assign continue (label after-call11))
   (assign val (op compiled-procedure-entry)
	   (reg proc))
   (goto (reg val))
   primitive-branch9
   (assign val
	   (op apply-primitive-procedure)
	   (reg proc)
	   (reg argl))
   after-call11))

で、これと proc-code を preserving なソレが以下ですか

(preserving '(env continue)
	    '((env) (proc)
	      ((assign proc
		       (op lookup-variable-value)
		       (const -)
		       (reg env))))
	    '((proc) (env proc val argl continue)
	      ((assign val (const 1))
	       (assign argl (op list) (reg val))
	       (test (op primitive-procedure?) (reg proc))
	       (branch (label primitive-branch9))
	       compiled-branch10
	       (assign continue (label after-call11))
	       (assign val (op compiled-procedure-entry)
		       (reg proc))
	       (goto (reg val))
	       primitive-branch9
	       (assign val
		       (op apply-primitive-procedure)
		       (reg proc)
		       (reg argl))
	       after-call11)))

これもざっくり append で良いのか

'((env) (env proc val argl continue)
  ((assign proc
	   (op lookup-variable-value)
	   (const -)
	   (reg env))
   (assign val (const 1))
   (assign argl (op list) (reg val))
   (test (op primitive-procedure?) (reg proc))
   (branch (label primitive-branch9))
   compiled-branch10
   (assign continue (label after-call11))
   (assign val (op compiled-procedure-entry)
	   (reg proc))
   (goto (reg val))
   primitive-branch9
   (assign val
	   (op apply-primitive-procedure)
	   (reg proc)
	   (reg argl))
   after-call11))

あら、なんかおかしいぞ。(- n 1) じゃねぇのかよ、と。面倒臭いのでこの時点で手を入れます。n を lookup したソレが cons されれば OK のはずなので以下か。

'((env) (env proc val argl continue)
  ((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-branch9))
   compiled-branch10
   (assign continue (label after-call11))
   (assign val (op compiled-procedure-entry)
	   (reg proc))
   (goto (reg val))
   primitive-branch9
   (assign val
	   (op apply-primitive-procedure)
	   (reg proc)
	   (reg argl))
   after-call11))

これが (- n 1) が戻すナニとゆー事で、これとてっぺんの式をナニ

(preserving 
 '(env continue)
 '((env) (proc)
   ((assign proc
	    (op lookup-variable-value)
	    (const factorial)
	    (reg env))))
 '((env) (env proc val argl continue)
   ((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-branch9))
    compiled-branch10
    (assign continue (label after-call11))
    (assign val (op compiled-procedure-entry)
	    (reg proc))
    (goto (reg val))
    primitive-branch9
    (assign val
	    (op apply-primitive-procedure)
	    (reg proc)
	    (reg argl))
    after-call11)))

む。これおかしいな。proc カブってますが上記の式だと最初の proc は save されない。ばたばたヤってるから雑になってるな。