2015年1月4日日曜日

開発環境

計算機プログラムの構造と解釈[第2版](ハロルド エイブルソン (著)、ジュリー サスマン (著)、ジェラルド・ジェイ サスマン (著)、Harold Abelson (原著)、Julie Sussman (原著)、Gerald Jay Sussman (原著)、和田 英一 (翻訳)、翔泳社、原書: Structure and Interpretation of Computer Programs (MIT Electrical Engineering and Computer Science)(SICP))の5(レジスタ計算機での計算)、5.5(翻訳系)、5.5.5(翻訳したコードの例)、問題 5.38-c.を解いてみる。

その他参考書籍

問題 5.38-c.

コード(BBEdit, Emacs)

sample38_c_1.scm

#!/usr/bin/env gosh
;; -*- coding: utf-8 -*-

(load "./compiler.scm")

(print  (compile
         '(define (factorial n)
            (if (= n 1)
                1
                (* (factorial (- n 1)) n)))
         'val
         'next))

sample38_c_2.scm

#!/usr/bin/env gosh
;; -*- coding: utf-8 -*-

(load "./compiler38_b.scm")

(print  (compile
         '(define (factorial n)
            (if (= n 1)
                1
                (* (factorial (- n 1)) n)))
         'val
         'next))

入出力結果(Terminal(gosh), REPL(Read, Eval, Print, Loop))

$ ./sample38_c_1.scm
((env val) (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 (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-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 (restore env) (restore continue) (test (op false?) (reg val)) (branch (label false-branch4)) true-branch3 (assign val (const 1)) (goto (reg continue)) false-branch4 (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 argl) (assign proc (op lookup-variable-value) (const factorial) (reg env)) (save proc) (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 (assign argl (op list) (reg val)) (restore proc) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch12)) compiled-branch13 (assign continue (label after-call14)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch12 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call14 (restore argl) (assign argl (op cons) (reg val) (reg argl)) (restore proc) (restore continue) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch15)) compiled-branch16 (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch15 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) (goto (reg continue)) after-call17 after-if5 after-lambda2 (perform (op define-variable!) (const factorial) (reg val) (reg env)) (assign val (const ok))))
$ ./sample38_c_2.scm
((env val) (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 (n)) (reg argl) (reg env)) (assign arg1 (op lookup-variable-value) (const n) (reg env)) (assign arg2 (const 1)) (assign val (op apply-open-code-procedure) (op =) (reg arg1) (reg arg2)) after-call6 (test (op false?) (reg val)) (branch (label false-branch4)) true-branch3 (assign val (const 1)) (goto (reg continue)) false-branch4 (save env) (assign proc (op lookup-variable-value) (const factorial) (reg env)) (assign arg1 (op lookup-variable-value) (const n) (reg env)) (assign arg2 (const 1)) (assign val (op apply-open-code-procedure) (op -) (reg arg1) (reg arg2)) after-call7 (assign argl (op list) (reg val)) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch8)) compiled-branch9 (assign continue (label proc-return11)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) proc-return11 (assign arg1 (reg val)) (goto (label after-call10)) primitive-branch8 (assign arg1 (op apply-primitive-procedure) (reg proc) (reg argl)) after-call10 (restore env) (assign arg2 (op lookup-variable-value) (const n) (reg env)) (assign val (op apply-open-code-procedure) (op *) (reg arg1) (reg arg2)) (goto (reg continue)) after-call12 after-if5 after-lambda2 (perform (op define-variable!) (const factorial) (reg val) (reg env)) (assign val (const ok))))
$

見やすくするため、改行を挿入して修正。

レジスタ計算機。(元のコンパイラ)

(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 (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-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 
(restore env) 
(restore continue) 
(test (op false?) (reg val)) 
(branch (label false-branch4))
true-branch3 
(assign val (const 1)) 
(goto (reg continue))
false-branch4 
(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 argl) 
(assign proc (op lookup-variable-value) (const factorial) (reg env)) 
(save proc) 
(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 
(assign argl (op list) (reg val)) 
(restore proc) 
(test (op primitive-procedure?) (reg proc)) 
(branch (label primitive-branch12)) compiled-branch13 
(assign continue (label after-call14)) 
(assign val (op compiled-procedure-entry) (reg proc)) 
(goto (reg val))
primitive-branch12 
(assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call14 
(restore argl) 
(assign argl (op cons) (reg val) (reg argl)) 
(restore proc) 
(restore continue) 
(test (op primitive-procedure?) (reg proc)) 
(branch (label primitive-branch15))
compiled-branch16 
(assign val (op compiled-procedure-entry) (reg proc)) 
(goto (reg val))
primitive-branch15 
(assign val (op apply-primitive-procedure) (reg proc) (reg argl)) 
(goto (reg continue))
after-call17
after-if5
after-lambda2 
(perform (op define-variable!) (const factorial) (reg val) (reg env)) 
(assign val (const ok))))

レジスタ計算機。(修正したコンパイラ)

(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 (n)) (reg argl) (reg env)) 
(assign arg1 (op lookup-variable-value) (const n) (reg env)) 
(assign arg2 (const 1)) 
(assign val (op apply-open-code-procedure) (op =) (reg arg1) (reg arg2))
after-call6 
(test (op false?) (reg val)) 
(branch (label false-branch4))
true-branch3 
(assign val (const 1)) 
(goto (reg continue))
false-branch4 
(save env) 
(assign proc (op lookup-variable-value) (const factorial) (reg env)) 
(assign arg1 (op lookup-variable-value) (const n) (reg env)) 
(assign arg2 (const 1)) 
(assign val (op apply-open-code-procedure) (op -) (reg arg1) (reg arg2))
after-call7 
(assign argl (op list) (reg val)) 
(test (op primitive-procedure?) (reg proc)) 
(branch (label primitive-branch8))
compiled-branch9 
(assign continue (label proc-return11)) 
(assign val (op compiled-procedure-entry) (reg proc)) 
(goto (reg val))
proc-return11 
(assign arg1 (reg val)) 
(goto (label after-call10)) primitive-branch8 
(assign arg1 (op apply-primitive-procedure) (reg proc) (reg argl))
after-call10 
(restore env) 
(assign arg2 (op lookup-variable-value) (const n) (reg env)) 
(assign val (op apply-open-code-procedure) (op *) (reg arg1) (reg arg2)) 
(goto (reg continue))
after-call12
after-if5
after-lambda2 
(perform (op define-variable!) (const factorial) (reg val) (reg env)) 
(assign val (const ok))))

0 コメント:

コメントを投稿