exercise-9.scm (3014B)
1 (define-library (sicp solutions chapter-4 exercise-9) 2 (import (scheme base) 3 (ice-9 match)) 4 5 (begin 6 (define (eval exp env) 7 (cond ((self-evaluating? exp) exp) 8 ((variable? exp) (lookup-variable-value exp env)) 9 ((quoted? exp) (text-of-quotation exp)) 10 ((assignment? exp) (eval-assignment exp env)) 11 ((definition? exp) (eval-definition exp env)) 12 ((if? exp) (eval-if exp env)) 13 ((lambda? exp) 14 (make-procedure (lambda-parameters exp) 15 (lambda-body exp) 16 env)) 17 ((begin? exp) 18 (eval-sequence (begin-actions exp) env)) 19 ((cond? exp) (eval (cond->if exp) env)) 20 ((let*? exp) (eval (let*->combination exp) env)) 21 ((application? exp) 22 (apply (eval (operator exp) env) 23 (list-of-values (operands exp) env))) 24 (else 25 (error "Unknown expression type -- EVAL" exp)))) 26 27 (define (let*? exp) (eqv? (car exp) 'let*)) 28 29 (let*->combination '(let* () a b c)) 30 (let*->combination '(let* ((a (b)) (c (d))) 1)) 31 32 (define (let*->combination exp) 33 (match exp 34 (`(let* () ,first-code-expression . ,rest-of-code-expressions) 35 `(begin ,first-code-expression 36 ,@rest-of-code-expressions)) 37 (`(let* ((,variable-name ,variable-expression)) 38 ,first-code-expression . ,rest-of-code-expressions) 39 `((lambda (,variable-name) 40 ,first-code-expression 41 ,@rest-of-code-expressions) 42 ,variable-expression)) 43 (`(let* ((,variable-name ,variable-expression) . ,rest-of-variables) 44 ,first-code-expression . ,rest-of-code-expressions) 45 (let ((inner 46 (let*->combination `(let* ,rest-of-variables 47 ,first-code-expression 48 ,@rest-of-code-expressions)))) 49 `((lambda (,variable-name) 50 ,inner) 51 ,variable-expression))))) 52 53 (let*->nested-lets '(let* () a b c)) 54 (let*->nested-lets '(let* ((a (b)) (c (d))) 1 2 3)) 55 56 (define (let*->nested-lets exp) 57 (match exp 58 (`(let* () ,first-code-expression . ,rest-of-code-expressions) 59 `(begin ,first-code-expression 60 ,@rest-of-code-expressions)) 61 (`(let* ((,variable-name ,variable-expression)) 62 ,first-code-expression . ,rest-of-code-expressions) 63 `(let ((,variable-name ,variable-expression)) 64 ,first-code-expression 65 ,@rest-of-code-expressions)) 66 (`(let* ((,variable-name ,variable-expression) . ,rest-of-variables) 67 ,first-code-expression . ,rest-of-code-expressions) 68 `(let ((,variable-name ,variable-expression)) 69 ,(let*->nested-lets 70 `(let* ,rest-of-variables 71 ,first-code-expression 72 ,@rest-of-code-expressions))))))))