(wat-aro)

無職から有職者にランクアップしました

SICP 問題 5.49

compileとassembleを機械計算として持ち,REPLを行うレジスタ計算機を設計する.
 
はじめ,assembleを命令列の上でやる方法がわからずに,compile-and-assembleという手続きを作り,
それを機械演算として登録してRCEPLを実装したが,

問題5.49 – SICP(計算機プログラムの構造と解釈)その301 : Serendip - Webデザイン・プログラミング

ここでそれをうまく回避していたので真似た.

(load "./eval.scm")
(load "./compiler.scm")
(load "./register-machine-simulator.scm")
(load "./eceval.scm")

(define (rcepl) RCEPL)

(define rcepl-proc
  (append eceval-procedure
          (list (list 'compile compile))
          (list (list 'assemble assemble))
          (list (list 'rcepl rcepl))
          (list (list 'statements statements))))

(define RCEPL
  (make-machine
   rcepl-proc
   '((assign machine (op rcepl)) ;直接RCEPLを指せないので
     read-compile-execute-print-loop
     (perform (op initialize-stack))
     (perform (op prompt-for-input) (const ";;;EC-COMP input:"))
     (assign exp (op read))
     (assign env (op get-global-environment))
     (assign continue (label print-result))
     (goto (label read-compile-execute))

     print-result
     (perform (op print-stack-statistics))
     (perform (op announce-output) (const ";;;EC-COMP value":))
     (perform (op user-print) (reg val))
     (goto (label read-compile-execute-print-loop))

     read-compile-execute
     (assign val (op compile) (reg exp) (const val) (const return) (const ()))
     (assign exp (op statements) (reg val))
     (assign val (op assemble) (reg exp) (reg machine))
     (goto (reg val)))))

(define (start-rcepl)
  (set! the-global-environment (setup-environment))
  (start RCEPL))

 
test

gosh> (start-rcepl)


;;;EC-COMP input:
      (define (factorial n)
        (if (< n 2)
            n
            (* (factorial (- n 1)) n)))

(total-pushes = 0 maximum-depth = 0)
;;;EC-COMP value
ok

;;;EC-COMP input:
(factorial 20)

(total-pushes = 78 maximum-depth = 40)
;;;EC-COMP value
2432902008176640000