さかもとのブログ

つらつらと

SICP演習問題5.15

命令の回数を数える問題.
変更点

  1. make-new-machineに変数instruct-countを追加
  2. (define (instruct-count-up) (inc! instruct-count))をmake-new-machineに追加
  3. make-new-machineのexecuteに(instruct-count-up)を追加
  4. (define (print-instruct-count) (print "instruct-count: " instruct-count) (set! instruct-count 0))をmake-new-machineに追加
  5. dispatchに[(eq? message 'print-inst-count) (print-instruct-count)]を追加
  6. (define (print-inst-count machine) (machine 'print-inst-count))を追加
実行
(define (fact-print-stack n)
  (define fact-machine
  (make-machine
   '(n val continue)
   (list (list '= =) (list '- -) (list '* *))
   '(fact
       (assign continue (label fact-done))
     fact-loop
       (test (op =) (reg n) (const 1))
       (branch (label base-case))
       (save continue)
       (save n)
       (assign n (op -) (reg n) (const 1))
       (assign continue (label after-fact))
       (goto (label fact-loop))
     after-fact
       (restore n)
       (restore continue)
       (assign val (op *) (reg n) (reg val))
       (goto (reg continue))
     base-case
       (assign val (const 1))
       (goto (reg continue))
     fact-done)))
  (newline)
  (let loop ((count 1))
    (if (> count n)
        'done
        (begin
          ((fact-machine 'stack) 'initialize)
          (set-register-contents! fact-machine 'n count)
          (start fact-machine)
          (format #t "fact(~2d):~8d\n" count (get-register-contents fact-machine 'val))
          (print-stack fact-machine)
          (print-inst-count fact-machine)
          (newline)
          (loop (+ count 1))))))
(fact-print-stack 5)
結果
gosh>
fact( 1):       1
(total-pushes = 0 maximum-depth = 0)
instruction-count: 5

fact( 2):       2
(total-pushes = 2 maximum-depth = 2)
instruction-count: 16

fact( 3):       6
(total-pushes = 4 maximum-depth = 4)
instruction-count: 27

fact( 4):      24
(total-pushes = 6 maximum-depth = 6)
instruction-count: 38

fact( 5):     120
(total-pushes = 8 maximum-depth = 8)
instruction-count: 49

done