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 も見てみた方が良さげ。とりあえず疲労困憊なので実装は別途。