SICP 読み (299) 5.4 積極制御評価器
問題 5.30
結構面倒クサそうだなと思いつつ allcode なソースを見たら以下の手続きがスデに記述されているのを発見。これってズルっぽいなぁ。(とほほ
unknown-expression-type (assign val (const unknown-expression-type-error)) (goto (label signal-error)) unknown-procedure-type (restore continue) (assign val (const unknown-procedure-type-error)) (goto (label signal-error)) signal-error (perform (op user-print) (reg val)) (goto (label read-eval-print-loop))
テキストにも多分出てねぇ。てーか unknown-procedure-type は b.向けなモノと見て良さげだなぁ。ざくっと検討下書きを以下に。
- lookup-variable-value の修正
(define (lookup-variable-value var env) (define (env-loop env) (define (scan vars vals) (cond ((null? vars) (env-loop (enclosing-environment env))) ((eq? var (car vars)) (car vals)) (else (scan (cdr vars) (cdr vals))))) (if (eq? env the-empty-environment) (error "Unbound variable" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env))
error じゃなく何か戻さなきゃ、なんですがどうしたものか。ただ問題の文章にあるように_特別な条件コードを返すようにすれば捕えることが出来る_んですけど ev-variable でやっつけてしまっては駄目なのかなぁ。
ev-variable (assign val (op lookup-variable-value) (reg exp) (reg env)) (test (op eq?) (reg val) (const **error**)) (branch (label unknown-expression-type)) (goto (reg continue))
駄目な理由を別途考えてみます。駄目かも、と思っている要因としては問題の文章の_変更が必要な場所をすべて見つけ_という記述によります。むむむ。
む
unknown-expression-type とか unknown-procedure-type はテキストに書いてあった。eval-dispatch とか apply-dispatch で使用されている。新たなソレを作らんと駄目か。
lookup なエラーを捕まえれば良いのだったら
unbound-variable (assign val (const unbound-variable)) (goto (label signal-error))
みたいな手続きを定義して上記の ev-variable で良いのか。あるいは gosh みたいに
unbound variable: x
な出力を、というナニは可能かどうか。これはスルーとしても、足りてるのかどうなのか、も含め動作を確認してみる。
って、この設問は lookup 以外に発生し得るエラーを捕捉せぇ、という事なのかなぁ。error で grep してみたら以下の出力が。
ch5-syntax.scm: (error "ELSE clause isn't last -- COND->IF" ch5-eceval-support.scm: (error "Too many arguments supplied" vars vals) ch5-eceval-support.scm: (error "Too few arguments supplied" vars vals)))) ch5-eceval-support.scm:; (error "Unbound variable" var) ch5-eceval-support.scm: '***error*** ch5-eceval-support.scm: (error "Unbound variable -- SET!" var)
む。set! でもヤッてましたか。あるいは extend-environment でもナニしとります。cond->if はスルーとしても
- compound-apply
- ev-assignment-1
な手続きと上記の手続きに手を入れればなんとかなるか。あるいは b.の設問については、
(define primitive-procedures (list (list 'car car) (list 'cdr cdr) (list 'cons cons) (list 'null? null?) ;;above from book -- here are some more (list '+ +) (list '- -) (list '* *) (list '= =) (list '/ /) (list '> >) (list '< <) ))
にある基本手続きについて以下なチェキを入れれば良いのか??
- car と cdr にはリストを一つ渡す
- cons な引数は二つ
- = な引数は二つ以上
- / は 0 div しないこと
- > と < は引数二つ
なんか微妙。R5RS も見てみた方が良さげ。とりあえず疲労困憊なので実装は別途。