SICP 読み (369) 5.5 翻訳系
問題 5.50
とりあえず前のエントリの修正を盛り込んで不具合対応予定。
あと、
- set-breakpoint
- proceed-machine
- cancel-breakpoint
- cancel-all-breakpoints
も。冗長ですが同じ試験に以下を挿入。
(cancel-all-breakpoints m) (test* "breakpoints register is ()" '() (get-contents ((m 'get-register) 'breakpoints))) (set-breakpoint m 'test-b 1) (test* "breakpoints register is ((test-b 1))" '((test-b 1)) (get-contents ((m 'get-register) 'breakpoints))) (set-breakpoint m 'test-b 2) (test* "breakpoints register is ((test-b 2) (test-b 1))" '((test-b 2) (test-b 1)) (get-contents ((m 'get-register) 'breakpoints))) (set-register-contents! m 'a 206) (set-register-contents! m 'b 40) (test* "stop (test-b 1)" '(break test-b 1) (start m)) (test* "stop (test-b 2)" '(break test-b 2) (proceed-machine m))
あと、make-assign な試験に以下を追加。
;; (assign b (op rem) (reg a) (label gcd-done)) ?? (let ((ope (make-assign '(assign a (op make-compiled-procedure) (label entry1) (reg env)) m '((entry1 ())) (m 'operations) ((m 'get-register) 'pc)))) (set-contents! ((m 'get-register) 'pc) '(() (gcd-done ()))) (set-contents! ((m 'get-register) 'env) '()) (ope) (test* "value of register a" '(compiled-procedure (()) ()) (get-contents ((m 'get-register) 'a))) )
うーん ... 醜い。
とりあえず、順に unbound variable なソレ達をツブしていこう。でも何をドコに、なんだったっけか。盛り込むのは ch5-eceval-compiler.scm の eceval-operation か。
なんか違うクサい。
(assign proc (op lookup-variable-value) (const cdddr) (reg env))
な式の (const cdddr) な lookup に失敗している模様。eceval-operation は (op なんたら) の cadr を解決するためのはず、かなぁ。const なソレはどうやってるんだったか。
(define (make-primitive-exp exp machine labels) (cond ((constant-exp? exp) (let ((c (constant-exp-value exp))) (lambda () c)))
assembler が戻すのは ch5-regsim の上記の部分だと思うんですが、戻る lambda 式を実際に評価するのは誰だ。
あ、そうか lookup の対象 (と言えば良いのか) は環境か。setup-environment を定義しているのは ch5-eceval-support.scm ですな。ここの primitive-procedure に追加すれば良いのかな。
良いみたいですが、次は caddr との事。で順に以下を盛り込んで
- cdddr
- caddr
- cddr
- cadr
- assoc
- min
- max
- even?
- odd?
- negative?
- positive?
- zero?
- >=
- <=
- integer?
- rational?
- real?
- complex?
- number?
- equal?
- eq?
- eqv?
再度原因不明の異常終了。とゆーのもスクロールバーでめくれる幅を越えてメセジが出力されているので、と思われる。仕方が無いので
(add-load-path ".") (load "load-eceval-compiler") (load "ch5-compiler") (load "objectCode.txt") (define true #t) (define false #f) (set! the-global-environment (setup-environment)) (set-register-contents! eceval 'val (assemble objectCode eceval)) (set-register-contents! eceval 'flag true) ;; insert debugger instruction ;;(set-breakpoint eceval 'entry0 1) (start eceval)
なスクリプトで
$ gosh load-5.50.scm 2>err.log
で見てみた。
*** ERROR: invalid application: (略) Stack Trace: _______________________________________ 0 args 1 (map (lambda (p) (p)) aprocs) At line 500 of "./ch5-regsim.scm" 2 value-proc 3 (set-contents! target (value-proc)) At line 371 of "./ch5-regsim.scm" 4 (instruction-execution-proc (car insts)) At line 192 of "./ch5-regsim.scm"
との事。ちなみに先頭部分が
((compiled-procedure ((((entry1337 1) assign env (op compiled-procedure-env) (reg proc)) . #<closure (make-assign make-assign)>)
みたいな感じ。これは make-compiled-procedure が作るリストだなぁ。あ、違うぞ。make-compiled- が作るリストを () で囲んで eval しようとしてるクサい。うーん。とりあえずな切り口としてはラベルか。
てコトで compile 済みなリストの entry1337 周辺を見てみると以下
after-lambda1331 (perform (op define-variable!) (const primitive-procedure-names) (reg val) (reg env)) (assign val (const ok)) (assign val (op make-compiled-procedure) (label entry1335) (reg env)) (goto (label after-lambda1336)) entry1335 (assign env (op compiled-procedure-env) (reg proc)) (assign env (op extend-environment) (const ()) (reg argl) (reg env)) (assign proc (op lookup-variable-value) (const map) (reg env)) (assign val (op lookup-variable-value) (const primitive-procedures) (reg env)) (assign argl (op list) (reg val)) (assign val (op make-compiled-procedure) (label entry1337) (reg env)) (goto (label after-lambda1338)) entry1337 (assign env (op compiled-procedure-env) (reg proc)) (assign env (op extend-environment) (const (proc)) (reg argl) (reg env)) (assign proc (op lookup-variable-value) (const list) (reg env))
うーん。こっち見ても駄目そげ。現時点で何が悪いのか、が全然イメージできてません。明日、見るナニがあれば再度検証予定ってコトで寝ます。