From 23a8766b451975cfa7d1310e8c03c8fea0b1093d Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Mon, 18 Jan 2021 08:19:32 -0500 Subject: [PATCH] Implement 4.8 --- ex-4_01-xx.scm | 61 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/ex-4_01-xx.scm b/ex-4_01-xx.scm index b6b00c4..890c6db 100644 --- a/ex-4_01-xx.scm +++ b/ex-4_01-xx.scm @@ -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")