開発環境
- 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.7(翻訳したコードと評価器のインターフェース)、解釈と翻訳、問題 5.47.を解いてみる。
その他参考書籍
問題 5.47.
まず修正前にテストしてみる。
翻訳した手続きfを翻訳した手続きgを呼び出す手続きとして、その後、手続きgを評価器で入力して定義しなおして、それぞれ手続きfを呼び出してみる。
コード(BBEdit)
sample.scm
(compile-and-go '(begin (define (f n) (+ (g n) 1)) (define (g n) (* n 10))))
入出力結果(Terminal, REPL(Read, Eval, Print, Loop))
$ scheme MIT/GNU Scheme running under MacOSX Type `^C' (control-C) followed by `H' to obtain information about interrupts. Copyright (C) 2011 Massachusetts Institute of Technology This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Image saved on Saturday October 26, 2013 at 11:02:50 PM Release 9.1.1 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/C 4.118 Edwin 3.116 1 ]=> (load "./eceval.scm") ;Loading "./eceval.scm"... done ;Value: start-eceval 1 ]=> (load "./sample.scm") ;Loading "./sample.scm"... (total-pushes = 0 maximum-depth = 0) ;;; EC-Eval value: ok ;;; EC-Eval input: f (total-pushes = 0 maximum-depth = 0) ;;; EC-Eval value: <compiled-procedure> ;;; EC-Eval input: g (total-pushes = 0 maximum-depth = 0) ;;; EC-Eval value: <compiled-procedure> ;;; EC-Eval input: (f 1) (total-pushes = 8 maximum-depth = 3) ;;; EC-Eval value: 11 ;;; EC-Eval input: (define (g n) (* n 20)) (total-pushes = 3 maximum-depth = 3) ;;; EC-Eval value: ok ;;; EC-Eval input: f (total-pushes = 0 maximum-depth = 0) ;;; EC-Eval value: <compiled-procedure> ;;; EC-Eval input: g (total-pushes = 0 maximum-depth = 0) ;;; EC-Eval value: (compound-procedure (n) ((* n 20)) <procedure-env>) ;;; EC-Eval input: (f 1) ;The object n, passed as the first argument to cdr, is not the correct type. ;To continue, call RESTART with an option number: ; (RESTART 2) => Specify an argument to use in its place. ; (RESTART 1) => Return to read-eval-print level 1. 2 error> ^D End of input stream reached. Moriturus te saluto. $
手続きgを評価器で入力して定義した場合はエラーになる。問題は、この、評価器で入力して定義した解釈させる手続きgも同様に呼び出せるように翻訳系を修正すること。
追加、修正箇所。
コード(BBEdit)
;; …
(define eceval
(make-machine
'(exp env val proc argl continue unev compapp)
eceval-operations
'(
(assign compapp (label compound-apply))
(branch (label external-entry))
read-eval-print-loop
;; …
;;
(define (compile-procedure-call target linkage)
;; …
(append-instruction-sequences
(make-instruction-sequence '(proc) '()
`((test (op primitive-procedure?) (reg proc))
(branch (label ,primitive-branch))))
(make-instruction-sequence '(proc) '()
`((test (op compiled-procedure?) (reg proc))
(branch (label ,compiled-branch))))
(parallel-instruction-sequences
(cond ((and (eq? target 'val) (not (eq? compiled-linkage 'return)))
(make-instruction-sequence '(proc) all-regs
`((assign continue (label ,compiled-linkage))
(save continue)
(goto (reg compapp)))))
((and (not (eq? target 'val))
(not (eq? compiled-linkage 'return)))
(let ((proc-return (make-label 'proc-return)))
(make-instruction-sequence '(proc) all-regs
`((assign continue (label ,proc-return))
(save continue)
(goto (reg compapp))
,proc-return
(assign ,target (reg val))
(goto (label ,compiled-linkage))))))
((and (eq? target 'val) (eq? compiled-linkage 'return))
(make-instruction-sequence '(proc continue) all-regs
'((save continue)
(goto (reg compapp)))))
((and (not (eq? target 'val)) (eq? compiled-linkage 'return))
(error
"PARALLEL-INSTRUCTION-SEQUENCES -- COMPILE-PROCEDURE-CALL"
target linkage)))
(parallel-instruction-sequences
(append-instruction-sequences
compiled-branch
(compile-proc-appl target compiled-linkage))
(append-instruction-sequences
primitive-branch
(end-with-linkage linkage
(make-instruction-sequence '(proc argl)
(list target)
`((assign ,target
(op apply-primitive-procedure)
(reg proc)
(reg argl))))))))
after-call))))
;; …
入出力結果(Terminal, REPL(Read, Eval, Print, Loop))
$ scheme MIT/GNU Scheme running under MacOSX Type `^C' (control-C) followed by `H' to obtain information about interrupts. Copyright (C) 2011 Massachusetts Institute of Technology This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Image saved on Saturday October 26, 2013 at 11:02:50 PM Release 9.1.1 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/C 4.118 Edwin 3.116 1 ]=> (load "./eceval.scm") ;Loading "./eceval.scm"... done ;Value: start-eceval ;Loading "./sample.scm"... (total-pushes = 0 maximum-depth = 0) ;;; EC-Eval value: ok ;;; EC-Eval input: (f 1) (total-pushes = 8 maximum-depth = 3) ;;; EC-Eval value: 11 ;;; EC-Eval input: f (total-pushes = 0 maximum-depth = 0) ;;; EC-Eval value: <compiled-procedure> ;;; EC-Eval input: g (total-pushes = 0 maximum-depth = 0) ;;; EC-Eval value: <compiled-procedure> ;;; EC-Eval input: (define (g n) (* n 20)) (total-pushes = 3 maximum-depth = 3) ;;; EC-Eval value: ok ;;; EC-Eval input: f (total-pushes = 0 maximum-depth = 0) ;;; EC-Eval value: <compiled-procedure> ;;; EC-Eval input: g (total-pushes = 0 maximum-depth = 0) ;;; EC-Eval value: (compound-procedure (n) ((* n 20)) <procedure-env>) ;;; EC-Eval input: (f 1) (total-pushes = 17 maximum-depth = 8) ;;; EC-Eval value: 21 ;;; EC-Eval input: End of input stream reached. Moriturus te saluto. $
評価器で入力して定義した解釈された手続きgを、翻訳した手続きfから呼び出すことが出来るようになった。
0 コメント:
コメントを投稿