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