SICP問題4.4

2010/03/17 evalでlookup-variable-valueのトコが間違ってたので修正

  • and: 式を左から右へ評価する。ある式が偽に評価されたら偽を返す;残りの式は評価しない。全ての式が真に評価されたら、最後の式の値を返す。式が一つもなければ真を返す
  • or: 式を左から右へと評価する。ある式が真に評価されたらその値を返す;残りの式は評価しない。全ての式が偽に評価されるか、式が一つもなければ偽を返す

eval-and と eval-or を作り、andとorを評価器の新しい特殊形式として組み込む

eval-andの定義

(define (and? exp)
  (tagged-list? exp 'and))
(define (and-clauses exp) (cdr exp))
(define (eval-and exp env)
  (define (iter rest result)
    (if (null? rest)
        result
        (let ((first-eval (eval (car rest) env)))
          (if (true? first-eval)
              (iter (cdr rest) first-eval)
              #f))))
  (iter (and-clauses exp) #t))

eval-orの定義

(define (or? exp)
  (tagged-list? exp 'or))
(define (or-clauses exp) (cdr exp))
(define (eval-or exp env)
  (define (iter rest result)
    (if (null? rest)
        result
        (let ((first-eval (eval (car rest) env)))
          (if (true? first-eval)
              #t
              (iter (cdr rest) first-eval)))))
  (iter (or-clauses exp) #f))

(データ主導型でない)evalへの組み込み

(define (eval exp env)
  (cond ((self-evaluating? exp) exp)
        ((variable? exp) (lookup-variable-value exp env))
        ((quoted? exp) (text-of-quotation exp))
        ((assignment? exp) (eval-assignment exp env))
        ((definition? exp) (eval-definition exp env))
        ((if? exp) (eval-if exp env))
        ((lambda? exp)
         (make-procedure (lambda-parameters exp)
                         (lambda-body exp)
                         env))
        ((begin? exp)
         (eval-sequence (begin-actions exp) env))
        ((cond? exp) (eval (cond->if exp) env))
        ((and? exp) (eval-and exp env)) ; 追加
        ((or? exp) (eval-or exp env))   ; 追加
        ((application? exp)
         (apply (eval (operator exp) env)
                (list-of-values (operands exp) env)))
        (else
         (error "Unknown expression type -- EVAL" exp))))