Implement 4.8

main
Felix Martin 2021-01-18 08:19:32 -05:00
parent dd2002783e
commit 23a8766b45
1 changed files with 49 additions and 12 deletions

View File

@ -51,7 +51,7 @@
env)))
(put 'begin (lambda (exp env) (eval-sequence (begin-actions exp) env)))
(put 'cond (lambda (exp env) (eval (cond->if exp) env)))
(put 'let (lambda (exp env) (eval (let->lambda exp) env)))
(put 'let (lambda (exp env) (eval (let->combination exp) env)))
(put 'let* (lambda (exp env) (eval (let*->nested-lets exp) env)))
(put 'and (lambda (exp env) (eval-and (clauses exp) env)))
(put 'or (lambda (exp env) (eval-or (clauses exp) env)))
@ -122,7 +122,7 @@
clauses)))
((cond-test-recipient-clause? first)
(let ((test-evaluated (eval (cond-test exp) env)))
(if test-evaluated
(if (true? test-evaluated)
(eval (list (cond-recipient exp) test-evaluated) env)
(expand-clauses rest))))
(else
@ -135,20 +135,20 @@
(display "\nex-4.6 - let\n")
(define (let? exp) (tagged-list exp 'let))
(define (let-init exp) (cadr exp))
(define (let-bindings exp) (cadr exp))
(define (let-body exp) (cddr exp))
(define (let-init-var init) (car init))
(define (let-init-exp init) (cadr init))
(define (let-init-vars exp) (map let-init-var (let-init exp)))
(define (let-init-exps exp) (map let-init-exp (let-init exp)))
(define (let-binding-var binding) (car binding))
(define (let-binding-exp binding) (cadr binding))
(define (let-vars exp) (map let-binding-var (let-bindings exp)))
(define (let-exps exp) (map let-binding-exp (let-bindings exp)))
(define (let->lambda exp)
(let ((let-variables (let-init-vars exp))
(let-expressions (let-init-exps exp)))
(define (let->combination exp)
(let ((let-variables (let-vars exp))
(let-expressions (let-exps exp)))
(cons (make-lambda let-variables (let-body exp))
let-expressions)))
(assert (let->lambda '(let ((a 3) (b 4)) (* 3 a b)))
(assert (let->combination '(let ((a 3) (b 4)) (* 3 a b)))
'((lambda (a b) (* 3 a b)) 3 4))
(display "\nex-4.7 - let*\n")
@ -173,8 +173,45 @@
(assert (let*->nested-lets '(let* ((x 1) (y 2)) (* x y) (+ x y)))
'(let ((x 1)) (let ((y 2)) (begin (* x y) (+ x y)))))
(display "\nex-4.8 - named-let\n")
(define (simple-let? exp) (pair? (let-bindings exp)))
(define (named-let? exp) (symbol? (let-bindings exp)))
(define (named-let-var exp) (cadr exp))
(define (named-let-bindings exp) (caddr exp))
(display "\nex-4.9\n")
(define (named-let-var exp) (cadr exp))
(define (named-let-bindings exp) (caddr exp))
(define (named-let-body exp) (cdddr exp))
(define (named-let-vars exp) (map let-binding-var (named-let-bindings exp)))
(define (named-let-exps exp) (map let-binding-exp (named-let-bindings exp)))
(define (let->combination exp)
(cond
((simple-let? exp)
(let ((let-variables (let-vars exp))
(let-expressions (let-exps exp)))
(cons (make-lambda let-variables (let-body exp))
let-expressions)))
((named-let? exp)
(let ((let-name (named-let-var exp))
(let-variables (named-let-vars exp))
(let-expressions (named-let-exps exp)))
(cons
(list 'define
(cons let-name let-variables)
(cons 'begin (named-let-body exp)))
let-expressions)))
(else (error "Unsupported let expression -- LET->COMBINATION"))))
(assert (let->combination '(let ((a 3) (b 4)) (* 3 a b)))
'((lambda (a b) (* 3 a b)) 3 4))
(assert (let->combination '(let fib-iter ((a 1)) (fib-iter (+ a 1))))
'((define (fib-iter a) (begin (fib-iter (+ a 1)))) 1))
(display "\nex-4.9 - iteration-constructs\n")
(display "\nex-4.10\n")