SICP 読み (327) 5.5 翻訳系

問題 5.35

以下のリストを逆コンパイルという問題

  (assign val (op make-compiled-procedure) (label entry16)
                                           (reg env))
  (goto (label after-lambda15))
entry16
  (assign env (op compiled-procedure-env) (reg proc))
  (assign env
          (op extend-environment) (const (x)) (reg argl) (reg env))
  (assign proc (op lookup-variable-value) (const +) (reg env))
  (save continue)
  (save proc)
  (save env)
  (assign proc (op lookup-variable-value) (const g) (reg env))
  (save proc)
  (assign proc (op lookup-variable-value) (const +) (reg env))
  (assign val (const 2))
  (assign argl (op list) (reg val))
  (assign val (op lookup-variable-value) (const x) (reg env))
  (assign argl (op cons) (reg val) (reg argl))
  (test (op primitive-procedure?) (reg proc))
  (branch (label primitive-branch19))
compiled-branch18
  (assign continue (label after-call17))
  (assign val (op compiled-procedure-entry) (reg proc))
  (goto (reg val))
primitive-branch19
  (assign val (op apply-primitive-procedure) (reg proc) (reg argl))
after-call17
  (assign argl (op list) (reg val))
  (restore proc)
  (test (op primitive-procedure?) (reg proc))
  (branch (label primitive-branch22))
compiled-branch21
  (assign continue (label after-call20))
  (assign val (op compiled-procedure-entry) (reg proc))
  (goto (reg val))
primitive-branch22
  (assign val (op apply-primitive-procedure) (reg proc) (reg argl))
after-call20
  (assign argl (op list) (reg val))
  (restore env)
  (assign val (op lookup-variable-value) (const x) (reg env))
  (assign argl (op cons) (reg val) (reg argl))
  (restore proc)
  (restore continue)
  (test (op primitive-procedure?) (reg proc))
  (branch (label primitive-branch25))
compiled-branch24
  (assign val (op compiled-procedure-entry) (reg proc))
  (goto (reg val))
primitive-branch25
  (assign val (op apply-primitive-procedure) (reg proc) (reg argl))
  (goto (reg continue))
after-call23
after-lambda15
  (perform (op define-variable!) (const f) (reg val) (reg env))
  (assign val (const ok))

順に分かったナニを箇条書きで列挙していきます。

  • f という手続きの定義
  • 引数は x 一発。(define (f x) 略) という形か
  • (g (+ x 2)) している
  • いっちゃん外側の演算子 + の最初の引数は x で次が上記
  • 手続き部分は (+ x (g (+ x 2)))

てコトで以下か

(define (f x)
  (+ x (g (+ x 2))))

ええと評価器に上記を吸わせれば良いのか。で、出てきたのを整形したのが以下

((env continue) (val) 
 ((assign val (op make-compiled-procedure) (label entry1) (reg env)) 
  (goto (label after-lambda2)) 
  entry1 
  (assign env (op compiled-procedure-env) (reg proc)) 
  (assign env (op extend-environment) (const (x)) (reg argl) (reg env)) 
  (assign proc (op lookup-variable-value) (const +) (reg env))
  (save continue) 
  (save proc) 
  (save env) 
  (assign proc (op lookup-variable-value) (const g) (reg env)) 
  (save proc) 
  (assign proc (op lookup-variable-value) (const +) (reg env)) 
  (assign val (const 2)) 
  (assign argl (op list) (reg val)) 
  (assign val (op lookup-variable-value) (const x) (reg env)) 
  (assign argl (op cons) (reg val) (reg argl)) 
  (test (op primitive-procedure?) (reg proc)) 
  (branch (label primitive-branch3)) 
  compiled-branch4 
  (assign continue (label after-call5)) 
  (assign val (op compiled-procedure-entry) (reg proc)) 
  (goto (reg val)) 
  primitive-branch3 
  (assign val (op apply-primitive-procedure) (reg proc) (reg argl))
  after-call5 
  (assign argl (op list) (reg val)) 
  (restore proc) 
  (test (op primitive-procedure?) (reg proc)) 
  (branch (label primitive-branch6)) 
  compiled-branch7 
  (assign continue (label after-call8)) 
  (assign val (op compiled-procedure-entry) (reg proc)) 
  (goto (reg val)) 
  primitive-branch6 
  (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) 
  after-call8 
  (assign argl (op list) (reg val)) 
  (restore env) 
  (assign val (op lookup-variable-value) (const x) (reg env)) 
  (assign argl (op cons) (reg val) (reg argl)) 
  (restore proc) 
  (restore continue) 
  (test (op primitive-procedure?) (reg proc)) 
  (branch (label primitive-branch9)) 
  compiled-branch10 
  (assign val (op compiled-procedure-entry) (reg proc)) 
  (goto (reg val)) 
  primitive-branch9 
  (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) 
  (goto (reg continue)) 
  after-call11 
  after-lambda2 
  (perform (op define-variable!) (const f) (reg val) (reg env)) 
  (assign val (const ok)) 
  (goto (reg continue))))

OKな模様。案外簡単でした。そろそろハードルがどかーんと上がりそうな予感。