summaryrefslogtreecommitdiff
path: root/main.scm
diff options
context:
space:
mode:
Diffstat (limited to 'main.scm')
-rw-r--r--main.scm48
1 files changed, 43 insertions, 5 deletions
diff --git a/main.scm b/main.scm
index dd60662..1781255 100644
--- a/main.scm
+++ b/main.scm
@@ -76,7 +76,9 @@
76(define (lambda-form? expr) (tagged? expr 'lambda)) 76(define (lambda-form? expr) (tagged? expr 'lambda))
77(define (lambda-params expr) (cadr expr)) 77(define (lambda-params expr) (cadr expr))
78(define (lambda-body expr) (cddr expr)) 78(define (lambda-body expr) (cddr expr))
79(define (make-lambda params body) (cons 'lambda (cons params body))) 79(define (make-lambda params body)
80 (cons 'lambda
81 (cons params (scan-out-defines body))))
80 82
81;;; begin 83;;; begin
82(define (begin-form? expr) (tagged? expr 'begin)) 84(define (begin-form? expr) (tagged? expr 'begin))
@@ -92,6 +94,11 @@
92;;; let 94;;; let
93(define (let-form? expr) (tagged? expr 'let)) 95(define (let-form? expr) (tagged? expr 'let))
94(define (let*-form? expr) (tagged? expr 'let*)) 96(define (let*-form? expr) (tagged? expr 'let*))
97(define (named-let-variable expr) (cadr expr))
98(define (named-let-form? expr) (and (tagged? expr 'let)
99 (variable? (named-let-variable expr))))
100(define (named-let-bindings expr) (caddr expr))
101(define (named-let-body expr) (cdddr expr))
95(define (let-bindings expr) (cadr expr)) 102(define (let-bindings expr) (cadr expr))
96(define (last-binding? bindings) (null? (cdr bindings))) 103(define (last-binding? bindings) (null? (cdr bindings)))
97(define (let-body expr) (cddr expr)) 104(define (let-body expr) (cddr expr))
@@ -110,22 +117,50 @@
110 [(last-binding? bindings) (make-let bindings body)] 117 [(last-binding? bindings) (make-let bindings body)]
111 [else (make-let (list (car bindings)) 118 [else (make-let (list (car bindings))
112 (let*->let (make-let* (cdr bindings) body)))]))) 119 (let*->let (make-let* (cdr bindings) body)))])))
120(define (named-let->let expr)
121 (let ([name (named-let-variable expr)]
122 [body (sequence->expr (named-let-body expr))]
123 [bindings (named-let-bindings expr)])
124 (let ([new-binding (make-lambda (let-binding-variables bindings)
125 body)])
126 (make-let (cons (list name new-binding)
127 bindings)
128 body))))
129
130;;; handle internal definitions
131(define (define->set statements)
132 (map (lambda (d)
133 (cons 'set! (cdr d)))
134 statements))
135(define (make-unassigned-bindings internal-defines)
136 (map (lambda (d)
137 (list (definition-name d) '*unassigned*)) internal-defines))
138(define (scan-out-defines body)
139 (let ([internal-defines (filter definition? body)]
140 [rest (filter (lambda (n) (not (definition? n))) body)])
141 (cond
142 [(null? internal-defines) body]
143 [else
144 (let ([variables (make-unassigned-bindings internal-defines)])
145 (let ([new-bindings (define->set internal-defines)])
146 (list (cons 'let (cons variables (append new-bindings rest))))))])))
113 147
114 148
115(define (eval-expr expr env) 149(define (eval-expr expr env)
116 (cond 150 (cond
117 [(self-evaluating? expr) expr] 151 [(self-evaluating? expr) expr]
118 [(variable? expr) (lookup-variable-value expr env)] 152 [(variable? expr) (lookup-variable-value expr env)]
153 [(assignment? expr) (eval-assignment expr env)]
154 [(definition? expr) (eval-definition expr env)]
155 [(quote-form? expr) (quotation-text expr)]
119 [(if-else? expr) (eval-if expr env)] 156 [(if-else? expr) (eval-if expr env)]
120 [(begin-form? expr) (eval-sequence (begin-actions expr) env)] 157 [(begin-form? expr) (eval-sequence (begin-actions expr) env)]
121 [(lambda-form? expr) (make-lambda (lambda-params expr) 158 [(lambda-form? expr) (make-lambda (lambda-params expr)
122 (lambda-body expr))] 159 (lambda-body expr))]
160 [(named-let-form? expr) 'false]
123 [(let-form? expr) (eval-let expr env)] 161 [(let-form? expr) (eval-let expr env)]
124 [(let*-form? expr) (eval-let* expr env)] 162 [(let*-form? expr) (eval-let* expr env)]
125 [(assignment? expr) (eval-assignment expr env)]
126 [(definition? expr) (eval-definition expr env)]
127 [(cond-form? expr) (eval-cond expr env)] 163 [(cond-form? expr) (eval-cond expr env)]
128 [(quote-form? expr) (quotation-text expr)]
129 [(function-application? expr) (eval-function-application expr env)])) 164 [(function-application? expr) (eval-function-application expr env)]))
130 165
131(define (eval-if expr env) 166(define (eval-if expr env)
@@ -143,6 +178,9 @@
143 (eval-expr (car exprs) env) 178 (eval-expr (car exprs) env)
144 (eval-sequence (cdr exprs) env))])) 179 (eval-sequence (cdr exprs) env))]))
145 180
181(define (eval-named-let expr env)
182 (eval-let (named-let->let expr) env))
183
146(define (eval-let expr env) 184(define (eval-let expr env)
147 (eval-function-application 185 (eval-function-application
148 (cons (let->lambda expr) 186 (cons (let->lambda expr)
@@ -153,7 +191,7 @@
153 (eval-expr (let*->let expr) env)) 191 (eval-expr (let*->let expr) env))
154 192
155(define (eval-assignment expr env) 193(define (eval-assignment expr env)
156 (set-variable-value! 194 (set-variable-value!
157 (assignment-name expr) 195 (assignment-name expr)
158 (eval-expr (assignment-value expr) env) 196 (eval-expr (assignment-value expr) env)
159 env)) 197 env))