2014年1月11日土曜日

開発環境

計算機プログラムの構造と解釈(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 コメント:

コメントを投稿