SICP 読み (263) 5.2 レジスタ計算機での計算
検証を、と言いつつ次の問題に着手してしまう。
問題 5.13
試験を考えてみたら、既存の試験とほぼ同様なソレがでっち上がった。
(use gauche.test) (add-load-path ".") (load "ch5-regsim") (test-start "5.13") (test-section "assign") (let ((m (make-machine (list (list 'rem remainder) (list '= =)) '(test-b (test (op =) (reg b) (const 0)) (branch (label gcd-done)) (assign t (op rem) (reg a) (reg b)) (assign a (reg b)) (assign b (reg t)) (goto (label test-b)) gcd-done)))) (test* "register a exist" '*unassigned* (get-register-contents m 'a)) (test* "register b exist" '*unassigned* (get-register-contents m 'b)) (test* "register t exist" '*unassigned* (get-register-contents m 't)) (set-register-contents! m 'a 206) (set-register-contents! m 'b 40) (test* "a" 206 (get-register-contents m 'a)) (test* "b" 40 (get-register-contents m 'b)) (start m) (test* "a" 2 (get-register-contents m 'a)) ) (test-end)
これは既存な試験の修正が必要だなぁ。ってこれ、machine に lookup-register ってメセジ送信した時に machine 側で失敗したら allocate すりゃ良いだけの話??
(define (lookup-register name) (let ((val (assoc name register-table))) (if val (cadr val) (set! register-table (cons (list name (make-register name)) register-table)))))
こりゃ無いかなぁ。って val 戻せてないし。
(define (lookup-register name) (let ((val (assoc name register-table))) (if val (cadr val) (let ((val (make-register name))) (set! register-table (cons (list name val) register-table)) (cadr val)))))
こうか。なんか微妙。
追記
む。間違えてた。上記の試験をしてみたら
*** ERROR: pair required, but got #<closure (make-register dispatch)>
と叱られる。よく見ると else なブロックの val はリストじゃないじゃん。正しくは以下でしょうか。
(define (lookup-register name) (let ((val (assoc name register-table))) (if val (cadr val) (let ((val (make-register name))) (set! register-table (cons (list name val) register-table)) val))))
一応これで上記の試験にはパスしておりますが ...
さらに追記
既存な試験にも手を入れてみました。
- allocate-register の削除
- undefined register な試験の削除
削除しちゃって良いのだろうか、と言いつつ全部コメントアウト。試験にもパスしていますが、こんなに簡単に終了しちゃって良いのだろうか。