https://github.com/akkartik/mu/blob/main/shell/evaluate.mu
1
2
3
4
5 fn evaluate _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell), call-number: int {
6
7 check-stack
8 {
9 var screen-cell/eax: (addr handle cell) <- copy screen-cell
10 compare screen-cell, 0
11 break-if-=
12 var screen-cell-addr/eax: (addr cell) <- lookup *screen-cell
13 compare screen-cell-addr, 0
14 break-if-=
15
16 show-stack-state
17 }
18
19 {
20 compare trace, 0
21 break-if-=
22 var error?/eax: boolean <- has-errors? trace
23 compare error?, 0/false
24 break-if-=
25 return
26 }
27 var in-ah/esi: (addr handle cell) <- copy _in-ah
28
29 {
30 compare screen-cell, 0
31 break-if-=
32 var tmp/eax: int <- copy call-number
33 tmp <- and 0xf
34 compare tmp, 0
35 break-if-!=
36 var screen-cell/eax: (addr handle cell) <- copy screen-cell
37 var screen-cell-addr/eax: (addr cell) <- lookup *screen-cell
38 compare screen-cell-addr, 0
39 break-if-=
40 var screen-obj-ah/eax: (addr handle screen) <- get screen-cell-addr, screen-data
41 var screen-obj/eax: (addr screen) <- lookup *screen-obj-ah
42 compare screen-obj, 0
43 break-if-=
44 var y/ecx: int <- render-screen 0/screen, screen-obj, 0x70/xmin, 1/ymin
45 }
46
47
48
49
50
51
52 +-- 14 lines: # trace "evaluate " in " in environment " env -----------------------------------------------------------------------------------------------------------------------------
66 trace-lower trace
67 var in/eax: (addr cell) <- lookup *in-ah
68 {
69 var nil?/eax: boolean <- nil? in
70 compare nil?, 0/false
71 break-if-=
72
73 trace-text trace, "eval", "nil"
74 copy-object _in-ah, _out-ah
75 trace-higher trace
76 return
77 }
78 var in-type/ecx: (addr int) <- get in, type
79 compare *in-type, 1/number
80 {
81 break-if-!=
82
83 trace-text trace, "eval", "number"
84 copy-object _in-ah, _out-ah
85 trace-higher trace
86 return
87 }
88 compare *in-type, 3/stream
89 {
90 break-if-!=
91
92 trace-text trace, "eval", "stream"
93 copy-object _in-ah, _out-ah
94 trace-higher trace
95 return
96 }
97 compare *in-type, 2/symbol
98 {
99 break-if-!=
100 trace-text trace, "eval", "symbol"
101 debug-print "a", 7/fg, 0/bg
102 lookup-symbol in, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell
103 debug-print "z", 7/fg, 0/bg
104 trace-higher trace
105 return
106 }
107 compare *in-type, 5/screen
108 {
109 break-if-!=
110 trace-text trace, "eval", "screen"
111 copy-object _in-ah, _out-ah
112 trace-higher trace
113 return
114 }
115 compare *in-type, 6/keyboard
116 {
117 break-if-!=
118 trace-text trace, "eval", "keyboard"
119 copy-object _in-ah, _out-ah
120 trace-higher trace
121 return
122 }
123
124 $evaluate:literal-function: {
125
126 var expr/esi: (addr cell) <- copy in
127 var in/edx: (addr cell) <- copy in
128 var first-ah/ecx: (addr handle cell) <- get in, left
129 var first/eax: (addr cell) <- lookup *first-ah
130 var litfn?/eax: boolean <- litfn? first
131 compare litfn?, 0/false
132 break-if-=
133 trace-text trace, "eval", "literal function"
134 copy-object _in-ah, _out-ah
135 trace-higher trace
136 return
137 }
138 $evaluate:literal-macro: {
139
140 var expr/esi: (addr cell) <- copy in
141 var in/edx: (addr cell) <- copy in
142 var first-ah/ecx: (addr handle cell) <- get in, left
143 var first/eax: (addr cell) <- lookup *first-ah
144 var litmac?/eax: boolean <- litmac? first
145 compare litmac?, 0/false
146 break-if-=
147 trace-text trace, "eval", "literal macro"
148 copy-object _in-ah, _out-ah
149 trace-higher trace
150 return
151 }
152 $evaluate:anonymous-function: {
153
154 var expr/esi: (addr cell) <- copy in
155 var in/edx: (addr cell) <- copy in
156 var first-ah/ecx: (addr handle cell) <- get in, left
157 var first/eax: (addr cell) <- lookup *first-ah
158 var fn?/eax: boolean <- fn? first
159 compare fn?, 0/false
160 break-if-=
161
162 trace-text trace, "eval", "anonymous function"
163 var rest-ah/eax: (addr handle cell) <- get in, right
164 var tmp: (handle cell)
165 var tmp-ah/edi: (addr handle cell) <- address tmp
166 new-pair tmp-ah, env-h, *rest-ah
167 var litfn: (handle cell)
168 var litfn-ah/eax: (addr handle cell) <- address litfn
169 new-symbol litfn-ah, "litfn"
170 new-pair _out-ah, *litfn-ah, *tmp-ah
171 trace-higher trace
172 return
173 }
174
175 $evaluate:quote: {
176
177 var expr/esi: (addr cell) <- copy in
178
179 var first-ah/ecx: (addr handle cell) <- get in, left
180 var rest-ah/edx: (addr handle cell) <- get in, right
181 var first/eax: (addr cell) <- lookup *first-ah
182 var quote?/eax: boolean <- symbol-equal? first, "'"
183 compare quote?, 0/false
184 break-if-=
185
186 trace-text trace, "eval", "quote"
187 copy-object rest-ah, _out-ah
188 trace-higher trace
189 return
190 }
191 $evaluate:backquote: {
192
193 var expr/esi: (addr cell) <- copy in
194
195 var first-ah/ecx: (addr handle cell) <- get in, left
196 var rest-ah/edx: (addr handle cell) <- get in, right
197 var first/eax: (addr cell) <- lookup *first-ah
198 var backquote?/eax: boolean <- symbol-equal? first, "`"
199 compare backquote?, 0/false
200 break-if-=
201
202 trace-text trace, "eval", "backquote"
203 debug-print "`(", 7/fg, 0/bg
204 evaluate-backquote rest-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
205 debug-print ")", 7/fg, 0/bg
206 trace-higher trace
207 return
208 }
209 $evaluate:def: {
210
211 var expr/esi: (addr cell) <- copy in
212
213 var first-ah/ecx: (addr handle cell) <- get in, left
214 var rest-ah/edx: (addr handle cell) <- get in, right
215 var first/eax: (addr cell) <- lookup *first-ah
216 var def?/eax: boolean <- symbol-equal? first, "def"
217 compare def?, 0/false
218 break-if-=
219
220 trace-text trace, "eval", "def"
221 trace-text trace, "eval", "evaluating second arg"
222 var rest/eax: (addr cell) <- lookup *rest-ah
223 var first-arg-ah/ecx: (addr handle cell) <- get rest, left
224 {
225 var first-arg/eax: (addr cell) <- lookup *first-arg-ah
226 var first-arg-type/eax: (addr int) <- get first-arg, type
227 compare *first-arg-type, 2/symbol
228 break-if-=
229 error trace, "first arg to def must be a symbol"
230 trace-higher trace
231 return
232 }
233 rest-ah <- get rest, right
234 rest <- lookup *rest-ah
235 var second-arg-ah/edx: (addr handle cell) <- get rest, left
236 debug-print "P", 4/fg, 0/bg
237 increment call-number
238 evaluate second-arg-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
239 debug-print "Q", 4/fg, 0/bg
240 trace-text trace, "eval", "saving global binding"
241 var first-arg/eax: (addr cell) <- lookup *first-arg-ah
242 var first-arg-data-ah/eax: (addr handle stream byte) <- get first-arg, text-data
243 var first-arg-data/eax: (addr stream byte) <- lookup *first-arg-data-ah
244 var tmp-string: (handle array byte)
245 var tmp-ah/edx: (addr handle array byte) <- address tmp-string
246 rewind-stream first-arg-data
247 stream-to-array first-arg-data, tmp-ah
248 var first-arg-data-string/eax: (addr array byte) <- lookup *tmp-ah
249 var out-ah/edi: (addr handle cell) <- copy _out-ah
250 assign-or-create-global globals, first-arg-data-string, *out-ah, trace
251 trace-higher trace
252 return
253 }
254 $evaluate:set: {
255
256 var expr/esi: (addr cell) <- copy in
257
258 var first-ah/ecx: (addr handle cell) <- get in, left
259 var rest-ah/edx: (addr handle cell) <- get in, right
260 var first/eax: (addr cell) <- lookup *first-ah
261 var set?/eax: boolean <- symbol-equal? first, "set"
262 compare set?, 0/false
263 break-if-=
264
265 trace-text trace, "eval", "set"
266 trace-text trace, "eval", "evaluating second arg"
267 var rest/eax: (addr cell) <- lookup *rest-ah
268 var first-arg-ah/ecx: (addr handle cell) <- get rest, left
269 {
270 var first-arg/eax: (addr cell) <- lookup *first-arg-ah
271 var first-arg-type/eax: (addr int) <- get first-arg, type
272 compare *first-arg-type, 2/symbol
273 break-if-=
274 error trace, "first arg to set must be a symbol"
275 trace-higher trace
276 return
277 }
278 rest-ah <- get rest, right
279 rest <- lookup *rest-ah
280 var second-arg-ah/edx: (addr handle cell) <- get rest, left
281 debug-print "P", 4/fg, 0/bg
282 increment call-number
283 evaluate second-arg-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
284 debug-print "Q", 4/fg, 0/bg
285 trace-text trace, "eval", "mutating binding"
286 var first-arg/eax: (addr cell) <- lookup *first-arg-ah
287 var first-arg-data-ah/eax: (addr handle stream byte) <- get first-arg, text-data
288 var first-arg-data/eax: (addr stream byte) <- lookup *first-arg-data-ah
289 mutate-binding first-arg-data, _out-ah, env-h, globals, trace
290 trace-higher trace
291 return
292 }
293 $evaluate:and: {
294 var expr/esi: (addr cell) <- copy in
295
296 var first-ah/ecx: (addr handle cell) <- get in, left
297 var rest-ah/edx: (addr handle cell) <- get in, right
298 var first/eax: (addr cell) <- lookup *first-ah
299 var and?/eax: boolean <- symbol-equal? first, "and"
300 compare and?, 0/false
301 break-if-=
302
303 trace-text trace, "eval", "and"
304 trace-text trace, "eval", "evaluating first arg"
305 var rest/eax: (addr cell) <- lookup *rest-ah
306 var first-arg-ah/ecx: (addr handle cell) <- get rest, left
307 debug-print "R2", 4/fg, 0/bg
308 increment call-number
309 evaluate first-arg-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
310 debug-print "S2", 4/fg, 0/bg
311
312 var out-ah/eax: (addr handle cell) <- copy _out-ah
313 var out/eax: (addr cell) <- lookup *out-ah
314 var nil?/eax: boolean <- nil? out
315 compare nil?, 0/false
316 {
317 break-if-=
318 return
319 }
320 var rest/eax: (addr cell) <- lookup *rest-ah
321 rest-ah <- get rest, right
322 rest <- lookup *rest-ah
323 var second-ah/eax: (addr handle cell) <- get rest, left
324 debug-print "T2", 4/fg, 0/bg
325 increment call-number
326 evaluate second-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
327 debug-print "U2", 4/fg, 0/bg
328 trace-higher trace
329 return
330 }
331 $evaluate:or: {
332 var expr/esi: (addr cell) <- copy in
333
334 var first-ah/ecx: (addr handle cell) <- get in, left
335 var rest-ah/edx: (addr handle cell) <- get in, right
336 var first/eax: (addr cell) <- lookup *first-ah
337 var or?/eax: boolean <- symbol-equal? first, "or"
338 compare or?, 0/false
339 break-if-=
340
341 trace-text trace, "eval", "or"
342 trace-text trace, "eval", "evaluating first arg"
343 var rest/eax: (addr cell) <- lookup *rest-ah
344 var first-arg-ah/ecx: (addr handle cell) <- get rest, left
345 debug-print "R2", 4/fg, 0/bg
346 increment call-number
347 evaluate first-arg-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
348 debug-print "S2", 4/fg, 0/bg
349
350 var out-ah/eax: (addr handle cell) <- copy _out-ah
351 var out/eax: (addr cell) <- lookup *out-ah
352 var nil?/eax: boolean <- nil? out
353 compare nil?, 0/false
354 {
355 break-if-!=
356 return
357 }
358 var rest/eax: (addr cell) <- lookup *rest-ah
359 rest-ah <- get rest, right
360 rest <- lookup *rest-ah
361 var second-ah/eax: (addr handle cell) <- get rest, left
362 debug-print "T2", 4/fg, 0/bg
363 increment call-number
364 evaluate second-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
365 debug-print "U2", 4/fg, 0/bg
366 trace-higher trace
367 return
368 }
369 $evaluate:if: {
370
371 var expr/esi: (addr cell) <- copy in
372
373 var first-ah/ecx: (addr handle cell) <- get in, left
374 var rest-ah/edx: (addr handle cell) <- get in, right
375 var first/eax: (addr cell) <- lookup *first-ah
376 var if?/eax: boolean <- symbol-equal? first, "if"
377 compare if?, 0/false
378 break-if-=
379
380 trace-text trace, "eval", "if"
381 trace-text trace, "eval", "evaluating first arg"
382 var rest/eax: (addr cell) <- lookup *rest-ah
383 var first-arg-ah/ecx: (addr handle cell) <- get rest, left
384 var guard-h: (handle cell)
385 var guard-ah/esi: (addr handle cell) <- address guard-h
386 debug-print "R", 4/fg, 0/bg
387 increment call-number
388 evaluate first-arg-ah, guard-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
389 debug-print "S", 4/fg, 0/bg
390 rest-ah <- get rest, right
391 rest <- lookup *rest-ah
392 var branch-ah/edi: (addr handle cell) <- get rest, left
393 var guard-a/eax: (addr cell) <- lookup *guard-ah
394 var skip-to-third-arg?/eax: boolean <- nil? guard-a
395 compare skip-to-third-arg?, 0/false
396 {
397 break-if-=
398 trace-text trace, "eval", "skipping to third arg"
399 var rest/eax: (addr cell) <- lookup *rest-ah
400 rest-ah <- get rest, right
401 rest <- lookup *rest-ah
402 branch-ah <- get rest, left
403 }
404 debug-print "T", 4/fg, 0/bg
405 increment call-number
406 evaluate branch-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
407 debug-print "U", 4/fg, 0/bg
408 trace-higher trace
409 return
410 }
411 $evaluate:while: {
412
413 var expr/esi: (addr cell) <- copy in
414
415 var first-ah/ecx: (addr handle cell) <- get in, left
416 var rest-ah/edx: (addr handle cell) <- get in, right
417 var first/eax: (addr cell) <- lookup *first-ah
418 var first-type/ecx: (addr int) <- get first, type
419 compare *first-type, 2/symbol
420 break-if-!=
421 var sym-data-ah/eax: (addr handle stream byte) <- get first, text-data
422 var sym-data/eax: (addr stream byte) <- lookup *sym-data-ah
423 var while?/eax: boolean <- stream-data-equal? sym-data, "while"
424 compare while?, 0/false
425 break-if-=
426
427 trace-text trace, "eval", "while"
428 var rest/eax: (addr cell) <- lookup *rest-ah
429 var first-arg-ah/ecx: (addr handle cell) <- get rest, left
430 rest-ah <- get rest, right
431 var guard-h: (handle cell)
432 var guard-ah/esi: (addr handle cell) <- address guard-h
433 $evaluate:while:loop-execution: {
434 {
435 compare trace, 0
436 break-if-=
437 var error?/eax: boolean <- has-errors? trace
438 compare error?, 0/false
439 break-if-!= $evaluate:while:loop-execution
440 }
441 trace-text trace, "eval", "loop termination check"
442 debug-print "V", 4/fg, 0/bg
443 increment call-number
444 evaluate first-arg-ah, guard-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
445 debug-print "W", 4/fg, 0/bg
446 var guard-a/eax: (addr cell) <- lookup *guard-ah
447 var done?/eax: boolean <- nil? guard-a
448 compare done?, 0/false
449 break-if-!=
450 evaluate-exprs rest-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
451 loop
452 }
453 trace-text trace, "eval", "loop terminated"
454 trace-higher trace
455 return
456 }
457 trace-text trace, "eval", "function call"
458 trace-text trace, "eval", "evaluating list elements"
459 trace-lower trace
460 var evaluated-list-storage: (handle cell)
461 var evaluated-list-ah/esi: (addr handle cell) <- address evaluated-list-storage
462 var curr-out-ah/edx: (addr handle cell) <- copy evaluated-list-ah
463 var curr/ecx: (addr cell) <- copy in
464 $evaluate-list:loop: {
465 allocate-pair curr-out-ah
466 var nil?/eax: boolean <- nil? curr
467 compare nil?, 0/false
468 break-if-!=
469
470 var curr-out/eax: (addr cell) <- lookup *curr-out-ah
471 var left-out-ah/edi: (addr handle cell) <- get curr-out, left
472 var left-ah/esi: (addr handle cell) <- get curr, left
473 debug-print "A", 4/fg, 0/bg
474 increment call-number
475 evaluate left-ah, left-out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
476 debug-print "B", 4/fg, 0/bg
477
478 {
479 compare trace, 0
480 break-if-!=
481 var left-out/eax: (addr cell) <- lookup *left-out-ah
482 compare left-out, 0
483 {
484 break-if-!=
485 abort "there was some error (likely in syntax): eval-list"
486 }
487 }
488
489 curr-out-ah <- get curr-out, right
490 var right-ah/eax: (addr handle cell) <- get curr, right
491 var right/eax: (addr cell) <- lookup *right-ah
492 curr <- copy right
493 loop
494 }
495 trace-higher trace
496 var evaluated-list/eax: (addr cell) <- lookup *evaluated-list-ah
497 var function-ah/ecx: (addr handle cell) <- get evaluated-list, left
498 var args-ah/edx: (addr handle cell) <- get evaluated-list, right
499 debug-print "C", 4/fg, 0/bg
500 apply function-ah, args-ah, _out-ah, globals, trace, screen-cell, keyboard-cell, call-number
501 debug-print "Y", 4/fg, 0/bg
502 trace-higher trace
503 +-- 11 lines: # trace "=> " _out-ah -----------------------------------------------------------------------------------------------------------------------------------------------------
514 debug-print "Z", 4/fg, 0/bg
515 }
516
517 fn apply _f-ah: (addr handle cell), args-ah: (addr handle cell), out: (addr handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell), call-number: int {
518 var f-ah/eax: (addr handle cell) <- copy _f-ah
519 var _f/eax: (addr cell) <- lookup *f-ah
520 var f/esi: (addr cell) <- copy _f
521
522 {
523 var f-type/eax: (addr int) <- get f, type
524 compare *f-type, 4/primitive-function
525 break-if-!=
526 apply-primitive f, args-ah, out, globals, trace
527 return
528 }
529
530 +-- 14 lines: # trace "apply anonymous function " f " in environment " env --------------------------------------------------------------------------------------------------------------
544 trace-lower trace
545 {
546 var f-type/ecx: (addr int) <- get f, type
547 compare *f-type, 0/pair
548 break-if-!=
549 var first-ah/eax: (addr handle cell) <- get f, left
550 var first/eax: (addr cell) <- lookup *first-ah
551 var litfn?/eax: boolean <- litfn? first
552 compare litfn?, 0/false
553 break-if-=
554 var rest-ah/esi: (addr handle cell) <- get f, right
555 var rest/eax: (addr cell) <- lookup *rest-ah
556 var callee-env-ah/edx: (addr handle cell) <- get rest, left
557 rest-ah <- get rest, right
558 rest <- lookup *rest-ah
559 var params-ah/ecx: (addr handle cell) <- get rest, left
560 var body-ah/eax: (addr handle cell) <- get rest, right
561 debug-print "D", 7/fg, 0/bg
562 apply-function params-ah, args-ah, body-ah, out, *callee-env-ah, globals, trace, screen-cell, keyboard-cell, call-number
563 debug-print "Y", 7/fg, 0/bg
564 trace-higher trace
565 return
566 }
567 error trace, "unknown function"
568 }
569
570 fn apply-function params-ah: (addr handle cell), args-ah: (addr handle cell), body-ah: (addr handle cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell), call-number: int {
571
572 var new-env-h: (handle cell)
573 var new-env-ah/esi: (addr handle cell) <- address new-env-h
574 push-bindings params-ah, args-ah, env-h, new-env-ah, trace
575
576 evaluate-exprs body-ah, out, new-env-h, globals, trace, screen-cell, keyboard-cell, call-number
577 }
578
579 fn evaluate-exprs _exprs-ah: (addr handle cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell), call-number: int {
580
581 var exprs-ah/ecx: (addr handle cell) <- copy _exprs-ah
582 $evaluate-exprs:loop: {
583 var exprs/eax: (addr cell) <- lookup *exprs-ah
584
585 {
586 var exprs-nil?/eax: boolean <- nil? exprs
587 compare exprs-nil?, 0/false
588 break-if-!= $evaluate-exprs:loop
589 }
590
591 {
592 var curr-ah/eax: (addr handle cell) <- get exprs, left
593 debug-print "E", 7/fg, 0/bg
594 increment call-number
595 evaluate curr-ah, out, env-h, globals, trace, screen-cell, keyboard-cell, call-number
596 debug-print "X", 7/fg, 0/bg
597 }
598
599 exprs-ah <- get exprs, right
600 loop
601 }
602
603 }
604
605
606
607
608
609
610
611
612
613
614
615
616 fn push-bindings _params-ah: (addr handle cell), _args-ah: (addr handle cell), old-env-h: (handle cell), env-ah: (addr handle cell), trace: (addr trace) {
617 var params-ah/edx: (addr handle cell) <- copy _params-ah
618 var args-ah/ebx: (addr handle cell) <- copy _args-ah
619 var _params/eax: (addr cell) <- lookup *params-ah
620 var params/esi: (addr cell) <- copy _params
621 {
622 var params-nil?/eax: boolean <- nil? params
623 compare params-nil?, 0/false
624 break-if-=
625
626 trace-text trace, "eval", "done with push-bindings"
627 copy-handle old-env-h, env-ah
628 return
629 }
630
631 +-- 16 lines: # trace "pushing bindings from " params " to " args -----------------------------------------------------------------------------------------------------------------------
647 trace-lower trace
648 var params-type/eax: (addr int) <- get params, type
649 compare *params-type, 2/symbol
650 {
651 break-if-!=
652 trace-text trace, "eval", "symbol; binding to all remaining args"
653
654 var new-binding-storage: (handle cell)
655 var new-binding-ah/eax: (addr handle cell) <- address new-binding-storage
656 new-pair new-binding-ah, *params-ah, *args-ah
657
658 new-pair env-ah, *new-binding-ah, old-env-h
659 trace-higher trace
660 return
661 }
662 compare *params-type, 0/pair
663 {
664 break-if-=
665 error trace, "cannot bind a non-symbol"
666 trace-higher trace
667 return
668 }
669 var _args/eax: (addr cell) <- lookup *args-ah
670 var args/edi: (addr cell) <- copy _args
671
672 var args-type/eax: (addr int) <- get args, type
673 compare *args-type, 0/pair
674 {
675 break-if-=
676 error trace, "args not in a proper list"
677 trace-higher trace
678 return
679 }
680 var intermediate-env-storage: (handle cell)
681 var intermediate-env-ah/edx: (addr handle cell) <- address intermediate-env-storage
682 var first-param-ah/eax: (addr handle cell) <- get params, left
683 var first-arg-ah/ecx: (addr handle cell) <- get args, left
684 push-bindings first-param-ah, first-arg-ah, old-env-h, intermediate-env-ah, trace
685 var remaining-params-ah/eax: (addr handle cell) <- get params, right
686 var remaining-args-ah/ecx: (addr handle cell) <- get args, right
687 push-bindings remaining-params-ah, remaining-args-ah, *intermediate-env-ah, env-ah, trace
688 trace-higher trace
689 }
690
691 fn lookup-symbol sym: (addr cell), out: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell) {
692
693 {
694 compare trace, 0
695 break-if-=
696 var stream-storage: (stream byte 0x800)
697 var stream/ecx: (addr stream byte) <- address stream-storage
698 write stream, "look up "
699 var sym2/eax: (addr cell) <- copy sym
700 var sym-data-ah/eax: (addr handle stream byte) <- get sym2, text-data
701 var sym-data/eax: (addr stream byte) <- lookup *sym-data-ah
702 rewind-stream sym-data
703 write-stream stream, sym-data
704 write stream, " in "
705 var env-ah/eax: (addr handle cell) <- address env-h
706 print-cell env-ah, stream, 0/no-trace
707 trace trace, "eval", stream
708 }
709 trace-lower trace
710 var _env/eax: (addr cell) <- lookup env-h
711 var env/ebx: (addr cell) <- copy _env
712
713 {
714 var env-type/ecx: (addr int) <- get env, type
715 compare *env-type, 0/pair
716 break-if-=
717 error trace, "eval found a non-list environment"
718 trace-higher trace
719 return
720 }
721
722 {
723 var env-nil?/eax: boolean <- nil? env
724 compare env-nil?, 0/false
725 break-if-=
726 debug-print "b", 7/fg, 0/bg
727 lookup-symbol-in-globals sym, out, globals, trace, screen-cell, keyboard-cell
728 debug-print "x", 7/fg, 0/bg
729 trace-higher trace
730 +-- 15 lines: # trace "=> " out " (global)" ---------------------------------------------------------------------------------------------------------------------------------------------
745 debug-print "y", 7/fg, 0/bg
746 return
747 }
748
749 var env-head-storage: (handle cell)
750 var env-head-ah/eax: (addr handle cell) <- address env-head-storage
751 car env, env-head-ah, 0/no-trace
752 var _env-head/eax: (addr cell) <- lookup *env-head-ah
753 var env-head/ecx: (addr cell) <- copy _env-head
754
755 {
756 var env-head-type/eax: (addr int) <- get env-head, type
757 compare *env-head-type, 0/pair
758 break-if-=
759 error trace, "environment is not a list of (key . value) pairs"
760 trace-higher trace
761 return
762 }
763
764 var curr-key-storage: (handle cell)
765 var curr-key-ah/eax: (addr handle cell) <- address curr-key-storage
766 car env-head, curr-key-ah, trace
767 var curr-key/eax: (addr cell) <- lookup *curr-key-ah
768
769 {
770 var curr-key-type/eax: (addr int) <- get curr-key, type
771 compare *curr-key-type, 2/symbol
772 break-if-=
773 error trace, "environment contains a binding for a non-symbol"
774 trace-higher trace
775 return
776 }
777
778 var match?/eax: boolean <- cell-isomorphic? curr-key, sym, trace
779 compare match?, 0/false
780 {
781 break-if-=
782 cdr env-head, out, 0/no-trace
783 +-- 15 lines: # trace "=> " out " (match)" ----------------------------------------------------------------------------------------------------------------------------------------------
798 trace-higher trace
799 return
800 }
801
802 var env-tail-storage: (handle cell)
803 var env-tail-ah/eax: (addr handle cell) <- address env-tail-storage
804 cdr env, env-tail-ah, trace
805 lookup-symbol sym, out, *env-tail-ah, globals, trace, screen-cell, keyboard-cell
806 trace-higher trace
807 +-- 15 lines: # trace "=> " out " (recurse)" --------------------------------------------------------------------------------------------------------------------------------------------
822 }
823
824 fn test-lookup-symbol-in-env {
825
826 var val-storage: (handle cell)
827 var val-ah/ecx: (addr handle cell) <- address val-storage
828 new-integer val-ah, 3
829 var key-storage: (handle cell)
830 var key-ah/edx: (addr handle cell) <- address key-storage
831 new-symbol key-ah, "a"
832 var env-storage: (handle cell)
833 var env-ah/ebx: (addr handle cell) <- address env-storage
834 new-pair env-ah, *key-ah, *val-ah
835
836 var nil-storage: (handle cell)
837 var nil-ah/ecx: (addr handle cell) <- address nil-storage
838 allocate-pair nil-ah
839 new-pair env-ah, *env-ah, *nil-ah
840
841 var tmp-storage: (handle cell)
842 var tmp-ah/edx: (addr handle cell) <- address tmp-storage
843 new-symbol tmp-ah, "a"
844 var in/eax: (addr cell) <- lookup *tmp-ah
845 lookup-symbol in, tmp-ah, *env-ah, 0/no-globals, 0/no-trace, 0/no-screen, 0/no-keyboard
846 var result/eax: (addr cell) <- lookup *tmp-ah
847 var result-type/edx: (addr int) <- get result, type
848 check-ints-equal *result-type, 1/number, "F - test-lookup-symbol-in-env/0"
849 var result-value-addr/eax: (addr float) <- get result, number-data
850 var result-value/eax: int <- convert *result-value-addr
851 check-ints-equal result-value, 3, "F - test-lookup-symbol-in-env/1"
852 }
853
854 fn test-lookup-symbol-in-globals {
855 var globals-storage: global-table
856 var globals/edi: (addr global-table) <- address globals-storage
857 initialize-globals globals
858
859 var nil-storage: (handle cell)
860 var nil-ah/ecx: (addr handle cell) <- address nil-storage
861 allocate-pair nil-ah
862
863 var tmp-storage: (handle cell)
864 var tmp-ah/ebx: (addr handle cell) <- address tmp-storage
865 new-symbol tmp-ah, "+"
866 var in/eax: (addr cell) <- lookup *tmp-ah
867 lookup-symbol in, tmp-ah, *nil-ah, globals, 0/no-trace, 0/no-screen, 0/no-keyboard
868 var result/eax: (addr cell) <- lookup *tmp-ah
869 var result-type/edx: (addr int) <- get result, type
870 check-ints-equal *result-type, 4/primitive-function, "F - test-lookup-symbol-in-globals/0"
871 var result-value/eax: (addr int) <- get result, index-data
872 check-ints-equal *result-value, 1/add, "F - test-lookup-symbol-in-globals/1"
873 }
874
875 fn mutate-binding name: (addr stream byte), val: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace) {
876
877 {
878 compare trace, 0
879 break-if-=
880 var stream-storage: (stream byte 0x800)
881 var stream/ecx: (addr stream byte) <- address stream-storage
882 write stream, "bind "
883 rewind-stream name
884 write-stream stream, name
885 write stream, " to "
886 print-cell val, stream, 0/no-trace
887 write stream, " in "
888 var env-ah/eax: (addr handle cell) <- address env-h
889 print-cell env-ah, stream, 0/no-trace
890 trace trace, "eval", stream
891 }
892 trace-lower trace
893 var _env/eax: (addr cell) <- lookup env-h
894 var env/ebx: (addr cell) <- copy _env
895
896 {
897 var env-type/ecx: (addr int) <- get env, type
898 compare *env-type, 0/pair
899 break-if-=
900 error trace, "eval found a non-list environment"
901 trace-higher trace
902 return
903 }
904
905 {
906 var env-nil?/eax: boolean <- nil? env
907 compare env-nil?, 0/false
908 break-if-=
909 debug-print "b", 3/fg, 0/bg
910 mutate-binding-in-globals name, val, globals, trace
911 debug-print "x", 3/fg, 0/bg
912 trace-higher trace
913 +-- 15 lines: # trace "=> " val " (global)" ---------------------------------------------------------------------------------------------------------------------------------------------
928 debug-print "y", 3/fg, 0/bg
929 return
930 }
931
932 var env-head-storage: (handle cell)
933 var env-head-ah/eax: (addr handle cell) <- address env-head-storage
934 car env, env-head-ah, 0/no-trace
935 var _env-head/eax: (addr cell) <- lookup *env-head-ah
936 var env-head/ecx: (addr cell) <- copy _env-head
937
938 {
939 var env-head-type/eax: (addr int) <- get env-head, type
940 compare *env-head-type, 0/pair
941 break-if-=
942 error trace, "environment is not a list of (key . value) pairs"
943 trace-higher trace
944 return
945 }
946
947 var curr-key-storage: (handle cell)
948 var curr-key-ah/eax: (addr handle cell) <- address curr-key-storage
949 car env-head, curr-key-ah, trace
950 var curr-key/eax: (addr cell) <- lookup *curr-key-ah
951
952 {
953 var curr-key-type/eax: (addr int) <- get curr-key, type
954 compare *curr-key-type, 2/symbol
955 break-if-=
956 error trace, "environment contains a binding for a non-symbol"
957 trace-higher trace
958 return
959 }
960
961 var curr-key-data-ah/eax: (addr handle stream byte) <- get curr-key, text-data
962 var curr-key-data/eax: (addr stream byte) <- lookup *curr-key-data-ah
963 var match?/eax: boolean <- streams-data-equal? curr-key-data, name
964 compare match?, 0/false
965 {
966 break-if-=
967 var dest/eax: (addr handle cell) <- get env-head, right
968 copy-object val, dest
969 trace-text trace, "eval", "=> done"
970 trace-higher trace
971 return
972 }
973
974 var env-tail-storage: (handle cell)
975 var env-tail-ah/eax: (addr handle cell) <- address env-tail-storage
976 cdr env, env-tail-ah, trace
977 mutate-binding name, val, *env-tail-ah, globals, trace
978 trace-higher trace
979 }
980
981 fn car _in: (addr cell), out: (addr handle cell), trace: (addr trace) {
982 trace-text trace, "eval", "car"
983 trace-lower trace
984 var in/eax: (addr cell) <- copy _in
985
986 {
987 var in-type/ecx: (addr int) <- get in, type
988 compare *in-type, 0/pair
989 break-if-=
990 error trace, "car on a non-list"
991 trace-higher trace
992 return
993 }
994
995 {
996 var in-nil?/eax: boolean <- nil? in
997 compare in-nil?, 0/false
998 break-if-=
999 error trace, "car on nil"
1000 trace-higher trace
1001 return
1002 }
1003 var in-left/eax: (addr handle cell) <- get in, left
1004 copy-object in-left, out
1005 trace-higher trace
1006 return
1007 }
1008
1009 fn cdr _in: (addr cell), out: (addr handle cell), trace: (addr trace) {
1010 trace-text trace, "eval", "cdr"
1011 trace-lower trace
1012 var in/eax: (addr cell) <- copy _in
1013
1014 {
1015 var in-type/ecx: (addr int) <- get in, type
1016 compare *in-type, 0/pair
1017 break-if-=
1018 error trace, "car on a non-list"
1019 trace-higher trace
1020 return
1021 }
1022
1023 {
1024 var in-nil?/eax: boolean <- nil? in
1025 compare in-nil?, 0/false
1026 break-if-=
1027 error trace, "car on nil"
1028 trace-higher trace
1029 return
1030 }
1031 var in-right/eax: (addr handle cell) <- get in, right
1032 copy-object in-right, out
1033 trace-higher trace
1034 return
1035 }
1036
1037 fn cell-isomorphic? _a: (addr cell), _b: (addr cell), trace: (addr trace) -> _/eax: boolean {
1038 trace-text trace, "eval", "cell-isomorphic?"
1039 trace-lower trace
1040 var a/esi: (addr cell) <- copy _a
1041 var b/edi: (addr cell) <- copy _b
1042
1043 var a-type-addr/eax: (addr int) <- get a, type
1044 var b-type-addr/ecx: (addr int) <- get b, type
1045 var b-type/ecx: int <- copy *b-type-addr
1046 compare b-type, *a-type-addr
1047 {
1048 break-if-=
1049 trace-higher trace
1050 trace-text trace, "eval", "=> false (type)"
1051 return 0/false
1052 }
1053
1054
1055 compare b-type, 1/number
1056 {
1057 break-if-!=
1058 var a-val-addr/eax: (addr float) <- get a, number-data
1059 var b-val-addr/ecx: (addr float) <- get b, number-data
1060 var a-val/xmm0: float <- copy *a-val-addr
1061 compare a-val, *b-val-addr
1062 {
1063 break-if-=
1064 trace-higher trace
1065 trace-text trace, "eval", "=> false (numbers)"
1066 return 0/false
1067 }
1068 trace-higher trace
1069 trace-text trace, "eval", "=> true (numbers)"
1070 return 1/true
1071 }
1072 $cell-isomorphic?:text-data: {
1073 {
1074 compare b-type, 2/symbol
1075 break-if-=
1076 compare b-type, 3/stream
1077 break-if-=
1078 break $cell-isomorphic?:text-data
1079 }
1080 var b-val-ah/eax: (addr handle stream byte) <- get b, text-data
1081 var _b-val/eax: (addr stream byte) <- lookup *b-val-ah
1082 var b-val/ecx: (addr stream byte) <- copy _b-val
1083 var a-val-ah/eax: (addr handle stream byte) <- get a, text-data
1084 var a-val/eax: (addr stream byte) <- lookup *a-val-ah
1085 var tmp-array: (handle array byte)
1086 var tmp-ah/edx: (addr handle array byte) <- address tmp-array
1087 rewind-stream a-val
1088 stream-to-array a-val, tmp-ah
1089 var tmp/eax: (addr array byte) <- lookup *tmp-ah
1090 var match?/eax: boolean <- stream-data-equal? b-val, tmp
1091 trace-higher trace
1092 {
1093 compare match?, 0/false
1094 break-if-=
1095 trace-text trace, "eval", "=> true (symbols)"
1096 }
1097 {
1098 compare match?, 0/false
1099 break-if-!=
1100 trace-text trace, "eval", "=> false (symbols)"
1101 }
1102 return match?
1103 }
1104
1105 compare b-type, 4/primitive
1106 {
1107 break-if-!=
1108 var a-val-addr/eax: (addr int) <- get a, index-data
1109 var b-val-addr/ecx: (addr int) <- get b, index-data
1110 var a-val/eax: int <- copy *a-val-addr
1111 compare a-val, *b-val-addr
1112 {
1113 break-if-=
1114 trace-higher trace
1115 trace-text trace, "eval", "=> false (primitives)"
1116 return 0/false
1117 }
1118 trace-higher trace
1119 trace-text trace, "eval", "=> true (primitives)"
1120 return 1/true
1121 }
1122
1123 compare b-type, 5/screen
1124 {
1125 break-if-!=
1126 var a-val-addr/eax: (addr handle screen) <- get a, screen-data
1127 var b-val-addr/ecx: (addr handle screen) <- get b, screen-data
1128 var result/eax: boolean <- handle-equal? *a-val-addr, *b-val-addr
1129 compare result, 0/false
1130 return result
1131 }
1132
1133 compare b-type, 6/keyboard
1134 {
1135 break-if-!=
1136 var a-val-addr/ecx: (addr handle gap-buffer) <- get a, keyboard-data
1137 var _a/eax: (addr gap-buffer) <- lookup *a-val-addr
1138 var a/ecx: (addr gap-buffer) <- copy _a
1139 var b-val-addr/eax: (addr handle gap-buffer) <- get b, keyboard-data
1140 var b/eax: (addr gap-buffer) <- lookup *b-val-addr
1141 var result/eax: boolean <- gap-buffers-equal? a, b
1142 return result
1143 }
1144
1145 {
1146
1147 var _b-nil?/eax: boolean <- nil? b
1148 var b-nil?/ecx: boolean <- copy _b-nil?
1149 var a-nil?/eax: boolean <- nil? a
1150
1151 {
1152 compare a-nil?, 0/false
1153 break-if-=
1154 compare b-nil?, 0/false
1155 break-if-=
1156 trace-higher trace
1157 trace-text trace, "eval", "=> true (nils)"
1158 return 1/true
1159 }
1160
1161 {
1162 compare a-nil?, 0/false
1163 break-if-=
1164 trace-higher trace
1165 trace-text trace, "eval", "=> false (b != nil)"
1166 return 0/false
1167 }
1168
1169 {
1170 compare b-nil?, 0/false
1171 break-if-=
1172 trace-higher trace
1173 trace-text trace, "eval", "=> false (a != nil)"
1174 return 0/false
1175 }
1176 }
1177
1178 var a-tmp-storage: (handle cell)
1179 var a-tmp-ah/edx: (addr handle cell) <- address a-tmp-storage
1180 var b-tmp-storage: (handle cell)
1181 var b-tmp-ah/ebx: (addr handle cell) <- address b-tmp-storage
1182
1183 car a, a-tmp-ah, trace
1184 car b, b-tmp-ah, trace
1185 {
1186 var _a-tmp/eax: (addr cell) <- lookup *a-tmp-ah
1187 var a-tmp/ecx: (addr cell) <- copy _a-tmp
1188 var b-tmp/eax: (addr cell) <- lookup *b-tmp-ah
1189 var result/eax: boolean <- cell-isomorphic? a-tmp, b-tmp, trace
1190 compare result, 0/false
1191 break-if-!=
1192 trace-higher trace
1193 trace-text trace, "eval", "=> false (car mismatch)"
1194 return 0/false
1195 }
1196
1197 cdr a, a-tmp-ah, trace
1198 cdr b, b-tmp-ah, trace
1199 var _a-tmp/eax: (addr cell) <- lookup *a-tmp-ah
1200 var a-tmp/ecx: (addr cell) <- copy _a-tmp
1201 var b-tmp/eax: (addr cell) <- lookup *b-tmp-ah
1202 var result/eax: boolean <- cell-isomorphic? a-tmp, b-tmp, trace
1203 trace-higher trace
1204 return result
1205 }
1206
1207 fn fn? _x: (addr cell) -> _/eax: boolean {
1208 var x/esi: (addr cell) <- copy _x
1209 var type/eax: (addr int) <- get x, type
1210 compare *type, 2/symbol
1211 {
1212 break-if-=
1213 return 0/false
1214 }
1215 var contents-ah/eax: (addr handle stream byte) <- get x, text-data
1216 var contents/eax: (addr stream byte) <- lookup *contents-ah
1217 var result/eax: boolean <- stream-data-equal? contents, "fn"
1218 return result
1219 }
1220
1221 fn litfn? _x: (addr cell) -> _/eax: boolean {
1222 var x/esi: (addr cell) <- copy _x
1223 var type/eax: (addr int) <- get x, type
1224 compare *type, 2/symbol
1225 {
1226 break-if-=
1227 return 0/false
1228 }
1229 var contents-ah/eax: (addr handle stream byte) <- get x, text-data
1230 var contents/eax: (addr stream byte) <- lookup *contents-ah
1231 var result/eax: boolean <- stream-data-equal? contents, "litfn"
1232 return result
1233 }
1234
1235 fn litmac? _x: (addr cell) -> _/eax: boolean {
1236 var x/esi: (addr cell) <- copy _x
1237 var type/eax: (addr int) <- get x, type
1238 compare *type, 2/symbol
1239 {
1240 break-if-=
1241 return 0/false
1242 }
1243 var contents-ah/eax: (addr handle stream byte) <- get x, text-data
1244 var contents/eax: (addr stream byte) <- lookup *contents-ah
1245 var result/eax: boolean <- stream-data-equal? contents, "litmac"
1246 return result
1247 }
1248
1249 fn test-evaluate-is-well-behaved {
1250 var t-storage: trace
1251 var t/esi: (addr trace) <- address t-storage
1252 initialize-trace t, 0x10, 0/visible
1253
1254 var env-storage: (handle cell)
1255 var env-ah/ecx: (addr handle cell) <- address env-storage
1256 allocate-pair env-ah
1257
1258 var tmp-storage: (handle cell)
1259 var tmp-ah/edx: (addr handle cell) <- address tmp-storage
1260 new-symbol tmp-ah, "a"
1261 evaluate tmp-ah, tmp-ah, *env-ah, 0/no-globals, t, 0/no-screen, 0/no-keyboard, 0/call-number
1262
1263 check-trace-contains t, "error", "unbound symbol: a", "F - test-evaluate-is-well-behaved"
1264 }
1265
1266 fn test-evaluate-number {
1267
1268 var env-storage: (handle cell)
1269 var env-ah/ecx: (addr handle cell) <- address env-storage
1270 allocate-pair env-ah
1271
1272 var tmp-storage: (handle cell)
1273 var tmp-ah/edx: (addr handle cell) <- address tmp-storage
1274 new-integer tmp-ah, 3
1275 evaluate tmp-ah, tmp-ah, *env-ah, 0/no-globals, 0/no-trace, 0/no-screen, 0/no-keyboard, 0/call-number
1276
1277 var result/eax: (addr cell) <- lookup *tmp-ah
1278 var result-type/edx: (addr int) <- get result, type
1279 check-ints-equal *result-type, 1/number, "F - test-evaluate-number/0"
1280 var result-value-addr/eax: (addr float) <- get result, number-data
1281 var result-value/eax: int <- convert *result-value-addr
1282 check-ints-equal result-value, 3, "F - test-evaluate-number/1"
1283 }
1284
1285 fn test-evaluate-symbol {
1286
1287 var val-storage: (handle cell)
1288 var val-ah/ecx: (addr handle cell) <- address val-storage
1289 new-integer val-ah, 3
1290 var key-storage: (handle cell)
1291 var key-ah/edx: (addr handle cell) <- address key-storage
1292 new-symbol key-ah, "a"
1293 var env-storage: (handle cell)
1294 var env-ah/ebx: (addr handle cell) <- address env-storage
1295 new-pair env-ah, *key-ah, *val-ah
1296
1297 var nil-storage: (handle cell)
1298 var nil-ah/ecx: (addr handle cell) <- address nil-storage
1299 allocate-pair nil-ah
1300 new-pair env-ah, *env-ah, *nil-ah
1301
1302 var tmp-storage: (handle cell)
1303 var tmp-ah/edx: (addr handle cell) <- address tmp-storage
1304 new-symbol tmp-ah, "a"
1305 evaluate tmp-ah, tmp-ah, *env-ah, 0/no-globals, 0/no-trace, 0/no-screen, 0/no-keyboard, 0/call-number
1306 var result/eax: (addr cell) <- lookup *tmp-ah
1307 var result-type/edx: (addr int) <- get result, type
1308 check-ints-equal *result-type, 1/number, "F - test-evaluate-symbol/0"
1309 var result-value-addr/eax: (addr float) <- get result, number-data
1310 var result-value/eax: int <- convert *result-value-addr
1311 check-ints-equal result-value, 3, "F - test-evaluate-symbol/1"
1312 }
1313
1314 fn test-evaluate-quote {
1315
1316 var nil-storage: (handle cell)
1317 var nil-ah/ecx: (addr handle cell) <- address nil-storage
1318 allocate-pair nil-ah
1319
1320 var tmp-storage: (handle cell)
1321 var tmp-ah/edx: (addr handle cell) <- address tmp-storage
1322 new-symbol tmp-ah, "'"
1323 var tmp2-storage: (handle cell)
1324 var tmp2-ah/ebx: (addr handle cell) <- address tmp2-storage
1325 new-symbol tmp2-ah, "a"
1326 new-pair tmp-ah, *tmp-ah, *tmp2-ah
1327 evaluate tmp-ah, tmp-ah, *nil-ah, 0/no-globals, 0/no-trace, 0/no-screen, 0/no-keyboard, 0/call-number
1328 var result/eax: (addr cell) <- lookup *tmp-ah
1329 var result-type/edx: (addr int) <- get result, type
1330 check-ints-equal *result-type, 2/symbol, "F - test-evaluate-quote/0"
1331 var sym?/eax: boolean <- symbol-equal? result, "a"
1332 check sym?, "F - test-evaluate-quote/1"
1333 }
1334
1335 fn test-evaluate-primitive-function {
1336 var globals-storage: global-table
1337 var globals/edi: (addr global-table) <- address globals-storage
1338 initialize-globals globals
1339 var nil-storage: (handle cell)
1340 var nil-ah/ecx: (addr handle cell) <- address nil-storage
1341 allocate-pair nil-ah
1342 var add-storage: (handle cell)
1343 var add-ah/ebx: (addr handle cell) <- address add-storage
1344 new-symbol add-ah, "+"
1345
1346 var tmp-storage: (handle cell)
1347 var tmp-ah/esi: (addr handle cell) <- address tmp-storage
1348 evaluate add-ah, tmp-ah, *nil-ah, globals, 0/no-trace, 0/no-screen, 0/no-keyboard, 0/call-number
1349
1350 var result/eax: (addr cell) <- lookup *tmp-ah
1351 var result-type/edx: (addr int) <- get result, type
1352 check-ints-equal *result-type, 4/primitive-function, "F - test-evaluate-primitive-function/0"
1353 var result-value/eax: (addr int) <- get result, index-data
1354 check-ints-equal *result-value, 1/add, "F - test-evaluate-primitive-function/1"
1355 }
1356
1357 fn test-evaluate-primitive-function-call {
1358 var t-storage: trace
1359 var t/edi: (addr trace) <- address t-storage
1360 initialize-trace t, 0x100, 0/visible
1361
1362 var nil-storage: (handle cell)
1363 var nil-ah/ecx: (addr handle cell) <- address nil-storage
1364 allocate-pair nil-ah
1365 var one-storage: (handle cell)
1366 var one-ah/edx: (addr handle cell) <- address one-storage
1367 new-integer one-ah, 1
1368 var add-storage: (handle cell)
1369 var add-ah/ebx: (addr handle cell) <- address add-storage
1370 new-symbol add-ah, "+"
1371
1372 var tmp-storage: (handle cell)
1373 var tmp-ah/esi: (addr handle cell) <- address tmp-storage
1374 new-pair tmp-ah, *one-ah, *nil-ah
1375 new-pair tmp-ah, *one-ah, *tmp-ah
1376 new-pair tmp-ah, *add-ah, *tmp-ah
1377
1378
1379 var globals-storage: global-table
1380 var globals/edx: (addr global-table) <- address globals-storage
1381 initialize-globals globals
1382
1383 evaluate tmp-ah, tmp-ah, *nil-ah, globals, t, 0/no-screen, 0/no-keyboard, 0/call-number
1384
1385
1386 var result/eax: (addr cell) <- lookup *tmp-ah
1387 var result-type/edx: (addr int) <- get result, type
1388 check-ints-equal *result-type, 1/number, "F - test-evaluate-primitive-function-call/0"
1389 var result-value-addr/eax: (addr float) <- get result, number-data
1390 var result-value/eax: int <- convert *result-value-addr
1391 check-ints-equal result-value, 2, "F - test-evaluate-primitive-function-call/1"
1392 }
1393
1394 fn test-evaluate-backquote {
1395
1396 var nil-storage: (handle cell)
1397 var nil-ah/ecx: (addr handle cell) <- address nil-storage
1398 allocate-pair nil-ah
1399
1400 var tmp-storage: (handle cell)
1401 var tmp-ah/edx: (addr handle cell) <- address tmp-storage
1402 new-symbol tmp-ah, "`"
1403 var tmp2-storage: (handle cell)
1404 var tmp2-ah/ebx: (addr handle cell) <- address tmp2-storage
1405 new-symbol tmp2-ah, "a"
1406 new-pair tmp-ah, *tmp-ah, *tmp2-ah
1407 clear-object tmp2-ah
1408 evaluate tmp-ah, tmp2-ah, *nil-ah, 0/no-globals, 0/no-trace, 0/no-screen, 0/no-keyboard, 0/call-number
1409 var result/eax: (addr cell) <- lookup *tmp2-ah
1410 var result-type/edx: (addr int) <- get result, type
1411 check-ints-equal *result-type, 2/symbol, "F - test-evaluate-backquote/0"
1412 var sym?/eax: boolean <- symbol-equal? result, "a"
1413 check sym?, "F - test-evaluate-backquote/1"
1414 }
1415
1416 fn evaluate-backquote _in-ah: (addr handle cell), _out-ah: (addr handle cell), env-h: (handle cell), globals: (addr global-table), trace: (addr trace), screen-cell: (addr handle cell), keyboard-cell: (addr handle cell), call-number: int {
1417
1418
1419 check-stack
1420 {
1421 var screen-cell/eax: (addr handle cell) <- copy screen-cell
1422 compare screen-cell, 0
1423 break-if-=
1424 var screen-cell-addr/eax: (addr cell) <- lookup *screen-cell
1425 compare screen-cell-addr, 0
1426 break-if-=
1427
1428 show-stack-state
1429 }
1430
1431 {
1432 compare trace, 0
1433 break-if-=
1434 var error?/eax: boolean <- has-errors? trace
1435 compare error?, 0/false
1436 break-if-=
1437 return
1438 }
1439 var in-ah/esi: (addr handle cell) <- copy _in-ah
1440 var in/eax: (addr cell) <- lookup *in-ah
1441 {
1442 var nil?/eax: boolean <- nil? in
1443 compare nil?, 0/false
1444 break-if-=
1445
1446 trace-text trace, "eval", "backquote nil"
1447 copy-object _in-ah, _out-ah
1448 trace-higher trace
1449 return
1450 }
1451 var in-type/ecx: (addr int) <- get in, type
1452 compare *in-type, 0/pair
1453 {
1454 break-if-=
1455
1456
1457 trace-text trace, "eval", "backquote atom"
1458 copy-object _in-ah, _out-ah
1459 trace-higher trace
1460 return
1461 }
1462
1463 debug-print "()", 4/fg, 0/bg
1464 var in-ah/esi: (addr handle cell) <- copy _in-ah
1465 var _in/eax: (addr cell) <- lookup *in-ah
1466 var in/ebx: (addr cell) <- copy _in
1467 var in-left-ah/ecx: (addr handle cell) <- get in, left
1468 debug-print "10", 4/fg, 0/bg
1469
1470 $macroexpand-iter:unquote: {
1471 var in-left/eax: (addr cell) <- lookup *in-left-ah
1472 var unquote?/eax: boolean <- symbol-equal? in-left, ","
1473 compare unquote?, 0/false
1474 break-if-=
1475 trace-text trace, "eval", "unquote"
1476 var rest-ah/eax: (addr handle cell) <- get in, right
1477 increment call-number
1478 debug-print ",", 3/fg, 0/bg
1479 evaluate rest-ah, _out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
1480 debug-print ",)", 3/fg, 0/bg
1481 return
1482 }
1483
1484 debug-print "11", 4/fg, 0/bg
1485 var out-ah/edi: (addr handle cell) <- copy _out-ah
1486 $macroexpand-iter:unquote-splice: {
1487
1488 var in-left/eax: (addr cell) <- lookup *in-left-ah
1489 {
1490 debug-print "12", 4/fg, 0/bg
1491 {
1492 var in-left-is-nil?/eax: boolean <- nil? in-left
1493 compare in-left-is-nil?, 0/false
1494 }
1495 break-if-!= $macroexpand-iter:unquote-splice
1496 var in-left-type/ecx: (addr int) <- get in-left, type
1497 debug-print "13", 4/fg, 0/bg
1498 compare *in-left-type, 0/pair
1499 break-if-!= $macroexpand-iter:unquote-splice
1500 var in-left-left-ah/eax: (addr handle cell) <- get in-left, left
1501 debug-print "14", 4/fg, 0/bg
1502 var in-left-left/eax: (addr cell) <- lookup *in-left-left-ah
1503 debug-print "15", 4/fg, 0/bg
1504 var in-left-left-type/ecx: (addr int) <- get in-left-left, type
1505 var left-is-unquote-splice?/eax: boolean <- symbol-equal? in-left-left, ",@"
1506 debug-print "16", 4/fg, 0/bg
1507 compare left-is-unquote-splice?, 0/false
1508 }
1509 break-if-=
1510 debug-print "17", 4/fg, 0/bg
1511 trace-text trace, "eval", "unquote-splice"
1512 var in-unquote-payload-ah/eax: (addr handle cell) <- get in-left, right
1513 increment call-number
1514 evaluate in-unquote-payload-ah, out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
1515
1516 {
1517 var out/eax: (addr cell) <- lookup *out-ah
1518 {
1519 var done?/eax: boolean <- nil? out
1520 compare done?, 0/false
1521 }
1522 break-if-!=
1523 out-ah <- get out, right
1524 loop
1525 }
1526
1527 var in-right-ah/ecx: (addr handle cell) <- get in, right
1528 evaluate-backquote in-right-ah, out-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
1529 return
1530 }
1531 debug-print "19", 4/fg, 0/bg
1532
1533 trace-text trace, "eval", "backquote: copy"
1534 var out-ah/edi: (addr handle cell) <- copy _out-ah
1535 allocate-pair out-ah
1536 debug-print "20", 7/fg, 0/bg
1537
1538 var out/eax: (addr cell) <- lookup *out-ah
1539 var out-left-ah/edx: (addr handle cell) <- get out, left
1540 debug-print "`(l", 3/fg, 0/bg
1541 evaluate-backquote in-left-ah, out-left-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
1542 debug-print "`r)", 3/fg, 0/bg
1543 var in-right-ah/ecx: (addr handle cell) <- get in, right
1544 var out-right-ah/edx: (addr handle cell) <- get out, right
1545 debug-print "`r(", 3/fg, 0/bg
1546 evaluate-backquote in-right-ah, out-right-ah, env-h, globals, trace, screen-cell, keyboard-cell, call-number
1547 debug-print "`r)", 3/fg, 0/bg
1548 }
1549
1550 fn test-evaluate-backquote-list {
1551 var nil-storage: (handle cell)
1552 var nil-ah/ecx: (addr handle cell) <- address nil-storage
1553 allocate-pair nil-ah
1554 var backquote-storage: (handle cell)
1555 var backquote-ah/edx: (addr handle cell) <- address backquote-storage
1556 new-symbol backquote-ah, "`"
1557
1558 var a-storage: (handle cell)
1559 var a-ah/ebx: (addr handle cell) <- address a-storage
1560 new-symbol a-ah, "a"
1561 var b-storage: (handle cell)
1562 var b-ah/esi: (addr handle cell) <- address b-storage
1563 new-symbol b-ah, "b"
1564 var tmp-storage: (handle cell)
1565 var tmp-ah/eax: (addr handle cell) <- address tmp-storage
1566 new-pair tmp-ah, *b-ah, *nil-ah
1567 new-pair tmp-ah, *a-ah, *tmp-ah
1568 new-pair tmp-ah, *backquote-ah, *tmp-ah
1569
1570 evaluate tmp-ah, tmp-ah, *nil-ah, 0/no-globals, 0/no-trace, 0/no-screen, 0/no-keyboard, 0/call-number
1571
1572 var result/eax: (addr cell) <- lookup *tmp-ah
1573 {
1574 var result-type/eax: (addr int) <- get result, type
1575 check-ints-equal *result-type, 0/pair, "F - test-evaluate-backquote-list/0"
1576 }
1577 {
1578 var a1-ah/eax: (addr handle cell) <- get result, left
1579 var a1/eax: (addr cell) <- lookup *a1-ah
1580 var check1/eax: boolean <- symbol-equal? a1, "a"
1581 check check1, "F - test-evaluate-backquote-list/1"
1582 }
1583 var rest-ah/eax: (addr handle cell) <- get result, right
1584 var rest/eax: (addr cell) <- lookup *rest-ah
1585 {
1586 var a2-ah/eax: (addr handle cell) <- get rest, left
1587 var a2/eax: (addr cell) <- lookup *a2-ah
1588 var check2/eax: boolean <- symbol-equal? a2, "b"
1589 check check2, "F - test-evaluate-backquote-list/2"
1590 }
1591 var rest-ah/eax: (addr handle cell) <- get rest, right
1592 var rest/eax: (addr cell) <- lookup *rest-ah
1593 var check3/eax: boolean <- nil? rest
1594 check check3, "F - test-evaluate-backquote-list/3"
1595 }
1596
1597 fn test-evaluate-backquote-list-with-unquote {
1598 var nil-h: (handle cell)
1599 var nil-ah/eax: (addr handle cell) <- address nil-h
1600 allocate-pair nil-ah
1601 var backquote-h: (handle cell)
1602 var backquote-ah/eax: (addr handle cell) <- address backquote-h
1603 new-symbol backquote-ah, "`"
1604 var unquote-h: (handle cell)
1605 var unquote-ah/eax: (addr handle cell) <- address unquote-h
1606 new-symbol unquote-ah, ","
1607 var a-h: (handle cell)
1608 var a-ah/eax: (addr handle cell) <- address a-h
1609 new-symbol a-ah, "a"
1610 var b-h: (handle cell)
1611 var b-ah/eax: (addr handle cell) <- address b-h
1612 new-symbol b-ah, "b"
1613
1614 var val-h: (handle cell)
1615 var val-ah/eax: (addr handle cell) <- address val-h
1616 new-integer val-ah, 3
1617 var env-h: (handle cell)
1618 var env-ah/eax: (addr handle cell) <- address env-h
1619 new-pair env-ah, b-h, val-h
1620 new-pair env-ah, env-h, nil-h
1621
1622 var tmp-h: (handle cell)
1623 var tmp-ah/eax: (addr handle cell) <- address tmp-h
1624
1625 new-pair tmp-ah, unquote-h, b-h
1626
1627 new-pair tmp-ah, tmp-h, nil-h
1628
1629 new-pair tmp-ah, a-h, tmp-h
1630
1631 new-pair tmp-ah, backquote-h, tmp-h
1632
1633 evaluate tmp-ah, tmp-ah, env-h, 0/no-globals, 0/no-trace, 0/no-screen, 0/no-keyboard, 0/call-number
1634
1635 var result/eax: (addr cell) <- lookup *tmp-ah
1636 {
1637 var result-type/eax: (addr int) <- get result, type
1638 check-ints-equal *result-type, 0/pair, "F - test-evaluate-backquote-list-with-unquote/0"
1639 }
1640 {
1641 var a1-ah/eax: (addr handle cell) <- get result, left
1642 var a1/eax: (addr cell) <- lookup *a1-ah
1643 var check1/eax: boolean <- symbol-equal? a1, "a"
1644 check check1, "F - test-evaluate-backquote-list-with-unquote/1"
1645 }
1646 var rest-ah/eax: (addr handle cell) <- get result, right
1647 var rest/eax: (addr cell) <- lookup *rest-ah
1648 {
1649 var a2-ah/eax: (addr handle cell) <- get rest, left
1650 var a2/eax: (addr cell) <- lookup *a2-ah
1651 var a2-value-addr/eax: (addr float) <- get a2, number-data
1652 var a2-value/eax: int <- convert *a2-value-addr
1653 check-ints-equal a2-value, 3, "F - test-evaluate-backquote-list-with-unquote/2"
1654 }
1655 var rest-ah/eax: (addr handle cell) <- get rest, right
1656 var rest/eax: (addr cell) <- lookup *rest-ah
1657 var check3/eax: boolean <- nil? rest
1658 check check3, "F - test-evaluate-backquote-list-with-unquote/3"
1659 }
1660
1661 fn test-evaluate-backquote-list-with-unquote-splice {
1662 var nil-h: (handle cell)
1663 var nil-ah/eax: (addr handle cell) <- address nil-h
1664 allocate-pair nil-ah
1665 var backquote-h: (handle cell)
1666 var backquote-ah/eax: (addr handle cell) <- address backquote-h
1667 new-symbol backquote-ah, "`"
1668 var unquote-splice-h: (handle cell)
1669 var unquote-splice-ah/eax: (addr handle cell) <- address unquote-splice-h
1670 new-symbol unquote-splice-ah, ",@"
1671 var a-h: (handle cell)
1672 var a-ah/eax: (addr handle cell) <- address a-h
1673 new-symbol a-ah, "a"
1674 var b-h: (handle cell)
1675 var b-ah/eax: (addr handle cell) <- address b-h
1676 new-symbol b-ah, "b"
1677
1678 var val-h: (handle cell)
1679 var val-ah/eax: (addr handle cell) <- address val-h
1680 new-integer val-ah, 3
1681 new-pair val-ah, val-h, nil-h
1682 new-pair val-ah, a-h, val-h
1683 var env-h: (handle cell)
1684 var env-ah/eax: (addr handle cell) <- address env-h
1685 new-pair env-ah, b-h, val-h
1686 new-pair env-ah, env-h, nil-h
1687
1688 var tmp-h: (handle cell)
1689 var tmp-ah/eax: (addr handle cell) <- address tmp-h
1690
1691 new-pair tmp-ah, b-h, nil-h
1692
1693 var tmp2-h: (handle cell)
1694 var tmp2-ah/ecx: (addr handle cell) <- address tmp2-h
1695 new-pair tmp2-ah, unquote-splice-h, b-h
1696
1697 new-pair tmp-ah, tmp2-h, tmp-h
1698
1699 new-pair tmp-ah, a-h, tmp-h
1700
1701 new-pair tmp-ah, backquote-h, tmp-h
1702
1703
1704 evaluate tmp-ah, tmp-ah, env-h, 0/no-globals, 0/no-trace, 0/no-screen, 0/no-keyboard, 0/call-number
1705
1706
1707 var result/eax: (addr cell) <- lookup *tmp-ah
1708 {
1709 var result-type/eax: (addr int) <- get result, type
1710 check-ints-equal *result-type, 0/pair, "F - test-evaluate-backquote-list-with-unquote-splice/0"
1711 }
1712 {
1713 var a1-ah/eax: (addr handle cell) <- get result, left
1714 var a1/eax: (addr cell) <- lookup *a1-ah
1715 var check1/eax: boolean <- symbol-equal? a1, "a"
1716 check check1, "F - test-evaluate-backquote-list-with-unquote-splice/1"
1717 }
1718 var rest-ah/eax: (addr handle cell) <- get result, right
1719 var rest/eax: (addr cell) <- lookup *rest-ah
1720 {
1721 var a2-ah/eax: (addr handle cell) <- get rest, left
1722 var a2/eax: (addr cell) <- lookup *a2-ah
1723 var check2/eax: boolean <- symbol-equal? a2, "a"
1724 check check2, "F - test-evaluate-backquote-list-with-unquote-splice/2"
1725 }
1726 var rest-ah/eax: (addr handle cell) <- get rest, right
1727 var rest/eax: (addr cell) <- lookup *rest-ah
1728 {
1729 var a3-ah/eax: (addr handle cell) <- get rest, left
1730 var a3/eax: (addr cell) <- lookup *a3-ah
1731 var a3-value-addr/eax: (addr float) <- get a3, number-data
1732 var a3-value/eax: int <- convert *a3-value-addr
1733 check-ints-equal a3-value, 3, "F - test-evaluate-backquote-list-with-unquote-splice/3"
1734 }
1735 var rest-ah/eax: (addr handle cell) <- get rest, right
1736 var rest/eax: (addr cell) <- lookup *rest-ah
1737 {
1738 var a4-ah/eax: (addr handle cell) <- get rest, left
1739 var a4/eax: (addr cell) <- lookup *a4-ah
1740 var check4/eax: boolean <- symbol-equal? a4, "b"
1741 check check4, "F - test-evaluate-backquote-list-with-unquote-splice/4"
1742 }
1743 var rest-ah/eax: (addr handle cell) <- get rest, right
1744 var rest/eax: (addr cell) <- lookup *rest-ah
1745 var check5/eax: boolean <- nil? rest
1746 check check5, "F - test-evaluate-backquote-list-with-unquote-splice/5"
1747 }