SICP 読み (251) 5.2 レジスタ計算機での計算

今日も宿酔。

問題 5.4

(define expt-machine
  (make-machine
   '(n continue b val)
   (list (list '= =) (list '- -) (list '* *))
   '(controller
     (assign continue (label expt-done))
     expt-loop
     (test (op =) (reg n) (const 0))
     (branch (label base-case))
     (save continue)
     (save n)
     (assign n (op -) (reg n) (const 1))
     (assign continue (label after-expt))
     (goto (label expt-loop))
     after-expt
     (restore n)
     (restore continue)
     (assign val (op *) (reg b) (reg val))
     (goto (reg continue))
     base-case
     (assign val (const 1))
     (goto (reg continue))
     expt-done)))

で良いのかなぁ。チェック抜きで評価器に吸わせてみる。

gosh> (add-load-path ".")
("." "/usr/share/gauche/site/lib" "/usr/share/gauche/0.8.7/lib")
gosh> (load "ch5-regsim.scm")
#t
gosh> (define expt-machine
  (make-machine
   '(n continue b val)
   (list (list '= =) (list '- -) (list '* *))
   '(controller
     (assign continue (label expt-done))
     expt-loop
     (test (op =) (reg n) (const 0))
     (branch (label base-case))
     (save continue)
     (save n)
     (assign n (op -) (reg n) (const 1))
     (assign continue (label after-expt))
     (goto (label expt-loop))
     after-expt
     (restore n)
     (restore continue)
     (assign val (op *) (reg b) (reg val))
     (goto (reg continue))
     base-case
     (assign val (const 1))
     (goto (reg continue))
     expt-done)))
expt-machine
gosh> (set-register-contents! expt-machine 'b 2)   
done
gosh> (set-register-contents! expt-machine 'n 5) 
done
gosh> (start expt-machine)
done
gosh> (get-register-contents expt-machine 'val)
32
gosh> (set-register-contents! expt-machine 'n 10)
done
gosh> (start expt-machine)
done
gosh> (get-register-contents expt-machine 'val)
1024
gosh>

を、動いとるな。よしよし。次は b.です。

(define expt-repeat-machine
  (make-machine
   '(n c b p)
   (list (list '= =) (list '- -) (list '* *))
   '(controller
     (assign c (reg n))
     (assign p (const 1))
     test-b
     (test (op =) (reg c) (const 0))
     (branch (label expt-done))
     (assign c (op -) (reg c) (const 1))
     (assign p (op *) (reg b) (reg p))
     (goto (label test-b))
     expt-done)))

を評価器に (const を count とミスタイプしてるナニが多い

gosh> (define expt-repeat-machine
  (make-machine
   '(n c b p)
   (list (list '= =) (list '- -) (list '* *))
   '(controller
     (assign c (reg n))
     (assign p (const 1))
     test-b
     (test (op =) (reg c) (const 0))
     (branch (label expt-done))
     (assign c (op -) (reg c) (const 1))
     (assign p (op *) (reg b) (reg p))
     (goto (label test-b))
     expt-done)))
expt-repeat-machine
gosh> (set-register-contents! expt-repeat-machine 'b 2)
done
gosh> (set-register-contents! expt-repeat-machine 'n 10)
done
gosh> (start expt-repeat-machine)
done
gosh> (get-register-contents expt-repeat-machine 'p)
1024
gosh> 

5.5 と 5.6 は確認スルーとして、次の問題を検討予定。
# もしかすると試してみるかも、ですが。