Geek-Side

Resource > SICP Exersise 4_5

Exercise 4.5:
 (define (cond-clauses exp) (cdr exp))
 (define (cond-else-clause? clause)
   (eq? (cond-predicate clause) 'else))
 (define (cond-predicate clause) (car clause))
 (define (cond-actions clause) (cdr clause))
 (define (cond->if exp)
   (expand-clauses (cond-clauses exp)))
 ;; clauses は 'cond を除いた条件文-アクションが並ぶ
 (define (expand-clauses clauses)
   (if (null? clauses)
       'false                          ; no `else' clause
       ;; firstは一つ目の条件文とアクション
       (let ((first (car clauses))
 	    (rest (cdr clauses)))
 	(if (cond-else-clause? first)
 	    (if (null? rest)
 		(sequence->exp (cond-actions first))
 		(error "ELSE clause isn't last -- COND->IF"
 		       clauses))
 	    (make-if (cond-predicate first)
 		     ;; 条件文の結果を sequence->expに渡す
 		     (sequence->exp (cond-predicate first) (cond-actions first))
 		     (expand-clauses rest))))))
 (define (make-if predicate consequent alternative)
   (list 'if predicate consequent alternative))
 
 (define (sequence->exp value seq)
   (cond ((null? seq) seq)
 	((last-exp? seq) (first-exp seq))
 	;; =>の場合はvalueを引数として手続きに渡す
 	((equal? '=> (first-exp seq)) (list (cadr seq) value))
 	(else (make-begin seq))))
 (define (last-exp? seq) (null? (cdr seq)))
 (define (first-exp seq) (car seq))
 (define (make-begin seq) (cons 'begin seq))
 (put 'eval 'cond (lambda(exp env) (eval (cond->if exp) env)))