SICP 読み (300) 5.4 積極制御評価器

体調悪い。どこでどうすりゃ良いのか、は何となくイメージできてるんですが、具体的にどうすれば、な部分で思考が止まる。疲れてるのかな。

問題 5.30 の a.

エラーです、という意味の **error** な文字列を特別な条件コードって事にする。なので、ch5-eceval-support.scm の extend-environment と lookup-variable-value と set-variable-value! はそれぞれ以下の形に変更。
あ、駄目だ。extend-environment は違うソレだな。面倒臭いから以下に。

(define (extend-environment vars vals base-env)
  (if (= (length vars) (length vals))
      (cons (make-frame vars vals) base-env)
      (if (< (length vars) (length vals))
	  'too-many-arguments
	  'too-few-arguments

(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)
	'unbound-variable
        (let ((frame (first-frame env)))
          (scan (frame-variables frame)
                (frame-values frame)))))
  (env-loop env))

(define (set-variable-value! var val env)
  (define (env-loop env)
    (define (scan vars vals)
      (cond ((null? vars)
             (env-loop (enclosing-environment env)))
            ((eq? var (car vars))
             (set-car! vals val))
            (else (scan (cdr vars) (cdr vals)))))
    (if (eq? env the-empty-environment)
	'unbound-variable
        (let ((frame (first-frame env)))
          (scan (frame-variables frame)
                (frame-values frame)))))
  (env-loop env))

で、ch5-eceval.scm の ev-variable が以下

ev-variable
  (assign val (op lookup-variable-value) (reg exp) (reg env))
  (test (op eq?) (reg val) (const unbound-variable))
  (branche (label unbound-variable-error))
  (goto (reg continue))

compound-apply は以下

compound-apply
  (assign unev (op procedure-parameters) (reg proc))
  (assign env (op procedure-environment) (reg proc))
  (assign env (op extend-environment)
              (reg unev) (reg argl) (reg env))
  (test (op eq?) (reg env) (const too-many-arguments))
  (branch (label too-many-arguments-error))
  (test (op eq?) (reg env) (const too-few-arguments))
  (branch (label too-few-arguments-error))
  (assign unev (op procedure-body) (reg proc))
  (goto (label ev-sequence))

あとは ev-assignment-1

ev-assignment-1
  (restore continue)
  (restore env)
  (restore unev)
  (perform
   (op set-variable-value!) (reg unev) (reg val) (reg env))
  (test (op eq?) (reg val) (const unbound-variable))
  (branch (label unbound-variable-error))
  (assign val (const ok))
  (goto (reg continue))

で、エラー処理を追加

unbound-variable-error
  (assign val (const unbound-variable))
  (goto (label signal-error))
too-many-arguments-error
  (assign val (const too-many-arguments))
  (goto (label signal-error))
too-few-arguments-error
  (assign val (const too-few-arguments))
  (goto (label signal-error))

微妙杉。ちょっとここ、スルー気味でヤッツケてラストに進んだ方が精神的に楽かも。(何

問題 5.30 の b.

こちら方面にも修正は盛り込む必要あり。

primitive-apply
  (assign val (op apply-primitive-procedure)
              (reg proc)
              (reg argl))
  (restore continue)
  (goto (reg continue))

val がエラーな条件コードだったら云々、になるのかなぁ。こんな感じにできれば幸せ??

primitive-apply
  (assign val (op apply-primitive-procedure)
              (reg proc)
              (reg argl))
  (test (op eq?) (reg val) (const pair-required))
  (branch (label signal-error))
  (restore continue)
  (goto (reg continue))

あるいは ch5-eceval-support.scm の

(define (apply-primitive-procedure proc args)
  (apply-in-underlying-scheme
   (primitive-implementation proc) args))

で args は proc の要件を満たした引数になってるかどうかを確認した上で云々、なのか

(define (apply-primitive-procedure proc args)
  (let ((ret (check-args (primitive-implementation proc) args)))
    (if (null? ret)
	(apply-in-underlying-scheme
	 (primitive-implementation proc) args)
	(car ret))))

むぎゃー。微妙。駄目だ絶不調。しかも check-args って手続き受け取っても名前が分からねぇ。わはははは。(死亡

案 1

primitive なソレを (primitive 手続きの名前 手続き本体) な形で持つ。

(define (primitive-procedure-objects)
  (map (lambda (proc) (list 'primitive (car proc) (cadr proc)))
       primitive-procedures))
(define (primitive-implementation proc) (caddr proc))

そーすれば名前 (cadr にある) を元に引数をチェック可能。