開発環境
- OS X Mavericks - Apple(OS)
- Emacs (CUI)、BBEdit - Bare Bones Software, Inc. (GUI) (Text Editor)
- Scheme (プログラミング言語)
- MIT/GNU Scheme (処理系)
計算機プログラムの構造と解釈(Gerald Jay Sussman(原著)、Julie Sussman(原著)、Harold Abelson(原著)、和田 英一(翻訳)、ピアソンエデュケーション、原書: Structure and Interpretation of Computer Programs (MIT Electrical Engineering and Computer Science)(SICP))の5(レジスタ計算機での計算)、5.5(翻訳系)、翻訳系の概観、5.5.5(翻訳したコードの例)、問題 5.33-b.を解いてみる。
その他参考書籍
問題 5.33.
翻訳。
(assign val (op make-compiled-procedure) (label entry2) (reg env)) (goto (label after-lambda1)) entry2 ;; factorial-altの呼び出し (assign env (op compiled-procedure-env) (reg proc)) (assign env (op extend-environment) (const (n)) (reg argl) (reg env)) ;; 手続き本体の開始 (save continue) (save 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-branch17)) compiled-branch16 (assign continue (label after-call15)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch17 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call15 ;; valには(= n 1)の結果がある (restore env) (restore continue) (test (op false?) (reg val)) (branch (label false-branch4)) true-branch5 ;; 1を返す (assign val (const 1)) (goto (reg continue)) false-branch4 ;; (* n (factorial-alt (- n 1)))を計算して返す (assign proc (op lookup-variable-value) (const *) (reg env)) (save continue) (save proc) ;; 手続きを退避 (save env) ;; factorial-altでは必要 ;; (factorial-alt (- n 1))の計算 (assign proc (op lookup-variable-value) (const factorial-alt) (reg env)) (save proc) ;; (- n 1)の計算 (assign proc (op lookup-variable-value) (const -) (reg env)) (assign val (const 1)) (assign argl (op list) (reg val)) ;; (save argl) factorial-altでは不必要 (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-branch8)) compiled-branch7 (assign continue (label after-call6)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch8 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call6 ;; valには(- n 1)の結果がある (assign argl (op list) (reg val)) (restore proc) (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch11)) compiled-branch10 (assign continue (label after-call9)) (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch11 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) after-call9 ;; valには(factorial-alt (- n 1))の結果がある ;; (restore argl) factorial-altでは不必要 (assign argl (op list) (reg val)) (restore env) ;; factorial-altでは必要 (assign val (op lookup-variable-value) (const n) (reg env)) (assign argl (op cons) (reg val) (reg argl)) (restore proc) ;; *を回復 (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch14)) compiled-branch13 (assign val (op compiled-procedure-entry) (reg proc)) (goto (reg val)) primitive-branch14 (assign val (op apply-primitive-procedure) (reg proc) (reg argl)) (goto (reg continue)) after-call12 after-if3 after-lambda1 (perform (op define-variable!) (const factorial-alt) (reg val) (reg env)) (assign val (const ok))
条件式ifのfalse部分について、factorial階乗手続きは、nを計算し、部分引数リストを退避し、(factorial (- n 1))を計算し、部分引数リストを回復して結果を求める。
一方、factorial-alt階乗手続きは、環境を退避し、(factorial (- n 1))を計算して、環境を回復して結果を求める。
部分引数リストを退避回復するか、環境を退避回復するかという相違はあるけど、どちらのプログラムの実行も効率性に大きな差はない。
0 コメント:
コメントを投稿