diff options
-rw-r--r-- | main.scm | 23 |
1 files changed, 20 insertions, 3 deletions
@@ -91,14 +91,26 @@ | |||
91 | 91 | ||
92 | ;;; let | 92 | ;;; let |
93 | (define (let-form? expr) (tagged? expr 'let)) | 93 | (define (let-form? expr) (tagged? expr 'let)) |
94 | (define (let*-form? expr) (tagged? expr 'let*)) | ||
94 | (define (let-bindings expr) (cadr expr)) | 95 | (define (let-bindings expr) (cadr expr)) |
96 | (define (last-binding? bindings) (null? (cdr bindings))) | ||
95 | (define (let-body expr) (cddr expr)) | 97 | (define (let-body expr) (cddr expr)) |
96 | (define (let-binding-variables bindings) (map car bindings)) | 98 | (define (let-binding-variables bindings) (map car bindings)) |
97 | (define (let-binding-values bindings) (map cadr bindings)) | 99 | (define (let-binding-values bindings) (map cadr bindings)) |
100 | (define (make-let bindings body) (list 'let bindings body)) | ||
101 | (define (make-let* bindings body) (list 'let* bindings body)) | ||
98 | (define (let->lambda expr) | 102 | (define (let->lambda expr) |
99 | (let ([bindings (let-bindings expr)]) | 103 | (let ([bindings (let-bindings expr)]) |
100 | (make-lambda (let-binding-variables bindings) | 104 | (make-lambda (let-binding-variables bindings) |
101 | (let-body expr)))) | 105 | (let-body expr)))) |
106 | (define (let*->let expr) | ||
107 | (let ([bindings (let-bindings expr)] | ||
108 | [body (sequence->expr (let-body expr))]) | ||
109 | (cond | ||
110 | [(last-binding? bindings) (make-let bindings body)] | ||
111 | [else (make-let (list (car bindings)) | ||
112 | (let*->let (make-let* (cdr bindings) body)))]))) | ||
113 | |||
102 | 114 | ||
103 | (define (eval-expr expr env) | 115 | (define (eval-expr expr env) |
104 | (cond | 116 | (cond |
@@ -109,6 +121,7 @@ | |||
109 | [(lambda-form? expr) (make-lambda (lambda-params expr) | 121 | [(lambda-form? expr) (make-lambda (lambda-params expr) |
110 | (lambda-body expr))] | 122 | (lambda-body expr))] |
111 | [(let-form? expr) (eval-let expr env)] | 123 | [(let-form? expr) (eval-let expr env)] |
124 | [(let*-form? expr) (eval-let* expr env)] | ||
112 | [(assignment? expr) (eval-assignment expr env)] | 125 | [(assignment? expr) (eval-assignment expr env)] |
113 | [(definition? expr) (eval-definition expr env)] | 126 | [(definition? expr) (eval-definition expr env)] |
114 | [(cond-form? expr) (eval-cond expr env)] | 127 | [(cond-form? expr) (eval-cond expr env)] |
@@ -131,9 +144,13 @@ | |||
131 | (eval-sequence (cdr exprs) env))])) | 144 | (eval-sequence (cdr exprs) env))])) |
132 | 145 | ||
133 | (define (eval-let expr env) | 146 | (define (eval-let expr env) |
134 | (eval-function-application (cons (let->lambda expr) | 147 | (eval-function-application |
135 | (let-binding-values (let-bindings expr))) | 148 | (cons (let->lambda expr) |
136 | env)) | 149 | (let-binding-values (let-bindings expr))) |
150 | env)) | ||
151 | |||
152 | (define (eval-let* expr env) | ||
153 | (eval-expr (let*->let expr) env)) | ||
137 | 154 | ||
138 | (define (eval-assignment expr env) | 155 | (define (eval-assignment expr env) |
139 | (set-variable-value! | 156 | (set-variable-value! |