Blame


1 665c255d 2023-08-04 jrmu (define apply-in-underlying-scheme apply)
2 665c255d 2023-08-04 jrmu
3 665c255d 2023-08-04 jrmu (define (eval exp env)
4 665c255d 2023-08-04 jrmu (cond ((self-evaluating? exp) exp)
5 665c255d 2023-08-04 jrmu ((variable? exp) (lookup-variable-value exp env))
6 665c255d 2023-08-04 jrmu ((quoted? exp) (text-of-quotation exp))
7 665c255d 2023-08-04 jrmu ((assignment? exp) (eval-assignment exp env))
8 665c255d 2023-08-04 jrmu ((definition? exp) (eval-definition exp env))
9 665c255d 2023-08-04 jrmu ((unbound? exp) (eval-unbound exp env))
10 665c255d 2023-08-04 jrmu ((if? exp) (eval-if exp env))
11 665c255d 2023-08-04 jrmu ((and? exp) (eval-and exp env))
12 665c255d 2023-08-04 jrmu ((or? exp) (eval-or exp env))
13 665c255d 2023-08-04 jrmu ((lambda? exp)
14 665c255d 2023-08-04 jrmu (make-procedure (lambda-parameters exp)
15 665c255d 2023-08-04 jrmu (lambda-body exp)
16 665c255d 2023-08-04 jrmu env))
17 665c255d 2023-08-04 jrmu ((begin? exp)
18 665c255d 2023-08-04 jrmu (eval-sequence (begin-actions exp) env))
19 665c255d 2023-08-04 jrmu ((cond? exp) (eval (cond->if exp) env))
20 665c255d 2023-08-04 jrmu ((let? exp) (eval (let->combination exp) env))
21 665c255d 2023-08-04 jrmu ((let*? exp) (eval (let*->nested-lets exp) env))
22 665c255d 2023-08-04 jrmu ((named-let? exp) (eval (named-let->combination exp) env))
23 665c255d 2023-08-04 jrmu ((do? exp) (eval (do->combination exp) env))
24 665c255d 2023-08-04 jrmu ((application? exp)
25 665c255d 2023-08-04 jrmu (apply (eval (operator exp) env)
26 665c255d 2023-08-04 jrmu (list-of-values (operands exp) env)))
27 665c255d 2023-08-04 jrmu (else
28 665c255d 2023-08-04 jrmu (error "Unknown expression type -- EVAL" exp))))
29 665c255d 2023-08-04 jrmu (define (apply procedure arguments)
30 665c255d 2023-08-04 jrmu (cond ((primitive-procedure? procedure)
31 665c255d 2023-08-04 jrmu (apply-primitive-procedure procedure arguments))
32 665c255d 2023-08-04 jrmu ((compound-procedure? procedure)
33 665c255d 2023-08-04 jrmu (eval-sequence
34 665c255d 2023-08-04 jrmu (procedure-body procedure)
35 665c255d 2023-08-04 jrmu (extend-environment
36 665c255d 2023-08-04 jrmu (procedure-parameters procedure)
37 665c255d 2023-08-04 jrmu arguments
38 665c255d 2023-08-04 jrmu (procedure-environment procedure))))
39 665c255d 2023-08-04 jrmu (else
40 665c255d 2023-08-04 jrmu (error
41 665c255d 2023-08-04 jrmu "Unknown procedure type -- APPLY" procedure))))
42 665c255d 2023-08-04 jrmu
43 665c255d 2023-08-04 jrmu (define (list-of-values exps env)
44 665c255d 2023-08-04 jrmu (if (no-operands? exps)
45 665c255d 2023-08-04 jrmu '()
46 665c255d 2023-08-04 jrmu (cons (eval (first-operand exps) env)
47 665c255d 2023-08-04 jrmu (list-of-values (rest-operands exps) env))))
48 665c255d 2023-08-04 jrmu
49 665c255d 2023-08-04 jrmu (define (tagged-list? exp tag)
50 665c255d 2023-08-04 jrmu (if (pair? exp)
51 665c255d 2023-08-04 jrmu (eq? (car exp) tag)
52 665c255d 2023-08-04 jrmu false))
53 665c255d 2023-08-04 jrmu
54 665c255d 2023-08-04 jrmu ;; self-evaluating/variable/quoted
55 665c255d 2023-08-04 jrmu (define (self-evaluating? exp)
56 665c255d 2023-08-04 jrmu (cond ((number? exp) true)
57 665c255d 2023-08-04 jrmu ((string? exp) true)
58 665c255d 2023-08-04 jrmu (else false)))
59 665c255d 2023-08-04 jrmu (define (variable? exp) (symbol? exp))
60 665c255d 2023-08-04 jrmu (define (quoted? exp)
61 665c255d 2023-08-04 jrmu (tagged-list? exp 'quote))
62 665c255d 2023-08-04 jrmu (define (text-of-quotation exp) (cadr exp))
63 665c255d 2023-08-04 jrmu
64 665c255d 2023-08-04 jrmu ;; assignment/definition
65 665c255d 2023-08-04 jrmu (define (assignment? exp)
66 665c255d 2023-08-04 jrmu (tagged-list? exp 'set!))
67 665c255d 2023-08-04 jrmu (define (assignment-variable exp) (cadr exp))
68 665c255d 2023-08-04 jrmu (define (assignment-value exp) (caddr exp))
69 665c255d 2023-08-04 jrmu (define (definition? exp)
70 665c255d 2023-08-04 jrmu (tagged-list? exp 'define))
71 665c255d 2023-08-04 jrmu (define (definition-variable exp)
72 665c255d 2023-08-04 jrmu (if (symbol? (cadr exp))
73 665c255d 2023-08-04 jrmu (cadr exp)
74 665c255d 2023-08-04 jrmu (caadr exp)))
75 665c255d 2023-08-04 jrmu (define (definition-value exp)
76 665c255d 2023-08-04 jrmu (if (symbol? (cadr exp))
77 665c255d 2023-08-04 jrmu (caddr exp)
78 665c255d 2023-08-04 jrmu (make-lambda (cdadr exp) ; formal parameters
79 665c255d 2023-08-04 jrmu (cddr exp)))) ; body
80 665c255d 2023-08-04 jrmu (define (eval-assignment exp env)
81 665c255d 2023-08-04 jrmu (set-variable-value! (assignment-variable exp)
82 665c255d 2023-08-04 jrmu (eval (assignment-value exp) env)
83 665c255d 2023-08-04 jrmu env)
84 665c255d 2023-08-04 jrmu 'ok)
85 665c255d 2023-08-04 jrmu (define (eval-definition exp env)
86 665c255d 2023-08-04 jrmu (define-variable! (definition-variable exp)
87 665c255d 2023-08-04 jrmu (eval (definition-value exp) env)
88 665c255d 2023-08-04 jrmu env)
89 665c255d 2023-08-04 jrmu 'ok)
90 665c255d 2023-08-04 jrmu (define (make-definition var val)
91 665c255d 2023-08-04 jrmu `(define ,var ,val))
92 665c255d 2023-08-04 jrmu
93 665c255d 2023-08-04 jrmu ;; make-unbound!
94 665c255d 2023-08-04 jrmu
95 665c255d 2023-08-04 jrmu (define (unbound? exp)
96 665c255d 2023-08-04 jrmu (tagged-list? exp 'make-unbound!))
97 665c255d 2023-08-04 jrmu (define (unbound-var exp)
98 665c255d 2023-08-04 jrmu (cadr exp))
99 665c255d 2023-08-04 jrmu (define (eval-unbound exp env)
100 665c255d 2023-08-04 jrmu (remove-binding-from-frame! (unbound-var exp) (first-frame env)))
101 665c255d 2023-08-04 jrmu (define (remove-binding-from-frame! var frame)
102 665c255d 2023-08-04 jrmu (define (scan vars vals)
103 665c255d 2023-08-04 jrmu (cond ((null? (cdr vars))
104 665c255d 2023-08-04 jrmu (error "Binding not found -- REMOVE-BINDING-FROM-FRAME!" var))
105 665c255d 2023-08-04 jrmu ((eq? var (cadr vars))
106 665c255d 2023-08-04 jrmu (set-cdr! vars (cddr vars))
107 665c255d 2023-08-04 jrmu (set-cdr! vals (cddr vals)))
108 665c255d 2023-08-04 jrmu (else (scan (cdr vars) (cdr vals)))))
109 665c255d 2023-08-04 jrmu (let ((vars (frame-variables frame))
110 665c255d 2023-08-04 jrmu (vals (frame-values frame)))
111 665c255d 2023-08-04 jrmu (if (eq? var (car vars))
112 665c255d 2023-08-04 jrmu (begin (set-car! frame (cdr vars))
113 665c255d 2023-08-04 jrmu (set-cdr! frame (cdr vals)))
114 665c255d 2023-08-04 jrmu (scan vars vals))))
115 665c255d 2023-08-04 jrmu
116 665c255d 2023-08-04 jrmu ;; if/and/or
117 665c255d 2023-08-04 jrmu (define (if? exp) (tagged-list? exp 'if))
118 665c255d 2023-08-04 jrmu (define (if-predicate exp) (cadr exp))
119 665c255d 2023-08-04 jrmu (define (if-consequent exp) (caddr exp))
120 665c255d 2023-08-04 jrmu (define (if-alternative exp)
121 665c255d 2023-08-04 jrmu (if (not (null? (cdddr exp)))
122 665c255d 2023-08-04 jrmu (cadddr exp)
123 665c255d 2023-08-04 jrmu 'false))
124 665c255d 2023-08-04 jrmu (define (make-if predicate consequent alternative)
125 665c255d 2023-08-04 jrmu (list 'if predicate consequent alternative))
126 665c255d 2023-08-04 jrmu (define (eval-if exp env)
127 665c255d 2023-08-04 jrmu (if (true? (eval (if-predicate exp) env))
128 665c255d 2023-08-04 jrmu (eval (if-consequent exp) env)
129 665c255d 2023-08-04 jrmu (eval (if-alternative exp) env)))
130 665c255d 2023-08-04 jrmu
131 665c255d 2023-08-04 jrmu (define (and? exp)
132 665c255d 2023-08-04 jrmu (tagged-list? exp 'and))
133 665c255d 2023-08-04 jrmu (define (and-clauses exp)
134 665c255d 2023-08-04 jrmu (cdr exp))
135 665c255d 2023-08-04 jrmu (define (or? exp)
136 665c255d 2023-08-04 jrmu (tagged-list? exp 'or))
137 665c255d 2023-08-04 jrmu (define (or-clauses exp)
138 665c255d 2023-08-04 jrmu (cdr exp))
139 665c255d 2023-08-04 jrmu (define (eval-and exp env)
140 665c255d 2023-08-04 jrmu (define (eval-clauses clauses)
141 665c255d 2023-08-04 jrmu (cond ((null? clauses) true)
142 665c255d 2023-08-04 jrmu ((null? (cdr clauses)) (eval (car clauses) env))
143 665c255d 2023-08-04 jrmu (else (and (eval (car clauses) env)
144 665c255d 2023-08-04 jrmu (eval-clauses (cdr clauses))))))
145 665c255d 2023-08-04 jrmu (eval-clauses (and-clauses exp)))
146 665c255d 2023-08-04 jrmu (define (eval-or exp env)
147 665c255d 2023-08-04 jrmu (define (eval-clauses clauses)
148 665c255d 2023-08-04 jrmu (if (null? clauses)
149 665c255d 2023-08-04 jrmu false
150 665c255d 2023-08-04 jrmu (or (eval (car clauses) env)
151 665c255d 2023-08-04 jrmu (eval-clauses (cdr clauses)))))
152 665c255d 2023-08-04 jrmu (eval-clauses (or-clauses exp)))
153 665c255d 2023-08-04 jrmu
154 665c255d 2023-08-04 jrmu
155 665c255d 2023-08-04 jrmu ;; lambda/let/let*
156 665c255d 2023-08-04 jrmu (define (lambda? exp) (tagged-list? exp 'lambda))
157 665c255d 2023-08-04 jrmu (define (lambda-parameters exp) (cadr exp))
158 665c255d 2023-08-04 jrmu (define (lambda-body exp) (cddr exp))
159 665c255d 2023-08-04 jrmu (define (make-lambda parameters body)
160 665c255d 2023-08-04 jrmu (cons 'lambda (cons parameters body)))
161 665c255d 2023-08-04 jrmu
162 665c255d 2023-08-04 jrmu (define (make-let vars vals body)
163 665c255d 2023-08-04 jrmu (cons 'let
164 665c255d 2023-08-04 jrmu (cons (map list vars vals)
165 665c255d 2023-08-04 jrmu body)))
166 665c255d 2023-08-04 jrmu (define (let? exp)
167 665c255d 2023-08-04 jrmu (and (tagged-list? exp 'let)
168 665c255d 2023-08-04 jrmu (not (symbol? (cadr exp)))))
169 665c255d 2023-08-04 jrmu (define (let-vars exp)
170 665c255d 2023-08-04 jrmu (map car (cadr exp)))
171 665c255d 2023-08-04 jrmu (define (let-vals exp)
172 665c255d 2023-08-04 jrmu (map cadr (cadr exp)))
173 665c255d 2023-08-04 jrmu (define (let-body exp)
174 665c255d 2023-08-04 jrmu (cddr exp))
175 665c255d 2023-08-04 jrmu (define (let->combination exp)
176 665c255d 2023-08-04 jrmu (make-application (make-lambda (let-vars exp) (let-body exp))
177 665c255d 2023-08-04 jrmu (let-vals exp)))
178 665c255d 2023-08-04 jrmu (define (named-let? exp)
179 665c255d 2023-08-04 jrmu (and (tagged-list? exp 'let)
180 665c255d 2023-08-04 jrmu (symbol? (cadr exp))))
181 665c255d 2023-08-04 jrmu (define (named-let-name exp)
182 665c255d 2023-08-04 jrmu (cadr exp))
183 665c255d 2023-08-04 jrmu (define (named-let-vars exp)
184 665c255d 2023-08-04 jrmu (map car (caddr exp)))
185 665c255d 2023-08-04 jrmu (define (named-let-vals exp)
186 665c255d 2023-08-04 jrmu (map cadr (caddr exp)))
187 665c255d 2023-08-04 jrmu (define (named-let-body exp)
188 665c255d 2023-08-04 jrmu (cdddr exp))
189 665c255d 2023-08-04 jrmu (define (named-let->combination exp)
190 665c255d 2023-08-04 jrmu (sequence->exp
191 665c255d 2023-08-04 jrmu (list (make-definition (named-let-name exp)
192 665c255d 2023-08-04 jrmu (make-lambda (named-let-vars exp)
193 665c255d 2023-08-04 jrmu (named-let-body exp)))
194 665c255d 2023-08-04 jrmu (make-application (named-let-name exp)
195 665c255d 2023-08-04 jrmu (named-let-vals exp)))))
196 665c255d 2023-08-04 jrmu (define (make-named-let name vars vals body)
197 665c255d 2023-08-04 jrmu (cons 'let
198 665c255d 2023-08-04 jrmu (cons name
199 665c255d 2023-08-04 jrmu (cons (map list vars vals)
200 665c255d 2023-08-04 jrmu body))))
201 665c255d 2023-08-04 jrmu
202 665c255d 2023-08-04 jrmu (define (make-application op args)
203 665c255d 2023-08-04 jrmu (cons op args))
204 665c255d 2023-08-04 jrmu
205 665c255d 2023-08-04 jrmu (define (let*? exp)
206 665c255d 2023-08-04 jrmu (tagged-list? exp 'let*))
207 665c255d 2023-08-04 jrmu (define let*-vars let-vars)
208 665c255d 2023-08-04 jrmu (define let*-vals let-vals)
209 665c255d 2023-08-04 jrmu (define let*-body let-body)
210 665c255d 2023-08-04 jrmu (define (let*->nested-lets exp)
211 665c255d 2023-08-04 jrmu (define (expand-lets vars vals)
212 665c255d 2023-08-04 jrmu (if (null? (cdr vars))
213 665c255d 2023-08-04 jrmu (make-let (list (car vars))
214 665c255d 2023-08-04 jrmu (list (car vals))
215 665c255d 2023-08-04 jrmu (let*-body exp))
216 665c255d 2023-08-04 jrmu (make-let (list (car vars))
217 665c255d 2023-08-04 jrmu (list (car vals))
218 665c255d 2023-08-04 jrmu (list (expand-lets (cdr vars) (cdr vals))))))
219 665c255d 2023-08-04 jrmu (let ((vars (let*-vars exp))
220 665c255d 2023-08-04 jrmu (vals (let*-vals exp)))
221 665c255d 2023-08-04 jrmu (if (null? vars)
222 665c255d 2023-08-04 jrmu (sequence->exp (let*-body exp))
223 665c255d 2023-08-04 jrmu (expand-lets vars vals))))
224 665c255d 2023-08-04 jrmu
225 665c255d 2023-08-04 jrmu ;; do loop
226 665c255d 2023-08-04 jrmu (define (do? exp)
227 665c255d 2023-08-04 jrmu (tagged-list? exp 'do))
228 665c255d 2023-08-04 jrmu (define (do-vars exp)
229 665c255d 2023-08-04 jrmu (map car (cadr exp)))
230 665c255d 2023-08-04 jrmu (define (do-inits exp)
231 665c255d 2023-08-04 jrmu (map cadr (cadr exp)))
232 665c255d 2023-08-04 jrmu (define (do-steps exp)
233 665c255d 2023-08-04 jrmu (map (lambda (var-init-step)
234 665c255d 2023-08-04 jrmu (if (null? (cddr var-init-step))
235 665c255d 2023-08-04 jrmu (car var-init-step)
236 665c255d 2023-08-04 jrmu (caddr var-init-step)))
237 665c255d 2023-08-04 jrmu (cadr exp)))
238 665c255d 2023-08-04 jrmu (define (do-test exp)
239 665c255d 2023-08-04 jrmu (caaddr exp))
240 665c255d 2023-08-04 jrmu (define (do-expressions exp)
241 665c255d 2023-08-04 jrmu (if (null? (cdaddr exp))
242 665c255d 2023-08-04 jrmu (caddr exp)
243 665c255d 2023-08-04 jrmu (cdaddr exp)))
244 665c255d 2023-08-04 jrmu (define (do-commands exp)
245 665c255d 2023-08-04 jrmu (cdddr exp))
246 665c255d 2023-08-04 jrmu (define (do->combination exp)
247 665c255d 2023-08-04 jrmu (make-named-let
248 665c255d 2023-08-04 jrmu 'do-iter
249 665c255d 2023-08-04 jrmu (do-vars exp)
250 665c255d 2023-08-04 jrmu (do-inits exp)
251 665c255d 2023-08-04 jrmu (list
252 665c255d 2023-08-04 jrmu (make-if
253 665c255d 2023-08-04 jrmu (do-test exp)
254 665c255d 2023-08-04 jrmu (sequence->exp (do-expressions exp))
255 665c255d 2023-08-04 jrmu (sequence->exp
256 665c255d 2023-08-04 jrmu (append (do-commands exp)
257 665c255d 2023-08-04 jrmu (list (make-application
258 665c255d 2023-08-04 jrmu 'do-iter
259 665c255d 2023-08-04 jrmu (do-steps exp)))))))))
260 665c255d 2023-08-04 jrmu
261 665c255d 2023-08-04 jrmu
262 665c255d 2023-08-04 jrmu ;; begin/sequence
263 665c255d 2023-08-04 jrmu (define (begin? exp) (tagged-list? exp 'begin))
264 665c255d 2023-08-04 jrmu (define (begin-actions exp) (cdr exp))
265 665c255d 2023-08-04 jrmu (define (last-exp? seq) (null? (cdr seq)))
266 665c255d 2023-08-04 jrmu (define (first-exp seq) (car seq))
267 665c255d 2023-08-04 jrmu (define (rest-exps seq) (cdr seq))
268 665c255d 2023-08-04 jrmu (define (sequence->exp seq)
269 665c255d 2023-08-04 jrmu (cond ((null? seq) seq)
270 665c255d 2023-08-04 jrmu ((last-exp? seq) (first-exp seq))
271 665c255d 2023-08-04 jrmu (else (make-begin seq))))
272 665c255d 2023-08-04 jrmu (define (make-begin seq) (cons 'begin seq))
273 665c255d 2023-08-04 jrmu (define (eval-sequence exps env)
274 665c255d 2023-08-04 jrmu (cond ((last-exp? exps) (eval (first-exp exps) env))
275 665c255d 2023-08-04 jrmu (else (eval (first-exp exps) env)
276 665c255d 2023-08-04 jrmu (eval-sequence (rest-exps exps) env))))
277 665c255d 2023-08-04 jrmu
278 665c255d 2023-08-04 jrmu ;; application
279 665c255d 2023-08-04 jrmu (define (application? exp) (pair? exp))
280 665c255d 2023-08-04 jrmu (define (operator exp) (car exp))
281 665c255d 2023-08-04 jrmu (define (operands exp) (cdr exp))
282 665c255d 2023-08-04 jrmu (define (no-operands? ops) (null? ops))
283 665c255d 2023-08-04 jrmu (define (first-operand ops) (car ops))
284 665c255d 2023-08-04 jrmu (define (rest-operands ops) (cdr ops))
285 665c255d 2023-08-04 jrmu
286 665c255d 2023-08-04 jrmu ;; cond
287 665c255d 2023-08-04 jrmu (define (cond? exp) (tagged-list? exp 'cond))
288 665c255d 2023-08-04 jrmu (define (cond-clauses exp) (cdr exp))
289 665c255d 2023-08-04 jrmu (define (cond-else-clause? clause)
290 665c255d 2023-08-04 jrmu (eq? (cond-predicate clause) 'else))
291 665c255d 2023-08-04 jrmu (define (cond-predicate clause) (car clause))
292 665c255d 2023-08-04 jrmu (define (cond-actions clause) (cdr clause))
293 665c255d 2023-08-04 jrmu (define (cond-extended-clause? clause)
294 665c255d 2023-08-04 jrmu (and (not (null? (cdr clause))) (eq? (cadr clause) '=>)))
295 665c255d 2023-08-04 jrmu (define (cond-extended-proc clause)
296 665c255d 2023-08-04 jrmu (caddr clause))
297 665c255d 2023-08-04 jrmu (define (cond->if exp)
298 665c255d 2023-08-04 jrmu (expand-clauses (cond-clauses exp)))
299 665c255d 2023-08-04 jrmu (define (expand-clauses clauses)
300 665c255d 2023-08-04 jrmu (if (null? clauses)
301 665c255d 2023-08-04 jrmu 'false ; no else clause
302 665c255d 2023-08-04 jrmu (let ((first (car clauses))
303 665c255d 2023-08-04 jrmu (rest (cdr clauses)))
304 665c255d 2023-08-04 jrmu (if (cond-else-clause? first)
305 665c255d 2023-08-04 jrmu (if (null? rest)
306 665c255d 2023-08-04 jrmu (sequence->exp (cond-actions first))
307 665c255d 2023-08-04 jrmu (error "ELSE clause isn't last -- COND->IF"
308 665c255d 2023-08-04 jrmu clauses))
309 665c255d 2023-08-04 jrmu (if (cond-extended-clause? first)
310 665c255d 2023-08-04 jrmu (make-if (cond-predicate first)
311 665c255d 2023-08-04 jrmu (make-application
312 665c255d 2023-08-04 jrmu (cond-extended-proc first)
313 665c255d 2023-08-04 jrmu (list (cond-predicate first)))
314 665c255d 2023-08-04 jrmu (expand-clauses rest))
315 665c255d 2023-08-04 jrmu (make-if (cond-predicate first)
316 665c255d 2023-08-04 jrmu (sequence->exp (cond-actions first))
317 665c255d 2023-08-04 jrmu (expand-clauses rest)))))))
318 665c255d 2023-08-04 jrmu (define (true? x)
319 665c255d 2023-08-04 jrmu (not (eq? x false)))
320 665c255d 2023-08-04 jrmu (define (false? x)
321 665c255d 2023-08-04 jrmu (eq? x false))
322 665c255d 2023-08-04 jrmu
323 665c255d 2023-08-04 jrmu ;; procedure
324 665c255d 2023-08-04 jrmu (define (make-procedure parameters body env)
325 665c255d 2023-08-04 jrmu (list 'procedure parameters body env))
326 665c255d 2023-08-04 jrmu (define (compound-procedure? p)
327 665c255d 2023-08-04 jrmu (tagged-list? p 'procedure))
328 665c255d 2023-08-04 jrmu (define (procedure-parameters p) (cadr p))
329 665c255d 2023-08-04 jrmu (define (procedure-body p) (caddr p))
330 665c255d 2023-08-04 jrmu (define (procedure-environment p) (cadddr p))
331 665c255d 2023-08-04 jrmu
332 665c255d 2023-08-04 jrmu ;; environment
333 665c255d 2023-08-04 jrmu (define (enclosing-environment env) (cdr env))
334 665c255d 2023-08-04 jrmu (define (first-frame env) (car env))
335 665c255d 2023-08-04 jrmu (define the-empty-environment '())
336 665c255d 2023-08-04 jrmu (define (make-frame variables values)
337 665c255d 2023-08-04 jrmu (cons variables values))
338 665c255d 2023-08-04 jrmu (define (frame-variables frame) (car frame))
339 665c255d 2023-08-04 jrmu (define (frame-values frame) (cdr frame))
340 665c255d 2023-08-04 jrmu (define (add-binding-to-frame! var val frame)
341 665c255d 2023-08-04 jrmu (set-car! frame (cons var (car frame)))
342 665c255d 2023-08-04 jrmu (set-cdr! frame (cons val (cdr frame))))
343 665c255d 2023-08-04 jrmu (define (extend-environment vars vals base-env)
344 665c255d 2023-08-04 jrmu (if (= (length vars) (length vals))
345 665c255d 2023-08-04 jrmu (cons (make-frame vars vals) base-env)
346 665c255d 2023-08-04 jrmu (if (< (length vars) (length vals))
347 665c255d 2023-08-04 jrmu (error "Too many arguments supplied" vars vals)
348 665c255d 2023-08-04 jrmu (error "Too few arguments supplied" vars vals))))
349 665c255d 2023-08-04 jrmu (define (lookup-variable-value var env)
350 665c255d 2023-08-04 jrmu (define (env-loop env)
351 665c255d 2023-08-04 jrmu (define (scan vars vals)
352 665c255d 2023-08-04 jrmu (cond ((null? vars)
353 665c255d 2023-08-04 jrmu (env-loop (enclosing-environment env)))
354 665c255d 2023-08-04 jrmu ((eq? var (car vars))
355 665c255d 2023-08-04 jrmu (car vals))
356 665c255d 2023-08-04 jrmu (else (scan (cdr vars) (cdr vals)))))
357 665c255d 2023-08-04 jrmu (if (eq? env the-empty-environment)
358 665c255d 2023-08-04 jrmu (error "Unbound variable" var)
359 665c255d 2023-08-04 jrmu (let ((frame (first-frame env)))
360 665c255d 2023-08-04 jrmu (scan (frame-variables frame)
361 665c255d 2023-08-04 jrmu (frame-values frame)))))
362 665c255d 2023-08-04 jrmu (env-loop env))
363 665c255d 2023-08-04 jrmu (define (set-variable-value! var val env)
364 665c255d 2023-08-04 jrmu (define (env-loop env)
365 665c255d 2023-08-04 jrmu (define (scan vars vals)
366 665c255d 2023-08-04 jrmu (cond ((null? vars)
367 665c255d 2023-08-04 jrmu (env-loop (enclosing-environment env)))
368 665c255d 2023-08-04 jrmu ((eq? var (car vars))
369 665c255d 2023-08-04 jrmu (set-car! vals val))
370 665c255d 2023-08-04 jrmu (else (scan (cdr vars) (cdr vals)))))
371 665c255d 2023-08-04 jrmu (if (eq? env the-empty-environment)
372 665c255d 2023-08-04 jrmu (error "Unbound variable -- SET!" var)
373 665c255d 2023-08-04 jrmu (let ((frame (first-frame env)))
374 665c255d 2023-08-04 jrmu (scan (frame-variables frame)
375 665c255d 2023-08-04 jrmu (frame-values frame)))))
376 665c255d 2023-08-04 jrmu (env-loop env))
377 665c255d 2023-08-04 jrmu (define (define-variable! var val env)
378 665c255d 2023-08-04 jrmu (let ((frame (first-frame env)))
379 665c255d 2023-08-04 jrmu (define (scan vars vals)
380 665c255d 2023-08-04 jrmu (cond ((null? vars)
381 665c255d 2023-08-04 jrmu (add-binding-to-frame! var val frame))
382 665c255d 2023-08-04 jrmu ((eq? var (car vars))
383 665c255d 2023-08-04 jrmu (set-car! vals val))
384 665c255d 2023-08-04 jrmu (else (scan (cdr vars) (cdr vals)))))
385 665c255d 2023-08-04 jrmu (scan (frame-variables frame)
386 665c255d 2023-08-04 jrmu (frame-values frame))))
387 665c255d 2023-08-04 jrmu
388 665c255d 2023-08-04 jrmu ;; primitives
389 665c255d 2023-08-04 jrmu (define (primitive-procedure? proc)
390 665c255d 2023-08-04 jrmu (tagged-list? proc 'primitive))
391 665c255d 2023-08-04 jrmu (define (primitive-implementation proc) (cadr proc))
392 665c255d 2023-08-04 jrmu (define primitive-procedures
393 665c255d 2023-08-04 jrmu (list (list 'car car)
394 665c255d 2023-08-04 jrmu (list 'cdr cdr)
395 665c255d 2023-08-04 jrmu (list 'caar caar)
396 665c255d 2023-08-04 jrmu (list 'cadr cadr)
397 665c255d 2023-08-04 jrmu (list 'cddr cddr)
398 665c255d 2023-08-04 jrmu (list 'cons cons)
399 665c255d 2023-08-04 jrmu (list 'null? null?)
400 665c255d 2023-08-04 jrmu (list '* *)
401 665c255d 2023-08-04 jrmu (list '/ /)
402 665c255d 2023-08-04 jrmu (list '+ +)
403 665c255d 2023-08-04 jrmu (list '- -)
404 665c255d 2023-08-04 jrmu (list '= =)
405 665c255d 2023-08-04 jrmu (list '< <)
406 665c255d 2023-08-04 jrmu (list '> >)
407 665c255d 2023-08-04 jrmu (list '<= <=)
408 665c255d 2023-08-04 jrmu (list '>= >=)
409 665c255d 2023-08-04 jrmu (list 'remainder remainder)
410 665c255d 2023-08-04 jrmu (list 'eq? eq?)
411 665c255d 2023-08-04 jrmu (list 'equal? equal?)
412 665c255d 2023-08-04 jrmu (list 'display display)))
413 665c255d 2023-08-04 jrmu (define (primitive-procedure-names)
414 665c255d 2023-08-04 jrmu (map car
415 665c255d 2023-08-04 jrmu primitive-procedures))
416 665c255d 2023-08-04 jrmu (define (primitive-procedure-objects)
417 665c255d 2023-08-04 jrmu (map (lambda (proc) (list 'primitive (cadr proc)))
418 665c255d 2023-08-04 jrmu primitive-procedures))
419 665c255d 2023-08-04 jrmu (define (apply-primitive-procedure proc args)
420 665c255d 2023-08-04 jrmu (apply-in-underlying-scheme
421 665c255d 2023-08-04 jrmu (primitive-implementation proc) args))
422 665c255d 2023-08-04 jrmu
423 665c255d 2023-08-04 jrmu ;; driver-loop
424 665c255d 2023-08-04 jrmu (define input-prompt ";;; M-Eval input:")
425 665c255d 2023-08-04 jrmu (define output-prompt ";;; M-Eval value:")
426 665c255d 2023-08-04 jrmu (define (driver-loop)
427 665c255d 2023-08-04 jrmu (prompt-for-input input-prompt)
428 665c255d 2023-08-04 jrmu (let ((input (read)))
429 665c255d 2023-08-04 jrmu (let ((output (eval input the-global-environment)))
430 665c255d 2023-08-04 jrmu (announce-output output-prompt)
431 665c255d 2023-08-04 jrmu (user-print output)))
432 665c255d 2023-08-04 jrmu (driver-loop))
433 665c255d 2023-08-04 jrmu (define (prompt-for-input string)
434 665c255d 2023-08-04 jrmu (newline) (newline) (display string) (newline))
435 665c255d 2023-08-04 jrmu
436 665c255d 2023-08-04 jrmu (define (announce-output string)
437 665c255d 2023-08-04 jrmu (newline) (display string) (newline))
438 665c255d 2023-08-04 jrmu (define (user-print object)
439 665c255d 2023-08-04 jrmu (if (compound-procedure? object)
440 665c255d 2023-08-04 jrmu (display (list 'compound-procedure
441 665c255d 2023-08-04 jrmu (procedure-parameters object)
442 665c255d 2023-08-04 jrmu (procedure-body object)
443 665c255d 2023-08-04 jrmu '<procedure-env>))
444 665c255d 2023-08-04 jrmu (display object)))
445 665c255d 2023-08-04 jrmu (define (setup-environment)
446 665c255d 2023-08-04 jrmu (let ((initial-env
447 665c255d 2023-08-04 jrmu (extend-environment (primitive-procedure-names)
448 665c255d 2023-08-04 jrmu (primitive-procedure-objects)
449 665c255d 2023-08-04 jrmu the-empty-environment)))
450 665c255d 2023-08-04 jrmu (define-variable! 'true true initial-env)
451 665c255d 2023-08-04 jrmu (define-variable! 'false false initial-env)
452 665c255d 2023-08-04 jrmu initial-env))
453 665c255d 2023-08-04 jrmu (define the-global-environment (setup-environment))
454 665c255d 2023-08-04 jrmu
455 665c255d 2023-08-04 jrmu ;; auxiliary
456 665c255d 2023-08-04 jrmu (define (test-case actual expected)
457 665c255d 2023-08-04 jrmu (newline)
458 665c255d 2023-08-04 jrmu (display "Actual: ")
459 665c255d 2023-08-04 jrmu (display actual)
460 665c255d 2023-08-04 jrmu (newline)
461 665c255d 2023-08-04 jrmu (display "Expected: ")
462 665c255d 2023-08-04 jrmu (display expected)
463 665c255d 2023-08-04 jrmu (newline))
464 665c255d 2023-08-04 jrmu (define (geval exp) ;; eval globally
465 665c255d 2023-08-04 jrmu (eval exp the-global-environment))
466 665c255d 2023-08-04 jrmu (define (test-eval exp expected)
467 665c255d 2023-08-04 jrmu (test-case (geval exp) expected))
468 665c255d 2023-08-04 jrmu
469 665c255d 2023-08-04 jrmu ;; Exercise 4.15. Given a one-argument procedure p and an object a, p is said to ``halt'' on a if evaluating the expression (p a) returns a value (as opposed to terminating with an error message or running forever). Show that it is impossible to write a procedure halts? that correctly determines whether p halts on a for any procedure p and object a. Use the following reasoning: If you had such a procedure halts?, you could implement the following program:
470 665c255d 2023-08-04 jrmu
471 665c255d 2023-08-04 jrmu (define (run-forever) (run-forever))
472 665c255d 2023-08-04 jrmu
473 665c255d 2023-08-04 jrmu (define (try p)
474 665c255d 2023-08-04 jrmu (if (halts? p p)
475 665c255d 2023-08-04 jrmu (run-forever)
476 665c255d 2023-08-04 jrmu 'halted))
477 665c255d 2023-08-04 jrmu
478 665c255d 2023-08-04 jrmu ;; Now consider evaluating the expression (try try) and show that any possible outcome (either halting or running forever) violates the intended behavior of halts?.23
479 665c255d 2023-08-04 jrmu
480 665c255d 2023-08-04 jrmu ;; If (try try) halts, (halts? try try) will be true. But then, according to the definition of try above, (try try) will run forever.
481 665c255d 2023-08-04 jrmu
482 665c255d 2023-08-04 jrmu ;; On the other hand, if (try try) does not halt, then (halts? try try) will be false. However, according to the definition of try above, this means that (try try) will return 'halted and therefore halt.
483 665c255d 2023-08-04 jrmu
484 665c255d 2023-08-04 jrmu ;; test-suite
485 665c255d 2023-08-04 jrmu
486 665c255d 2023-08-04 jrmu ;; procedure definitions
487 665c255d 2023-08-04 jrmu
488 665c255d 2023-08-04 jrmu (geval
489 665c255d 2023-08-04 jrmu '(define (assoc key records)
490 665c255d 2023-08-04 jrmu (cond ((null? records) false)
491 665c255d 2023-08-04 jrmu ((equal? key (caar records)) (car records))
492 665c255d 2023-08-04 jrmu (else (assoc key (cdr records))))))
493 665c255d 2023-08-04 jrmu
494 665c255d 2023-08-04 jrmu (geval
495 665c255d 2023-08-04 jrmu '(define (map proc list)
496 665c255d 2023-08-04 jrmu (if (null? list)
497 665c255d 2023-08-04 jrmu '()
498 665c255d 2023-08-04 jrmu (cons (proc (car list))
499 665c255d 2023-08-04 jrmu (map proc (cdr list))))))
500 665c255d 2023-08-04 jrmu
501 665c255d 2023-08-04 jrmu (geval
502 665c255d 2023-08-04 jrmu '(define (accumulate op initial sequence)
503 665c255d 2023-08-04 jrmu (if (null? sequence)
504 665c255d 2023-08-04 jrmu initial
505 665c255d 2023-08-04 jrmu (op (car sequence)
506 665c255d 2023-08-04 jrmu (accumulate op initial (cdr sequence))))))
507 665c255d 2023-08-04 jrmu
508 665c255d 2023-08-04 jrmu ;; all special forms
509 665c255d 2023-08-04 jrmu (test-eval '(begin 5 6) 6)
510 665c255d 2023-08-04 jrmu (test-eval '10 10)
511 665c255d 2023-08-04 jrmu (geval '(define x 3))
512 665c255d 2023-08-04 jrmu (test-eval 'x 3)
513 665c255d 2023-08-04 jrmu (test-eval '(set! x -25) 'ok)
514 665c255d 2023-08-04 jrmu (test-eval 'x -25)
515 665c255d 2023-08-04 jrmu (geval '(define z (lambda (x y) (+ x (* x y)))))
516 665c255d 2023-08-04 jrmu (test-eval '(z 3 4) 15)
517 665c255d 2023-08-04 jrmu (test-eval '(cond ((= x -2) 'x=-2)
518 665c255d 2023-08-04 jrmu ((= x -25) 'x=-25)
519 665c255d 2023-08-04 jrmu (else 'failed))
520 665c255d 2023-08-04 jrmu 'x=-25)
521 665c255d 2023-08-04 jrmu (test-eval '(if true false true) false)
522 665c255d 2023-08-04 jrmu (test-eval
523 665c255d 2023-08-04 jrmu '(let ((x 4) (y 7))
524 665c255d 2023-08-04 jrmu (+ x y (* x y)))
525 665c255d 2023-08-04 jrmu (+ 4 7 (* 4 7)))
526 665c255d 2023-08-04 jrmu
527 665c255d 2023-08-04 jrmu
528 665c255d 2023-08-04 jrmu ;; and/or
529 665c255d 2023-08-04 jrmu (geval '(define x (+ 3 8)))
530 665c255d 2023-08-04 jrmu (test-eval '(and 0 true x) 11)
531 665c255d 2023-08-04 jrmu (test-eval '(and 0 true x false) false)
532 665c255d 2023-08-04 jrmu (test-eval '(and 0 true x (set! x -2) false) false)
533 665c255d 2023-08-04 jrmu (test-eval 'x -2)
534 665c255d 2023-08-04 jrmu (test-eval '(and 0 true x false (set! x -5)) false)
535 665c255d 2023-08-04 jrmu (test-eval 'x -2)
536 665c255d 2023-08-04 jrmu (test-eval '(or false (set! x 25)) 'ok)
537 665c255d 2023-08-04 jrmu (test-eval 'x 25)
538 665c255d 2023-08-04 jrmu (test-eval '(or (set! x 2) (set! x 4)) 'ok)
539 665c255d 2023-08-04 jrmu (test-eval 'x 2)
540 665c255d 2023-08-04 jrmu (test-eval '(or false (set! x 25) true false) 'ok)
541 665c255d 2023-08-04 jrmu (test-eval 'x 25)
542 665c255d 2023-08-04 jrmu (test-eval '(or ((lambda (x) x) 5)) 5)
543 665c255d 2023-08-04 jrmu (test-eval '(or (begin (set! x (+ x 1)) x)) 26)
544 665c255d 2023-08-04 jrmu
545 665c255d 2023-08-04 jrmu
546 665c255d 2023-08-04 jrmu ;; cond
547 665c255d 2023-08-04 jrmu
548 665c255d 2023-08-04 jrmu (test-eval
549 665c255d 2023-08-04 jrmu '(cond ((assoc 'b '((a 1) (b 2))) => cadr)
550 665c255d 2023-08-04 jrmu (else false))
551 665c255d 2023-08-04 jrmu 2)
552 665c255d 2023-08-04 jrmu
553 665c255d 2023-08-04 jrmu (test-eval
554 665c255d 2023-08-04 jrmu '(cond ((= 3 4) 'not-true)
555 665c255d 2023-08-04 jrmu ((= (* 2 4) 3) 'also-false)
556 665c255d 2023-08-04 jrmu ((map (lambda (x)
557 665c255d 2023-08-04 jrmu (* x (+ x 1)))
558 665c255d 2023-08-04 jrmu '(2 4 1 9))
559 665c255d 2023-08-04 jrmu =>
560 665c255d 2023-08-04 jrmu (lambda (x)
561 665c255d 2023-08-04 jrmu (accumulate + 0 x)))
562 665c255d 2023-08-04 jrmu (else 'never-reach))
563 665c255d 2023-08-04 jrmu 118)
564 665c255d 2023-08-04 jrmu ;; '(6 20 2 90)
565 665c255d 2023-08-04 jrmu
566 665c255d 2023-08-04 jrmu
567 665c255d 2023-08-04 jrmu ;; procedure definition and application
568 665c255d 2023-08-04 jrmu (geval
569 665c255d 2023-08-04 jrmu '(define (factorial n)
570 665c255d 2023-08-04 jrmu (if (= n 0)
571 665c255d 2023-08-04 jrmu 1
572 665c255d 2023-08-04 jrmu (* n (factorial (- n 1))))))
573 665c255d 2023-08-04 jrmu (test-eval '(factorial 5) 120)
574 665c255d 2023-08-04 jrmu
575 665c255d 2023-08-04 jrmu ;; map
576 665c255d 2023-08-04 jrmu
577 665c255d 2023-08-04 jrmu (test-eval
578 665c255d 2023-08-04 jrmu '(map (lambda (x)
579 665c255d 2023-08-04 jrmu (* x (+ x 1)))
580 665c255d 2023-08-04 jrmu '(2 1 4 2 8 3))
581 665c255d 2023-08-04 jrmu '(6 2 20 6 72 12))
582 665c255d 2023-08-04 jrmu ;; accumulate
583 665c255d 2023-08-04 jrmu
584 665c255d 2023-08-04 jrmu (test-eval
585 665c255d 2023-08-04 jrmu '(accumulate + 0 '(1 2 3 4 5))
586 665c255d 2023-08-04 jrmu 15)
587 665c255d 2023-08-04 jrmu
588 665c255d 2023-08-04 jrmu ;; make-let
589 665c255d 2023-08-04 jrmu (test-eval
590 665c255d 2023-08-04 jrmu (make-let '(x y) '(3 5) '((+ x y)))
591 665c255d 2023-08-04 jrmu 8)
592 665c255d 2023-08-04 jrmu (test-eval
593 665c255d 2023-08-04 jrmu '(let ()
594 665c255d 2023-08-04 jrmu 5)
595 665c255d 2023-08-04 jrmu 5)
596 665c255d 2023-08-04 jrmu (test-eval
597 665c255d 2023-08-04 jrmu '(let ((x 3))
598 665c255d 2023-08-04 jrmu x)
599 665c255d 2023-08-04 jrmu 3)
600 665c255d 2023-08-04 jrmu (test-eval
601 665c255d 2023-08-04 jrmu '(let ((x 3)
602 665c255d 2023-08-04 jrmu (y 5))
603 665c255d 2023-08-04 jrmu (+ x y))
604 665c255d 2023-08-04 jrmu 8)
605 665c255d 2023-08-04 jrmu (test-eval
606 665c255d 2023-08-04 jrmu '(let ((x 3)
607 665c255d 2023-08-04 jrmu (y 2))
608 665c255d 2023-08-04 jrmu (+ (let ((x (+ y 2))
609 665c255d 2023-08-04 jrmu (y x))
610 665c255d 2023-08-04 jrmu (* x y))
611 665c255d 2023-08-04 jrmu x y))
612 665c255d 2023-08-04 jrmu (+ (* 4 3) 3 2))
613 665c255d 2023-08-04 jrmu (test-eval
614 665c255d 2023-08-04 jrmu '(let ((x 6)
615 665c255d 2023-08-04 jrmu (y (let ((x 2))
616 665c255d 2023-08-04 jrmu (+ x 3)))
617 665c255d 2023-08-04 jrmu (z (let ((a (* 3 2)))
618 665c255d 2023-08-04 jrmu (+ a 3))))
619 665c255d 2023-08-04 jrmu (+ x y z))
620 665c255d 2023-08-04 jrmu (+ 6 5 9))
621 665c255d 2023-08-04 jrmu
622 665c255d 2023-08-04 jrmu
623 665c255d 2023-08-04 jrmu ;; let*
624 665c255d 2023-08-04 jrmu
625 665c255d 2023-08-04 jrmu (test-eval
626 665c255d 2023-08-04 jrmu '(let* ((x 3)
627 665c255d 2023-08-04 jrmu (y (+ x 2))
628 665c255d 2023-08-04 jrmu (z (+ x y 5)))
629 665c255d 2023-08-04 jrmu (* x z))
630 665c255d 2023-08-04 jrmu 39)
631 665c255d 2023-08-04 jrmu
632 665c255d 2023-08-04 jrmu (test-eval
633 665c255d 2023-08-04 jrmu '(let* ()
634 665c255d 2023-08-04 jrmu 5)
635 665c255d 2023-08-04 jrmu 5)
636 665c255d 2023-08-04 jrmu (test-eval
637 665c255d 2023-08-04 jrmu '(let* ((x 3))
638 665c255d 2023-08-04 jrmu (let* ((y 5))
639 665c255d 2023-08-04 jrmu (+ x y)))
640 665c255d 2023-08-04 jrmu 8)
641 665c255d 2023-08-04 jrmu
642 665c255d 2023-08-04 jrmu (test-eval
643 665c255d 2023-08-04 jrmu '(let* ((x 3)
644 665c255d 2023-08-04 jrmu (y (+ x 1)))
645 665c255d 2023-08-04 jrmu (+ (let* ((x (+ y 2))
646 665c255d 2023-08-04 jrmu (y x))
647 665c255d 2023-08-04 jrmu (* x y))
648 665c255d 2023-08-04 jrmu x y))
649 665c255d 2023-08-04 jrmu (+ (* 6 6) 3 4))
650 665c255d 2023-08-04 jrmu (test-eval
651 665c255d 2023-08-04 jrmu '(let* ((x 6)
652 665c255d 2023-08-04 jrmu (y (let* ((x 2)
653 665c255d 2023-08-04 jrmu (a (let* ((x (* 3 x)))
654 665c255d 2023-08-04 jrmu (+ x 2))))
655 665c255d 2023-08-04 jrmu (+ x a)))
656 665c255d 2023-08-04 jrmu (z (+ x y)))
657 665c255d 2023-08-04 jrmu (+ x y z))
658 665c255d 2023-08-04 jrmu 32)
659 665c255d 2023-08-04 jrmu
660 665c255d 2023-08-04 jrmu ;; named-let
661 665c255d 2023-08-04 jrmu
662 665c255d 2023-08-04 jrmu (test-eval
663 665c255d 2023-08-04 jrmu '(let eight ()
664 665c255d 2023-08-04 jrmu 5
665 665c255d 2023-08-04 jrmu 7
666 665c255d 2023-08-04 jrmu 8)
667 665c255d 2023-08-04 jrmu 8)
668 665c255d 2023-08-04 jrmu (test-eval
669 665c255d 2023-08-04 jrmu '(let loop ((count 0))
670 665c255d 2023-08-04 jrmu (if (= 100 count)
671 665c255d 2023-08-04 jrmu count
672 665c255d 2023-08-04 jrmu (loop (+ count 1))))
673 665c255d 2023-08-04 jrmu 100)
674 665c255d 2023-08-04 jrmu (geval
675 665c255d 2023-08-04 jrmu '(define (prime? x)
676 665c255d 2023-08-04 jrmu (let prime-iter ((i 2))
677 665c255d 2023-08-04 jrmu (cond ((> (* i i) x) true)
678 665c255d 2023-08-04 jrmu ((= (remainder x i) 0) false)
679 665c255d 2023-08-04 jrmu (else (prime-iter (+ i 1)))))))
680 665c255d 2023-08-04 jrmu (test-eval
681 665c255d 2023-08-04 jrmu '(let primes ((x 2)
682 665c255d 2023-08-04 jrmu (n 20))
683 665c255d 2023-08-04 jrmu (cond ((= n 0) '())
684 665c255d 2023-08-04 jrmu ((prime? x)
685 665c255d 2023-08-04 jrmu (cons x
686 665c255d 2023-08-04 jrmu (primes (+ x 1) (- n 1))))
687 665c255d 2023-08-04 jrmu (else (primes (+ x 1) n))))
688 665c255d 2023-08-04 jrmu '(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71))
689 665c255d 2023-08-04 jrmu
690 665c255d 2023-08-04 jrmu (geval
691 665c255d 2023-08-04 jrmu '(define (fib n)
692 665c255d 2023-08-04 jrmu (let fib-iter ((a 1)
693 665c255d 2023-08-04 jrmu (b 0)
694 665c255d 2023-08-04 jrmu (count n))
695 665c255d 2023-08-04 jrmu (if (= count 0)
696 665c255d 2023-08-04 jrmu b
697 665c255d 2023-08-04 jrmu (fib-iter (+ a b) a (- count 1))))))
698 665c255d 2023-08-04 jrmu (test-eval '(fib 19) 4181)
699 665c255d 2023-08-04 jrmu
700 665c255d 2023-08-04 jrmu ;; do-loop
701 665c255d 2023-08-04 jrmu (test-eval
702 665c255d 2023-08-04 jrmu '(let ((y 0))
703 665c255d 2023-08-04 jrmu (do ((x 0 (+ x 1)))
704 665c255d 2023-08-04 jrmu ((= x 5) y)
705 665c255d 2023-08-04 jrmu (set! y (+ y 1))))
706 665c255d 2023-08-04 jrmu 5)
707 665c255d 2023-08-04 jrmu (test-eval
708 665c255d 2023-08-04 jrmu '(do ()
709 665c255d 2023-08-04 jrmu (true))
710 665c255d 2023-08-04 jrmu true)
711 665c255d 2023-08-04 jrmu (test-eval
712 665c255d 2023-08-04 jrmu '(do ()
713 665c255d 2023-08-04 jrmu (true 5))
714 665c255d 2023-08-04 jrmu 5)
715 665c255d 2023-08-04 jrmu (test-eval
716 665c255d 2023-08-04 jrmu '(let ((y 0))
717 665c255d 2023-08-04 jrmu (do ()
718 665c255d 2023-08-04 jrmu ((= y 5) y)
719 665c255d 2023-08-04 jrmu (set! y (+ y 1))))
720 665c255d 2023-08-04 jrmu 5)
721 665c255d 2023-08-04 jrmu
722 665c255d 2023-08-04 jrmu (test-eval
723 665c255d 2023-08-04 jrmu '(do ((y '(1 2 3 4)))
724 665c255d 2023-08-04 jrmu ((null? y))
725 665c255d 2023-08-04 jrmu (set! y (cdr y)))
726 665c255d 2023-08-04 jrmu true)
727 665c255d 2023-08-04 jrmu (test-eval
728 665c255d 2023-08-04 jrmu '(let ((y 0))
729 665c255d 2023-08-04 jrmu (do ((x 0 (+ x 1)))
730 665c255d 2023-08-04 jrmu ((= x 5) y)
731 665c255d 2023-08-04 jrmu (set! y (+ y 1))))
732 665c255d 2023-08-04 jrmu 5)
733 665c255d 2023-08-04 jrmu (test-eval
734 665c255d 2023-08-04 jrmu '(let ((x '(1 3 5 7 9)))
735 665c255d 2023-08-04 jrmu (do ((x x (cdr x))
736 665c255d 2023-08-04 jrmu (sum 0 (+ sum (car x))))
737 665c255d 2023-08-04 jrmu ((null? x) sum)))
738 665c255d 2023-08-04 jrmu 25)
739 665c255d 2023-08-04 jrmu (test-eval
740 665c255d 2023-08-04 jrmu '(let ((z '()))
741 665c255d 2023-08-04 jrmu (do ((x '(1 2 3 4) (cdr x))
742 665c255d 2023-08-04 jrmu (y '(1 2 3 4 5 6 7 8) (cddr y)))
743 665c255d 2023-08-04 jrmu ((null? x) y x z)
744 665c255d 2023-08-04 jrmu (set! z (cons (car x) z))))
745 665c255d 2023-08-04 jrmu '(4 3 2 1))
746 665c255d 2023-08-04 jrmu
747 665c255d 2023-08-04 jrmu ;; make-unbound!
748 665c255d 2023-08-04 jrmu
749 665c255d 2023-08-04 jrmu (test-eval
750 665c255d 2023-08-04 jrmu '(let ((x 3))
751 665c255d 2023-08-04 jrmu (let ((x 5))
752 665c255d 2023-08-04 jrmu (make-unbound! x)
753 665c255d 2023-08-04 jrmu (* x x)))
754 665c255d 2023-08-04 jrmu 9)
755 665c255d 2023-08-04 jrmu
756 665c255d 2023-08-04 jrmu (test-eval
757 665c255d 2023-08-04 jrmu '(let ((x 3))
758 665c255d 2023-08-04 jrmu (let ((x 5))
759 665c255d 2023-08-04 jrmu (define y x)
760 665c255d 2023-08-04 jrmu (make-unbound! x)
761 665c255d 2023-08-04 jrmu (* y x)))
762 665c255d 2023-08-04 jrmu 15)
763 665c255d 2023-08-04 jrmu
764 665c255d 2023-08-04 jrmu (test-eval
765 665c255d 2023-08-04 jrmu '(let ((y -1) (x 3))
766 665c255d 2023-08-04 jrmu (let ((y 0.5) (x 5))
767 665c255d 2023-08-04 jrmu (define a x)
768 665c255d 2023-08-04 jrmu (define b y)
769 665c255d 2023-08-04 jrmu (make-unbound! x)
770 665c255d 2023-08-04 jrmu (make-unbound! y)
771 665c255d 2023-08-04 jrmu (* a b x y)))
772 665c255d 2023-08-04 jrmu (* 5 3 -1 0.5))
773 665c255d 2023-08-04 jrmu
774 665c255d 2023-08-04 jrmu (test-eval
775 665c255d 2023-08-04 jrmu '(let ((x 3) (y 4))
776 665c255d 2023-08-04 jrmu (let ((x 5))
777 665c255d 2023-08-04 jrmu (make-unbound! x)
778 665c255d 2023-08-04 jrmu (+ x 4)))
779 665c255d 2023-08-04 jrmu 7)
780 665c255d 2023-08-04 jrmu
781 665c255d 2023-08-04 jrmu (test-eval
782 665c255d 2023-08-04 jrmu '(let ((a 1) (b 2) (c 3) (d 4))
783 665c255d 2023-08-04 jrmu (make-unbound! b)
784 665c255d 2023-08-04 jrmu (+ a c d))
785 665c255d 2023-08-04 jrmu (+ 1 3 4))
786 665c255d 2023-08-04 jrmu
787 665c255d 2023-08-04 jrmu (test-eval
788 665c255d 2023-08-04 jrmu '(let ((x 4) (y 5))
789 665c255d 2023-08-04 jrmu (let ((a 1) (b 2) (c 3))
790 665c255d 2023-08-04 jrmu (let ((x (+ a b)) (y (+ c a)))
791 665c255d 2023-08-04 jrmu (make-unbound! x)
792 665c255d 2023-08-04 jrmu (let ((a x) (b (+ x y)))
793 665c255d 2023-08-04 jrmu (define z b)
794 665c255d 2023-08-04 jrmu (make-unbound! b)
795 665c255d 2023-08-04 jrmu (* (+ a z)
796 665c255d 2023-08-04 jrmu (+ a b y))))))
797 665c255d 2023-08-04 jrmu (* (+ 4 8)
798 665c255d 2023-08-04 jrmu (+ 4 2 4)))