https://github.com/akkartik/mu/blob/main/shell/primitives.mu
1
2
3
4 fn initialize-primitives _self: (addr global-table) {
5 var self/esi: (addr global-table) <- copy _self
6
7 append-primitive self, "+"
8 append-primitive self, "-"
9 append-primitive self, "*"
10 append-primitive self, "/"
11 append-primitive self, "%"
12 append-primitive self, "sqrt"
13 append-primitive self, "abs"
14 append-primitive self, "sgn"
15 append-primitive self, "<"
16 append-primitive self, ">"
17 append-primitive self, "<="
18 append-primitive self, ">="
19
20 append-primitive self, "apply"
21 append-primitive self, "="
22 append-primitive self, "no"
23 append-primitive self, "not"
24 append-primitive self, "dbg"
25
26 append-primitive self, "car"
27 append-primitive self, "cdr"
28 append-primitive self, "cons"
29 append-primitive self, "cons?"
30
31 append-primitive self, "print"
32 append-primitive self, "clear"
33 append-primitive self, "lines"
34 append-primitive self, "columns"
35 append-primitive self, "up"
36 append-primitive self, "down"
37 append-primitive self, "left"
38 append-primitive self, "right"
39 append-primitive self, "cr"
40 append-primitive self, "pixel"
41 append-primitive self, "line"
42 append-primitive self, "hline"
43 append-primitive self, "vline"
44 append-primitive self, "circle"
45 append-primitive self, "bezier"
46 append-primitive self, "width"
47 append-primitive self, "height"
48 append-primitive self, "new_screen"
49 append-primitive self, "blit"
50
51 append-primitive self, "key"
52
53 append-primitive self, "stream"
54 append-primitive self, "write"
55 append-primitive self, "read"
56 append-primitive self, "rewind"
57
58 append-primitive self, "abort"
59
60 }
61
62
63
64 fn render-primitives screen: (addr screen), xmin: int, xmax: int, ymax: int {
65 var y/ecx: int <- copy ymax
66 y <- subtract 0x11/primitives-border
67 clear-rect screen, xmin, y, xmax, ymax, 0xdc/bg=green-bg
68 y <- increment
69 var right-min/edx: int <- copy xmax
70 right-min <- subtract 0x1e/primitives-divider
71 set-cursor-position screen, right-min, y
72 draw-text-wrapping-right-then-down-from-cursor screen, "primitives", right-min, y, xmax, ymax, 7/fg=grey, 0xdc/bg=green-bg
73 y <- increment
74 set-cursor-position screen, right-min, y
75 draw-text-wrapping-right-then-down-from-cursor screen, "fn apply set if while", right-min, y, xmax, ymax, 0x2a/fg=orange, 0xdc/bg=green-bg
76 y <- increment
77 set-cursor-position screen, right-min, y
78 draw-text-wrapping-right-then-down-from-cursor screen, "booleans", right-min, y, xmax, ymax, 7/fg=grey, 0xdc/bg=green-bg
79 y <- increment
80 set-cursor-position screen, right-min, y
81 draw-text-wrapping-right-then-down-from-cursor screen, "= and or not", right-min, y, xmax, ymax, 0x2a/fg=orange, 0xdc/bg=green-bg
82 y <- increment
83 set-cursor-position screen, right-min, y
84 draw-text-wrapping-right-then-down-from-cursor screen, "lists", right-min, y, xmax, ymax, 7/fg=grey, 0xdc/bg=green-bg
85 y <- increment
86 set-cursor-position screen, right-min, y
87 draw-text-wrapping-right-then-down-from-cursor screen, "cons car cdr no cons?", right-min, y, xmax, ymax, 0x2a/fg=orange, 0xdc/bg=green-bg
88 y <- increment
89 set-cursor-position screen, right-min, y
90 draw-text-wrapping-right-then-down-from-cursor screen, "numbers", right-min, y, xmax, ymax, 7/fg=grey, 0xdc/bg=green-bg
91 y <- increment
92 set-cursor-position screen, right-min, y
93 draw-text-wrapping-right-then-down-from-cursor screen, "+ - * / %", right-min, y, xmax, ymax, 0x2a/fg=orange, 0xdc/bg=green-bg
94 y <- increment
95 set-cursor-position screen, right-min, y
96 draw-text-wrapping-right-then-down-from-cursor screen, "< > <= >=", right-min, y, xmax, ymax, 0x2a/fg=orange, 0xdc/bg=green-bg
97 y <- increment
98 set-cursor-position screen, right-min, y
99 draw-text-wrapping-right-then-down-from-cursor screen, "sqrt abs sgn", right-min, y, xmax, ymax, 0x2a/fg=orange, 0xdc/bg=green-bg
100
101
102
103
104
105
106
107 y <- copy ymax
108 y <- subtract 0x10/primitives-border
109 var left-max/edx: int <- copy xmax
110 left-max <- subtract 0x20/primitives-divider
111 var tmpx/eax: int <- copy xmin
112 tmpx <- draw-text-rightward screen, "cursor graphics", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
113 y <- increment
114 var tmpx/eax: int <- copy xmin
115 tmpx <- draw-text-rightward screen, " print", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
116 tmpx <- draw-text-rightward screen, ": screen a -> a", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
117 y <- increment
118 var tmpx/eax: int <- copy xmin
119 tmpx <- draw-text-rightward screen, " lines columns", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
120 tmpx <- draw-text-rightward screen, ": screen -> number", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
121 y <- increment
122 var tmpx/eax: int <- copy xmin
123 tmpx <- draw-text-rightward screen, " up down left right", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
124 tmpx <- draw-text-rightward screen, ": screen", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
125 y <- increment
126 var tmpx/eax: int <- copy xmin
127 tmpx <- draw-text-rightward screen, " cr", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
128 tmpx <- draw-text-rightward screen, ": screen ", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
129 tmpx <- draw-text-rightward screen, "# move cursor down and to left margin", tmpx, left-max, y, 0x38/fg=trace, 0xdc/bg=green-bg
130 y <- increment
131 var tmpx/eax: int <- copy xmin
132 tmpx <- draw-text-rightward screen, "pixel graphics", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
133 y <- increment
134 var tmpx/eax: int <- copy xmin
135 tmpx <- draw-text-rightward screen, " circle bezier line hline vline pixel", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
136 y <- increment
137 var tmpx/eax: int <- copy xmin
138 tmpx <- draw-text-rightward screen, " width height", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
139 tmpx <- draw-text-rightward screen, ": screen -> number", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
140 y <- increment
141 var tmpx/eax: int <- copy xmin
142 tmpx <- draw-text-rightward screen, " new_screen", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
143 tmpx <- draw-text-rightward screen, ": number number -> screen ", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
144 y <- increment
145 var tmpx/eax: int <- copy xmin
146 tmpx <- draw-text-rightward screen, " clear blit", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
147 tmpx <- draw-text-rightward screen, ": screen", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
148 y <- increment
149 var tmpx/eax: int <- copy xmin
150 tmpx <- draw-text-rightward screen, " key", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
151 tmpx <- draw-text-rightward screen, ": keyboard -> grapheme?", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
152 y <- increment
153 var tmpx/eax: int <- copy xmin
154 tmpx <- draw-text-rightward screen, "streams", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
155 y <- increment
156 var tmpx/eax: int <- copy xmin
157 tmpx <- draw-text-rightward screen, " stream", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
158 tmpx <- draw-text-rightward screen, ": -> stream ", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
159 y <- increment
160 var tmpx/eax: int <- copy xmin
161 tmpx <- draw-text-rightward screen, " write", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
162 tmpx <- draw-text-rightward screen, ": stream grapheme -> stream", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
163 y <- increment
164 var tmpx/eax: int <- copy xmin
165 tmpx <- draw-text-rightward screen, " rewind clear", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
166 tmpx <- draw-text-rightward screen, ": stream", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
167 y <- increment
168 var tmpx/eax: int <- copy xmin
169 tmpx <- draw-text-rightward screen, " read", tmpx, left-max, y, 0x2a/fg=orange, 0xdc/bg=green-bg
170 tmpx <- draw-text-rightward screen, ": stream -> grapheme", tmpx, left-max, y, 7/fg=grey, 0xdc/bg=green-bg
171 }
172
173 fn primitive-global? _x: (addr global) -> _/eax: boolean {
174 var x/eax: (addr global) <- copy _x
175 var value-ah/eax: (addr handle cell) <- get x, value
176 var value/eax: (addr cell) <- lookup *value-ah
177 compare value, 0/null
178 {
179 break-if-!=
180 return 0/false
181 }
182 {
183 var value-type/eax: (addr int) <- get value, type
184 compare *value-type, 4/primitive
185 break-if-=
186 return 0/false
187 }
188 return 1/true
189 }
190
191 fn append-primitive _self: (addr global-table), name: (addr array byte) {
192 var self/esi: (addr global-table) <- copy _self
193 compare self, 0
194 {
195 break-if-!=
196 abort "append primitive"
197 return
198 }
199 var final-index-addr/ecx: (addr int) <- get self, final-index
200 increment *final-index-addr
201 var curr-index/ecx: int <- copy *final-index-addr
202 var data-ah/eax: (addr handle array global) <- get self, data
203 var data/eax: (addr array global) <- lookup *data-ah
204 var curr-offset/esi: (offset global) <- compute-offset data, curr-index
205 var curr/esi: (addr global) <- index data, curr-offset
206 var curr-name-ah/eax: (addr handle array byte) <- get curr, name
207 copy-array-object name, curr-name-ah
208 var curr-value-ah/eax: (addr handle cell) <- get curr, value
209 new-primitive-function curr-value-ah, curr-index
210 }
211
212
213 fn apply-primitive _f: (addr cell), args-ah: (addr handle cell), out: (addr handle cell), _globals: (addr global-table), trace: (addr trace) {
214 var f/esi: (addr cell) <- copy _f
215 var f-index-a/ecx: (addr int) <- get f, index-data
216 var f-index/ecx: int <- copy *f-index-a
217 var globals/eax: (addr global-table) <- copy _globals
218 compare globals, 0
219 {
220 break-if-!=
221 abort "apply primitive"
222 return
223 }
224 var global-data-ah/eax: (addr handle array global) <- get globals, data
225 var global-data/eax: (addr array global) <- lookup *global-data-ah
226 var f-offset/ecx: (offset global) <- compute-offset global-data, f-index
227 var f-value/ecx: (addr global) <- index global-data, f-offset
228 var f-name-ah/ecx: (addr handle array byte) <- get f-value, name
229 var f-name/eax: (addr array byte) <- lookup *f-name-ah
230 {
231 var add?/eax: boolean <- string-equal? f-name, "+"
232 compare add?, 0/false
233 break-if-=
234 apply-add args-ah, out, trace
235 return
236 }
237 {
238 var subtract?/eax: boolean <- string-equal? f-name, "-"
239 compare subtract?, 0/false
240 break-if-=
241 apply-subtract args-ah, out, trace
242 return
243 }
244 {
245 var multiply?/eax: boolean <- string-equal? f-name, "*"
246 compare multiply?, 0/false
247 break-if-=
248 apply-multiply args-ah, out, trace
249 return
250 }
251 {
252 var divide?/eax: boolean <- string-equal? f-name, "/"
253 compare divide?, 0/false
254 break-if-=
255 apply-divide args-ah, out, trace
256 return
257 }
258
259
260
261
262
263
264 {
265 var remainder?/eax: boolean <- string-equal? f-name, "%"
266 compare remainder?, 0/false
267 break-if-=
268 apply-remainder args-ah, out, trace
269 return
270 }
271 {
272 var square-root?/eax: boolean <- string-equal? f-name, "sqrt"
273 compare square-root?, 0/false
274 break-if-=
275 apply-square-root args-ah, out, trace
276 return
277 }
278 {
279 var abs?/eax: boolean <- string-equal? f-name, "abs"
280 compare abs?, 0/false
281 break-if-=
282 apply-abs args-ah, out, trace
283 return
284 }
285 {
286 var sgn?/eax: boolean <- string-equal? f-name, "sgn"
287 compare sgn?, 0/false
288 break-if-=
289 apply-sgn args-ah, out, trace
290 return
291 }
292 {
293 var car?/eax: boolean <- string-equal? f-name, "car"
294 compare car?, 0/false
295 break-if-=
296 apply-car args-ah, out, trace
297 return
298 }
299 {
300 var cdr?/eax: boolean <- string-equal? f-name, "cdr"
301 compare cdr?, 0/false
302 break-if-=
303 apply-cdr args-ah, out, trace
304 return
305 }
306 {
307 var cons?/eax: boolean <- string-equal? f-name, "cons"
308 compare cons?, 0/false
309 break-if-=
310 apply-cons args-ah, out, trace
311 return
312 }
313 {
314 var cons-check?/eax: boolean <- string-equal? f-name, "cons?"
315 compare cons-check?, 0/false
316 break-if-=
317 apply-cons-check args-ah, out, trace
318 return
319 }
320 {
321 var cell-isomorphic?/eax: boolean <- string-equal? f-name, "="
322 compare cell-isomorphic?, 0/false
323 break-if-=
324 apply-cell-isomorphic args-ah, out, trace
325 return
326 }
327 {
328 var not?/eax: boolean <- string-equal? f-name, "no"
329 compare not?, 0/false
330 break-if-=
331 apply-not args-ah, out, trace
332 return
333 }
334 {
335 var not?/eax: boolean <- string-equal? f-name, "not"
336 compare not?, 0/false
337 break-if-=
338 apply-not args-ah, out, trace
339 return
340 }
341 {
342 var debug?/eax: boolean <- string-equal? f-name, "dbg"
343 compare debug?, 0/false
344 break-if-=
345 apply-debug args-ah, out, trace
346 return
347 }
348 {
349 var lesser?/eax: boolean <- string-equal? f-name, "<"
350 compare lesser?, 0/false
351 break-if-=
352 apply-< args-ah, out, trace
353 return
354 }
355 {
356 var greater?/eax: boolean <- string-equal? f-name, ">"
357 compare greater?, 0/false
358 break-if-=
359 apply-> args-ah, out, trace
360 return
361 }
362 {
363 var lesser-or-equal?/eax: boolean <- string-equal? f-name, "<="
364 compare lesser-or-equal?, 0/false
365 break-if-=
366 apply-<= args-ah, out, trace
367 return
368 }
369 {
370 var greater-or-equal?/eax: boolean <- string-equal? f-name, ">="
371 compare greater-or-equal?, 0/false
372 break-if-=
373 apply->= args-ah, out, trace
374 return
375 }
376 {
377 var print?/eax: boolean <- string-equal? f-name, "print"
378 compare print?, 0/false
379 break-if-=
380 apply-print args-ah, out, trace
381 return
382 }
383 {
384 var clear?/eax: boolean <- string-equal? f-name, "clear"
385 compare clear?, 0/false
386 break-if-=
387 apply-clear args-ah, out, trace
388 return
389 }
390 {
391 var lines?/eax: boolean <- string-equal? f-name, "lines"
392 compare lines?, 0/false
393 break-if-=
394 apply-lines args-ah, out, trace
395 return
396 }
397 {
398 var columns?/eax: boolean <- string-equal? f-name, "columns"
399 compare columns?, 0/false
400 break-if-=
401 apply-columns args-ah, out, trace
402 return
403 }
404 {
405 var up?/eax: boolean <- string-equal? f-name, "up"
406 compare up?, 0/false
407 break-if-=
408 apply-up args-ah, out, trace
409 return
410 }
411 {
412 var down?/eax: boolean <- string-equal? f-name, "down"
413 compare down?, 0/false
414 break-if-=
415 apply-down args-ah, out, trace
416 return
417 }
418 {
419 var left?/eax: boolean <- string-equal? f-name, "left"
420 compare left?, 0/false
421 break-if-=
422 apply-left args-ah, out, trace
423 return
424 }
425 {
426 var right?/eax: boolean <- string-equal? f-name, "right"
427 compare right?, 0/false
428 break-if-=
429 apply-right args-ah, out, trace
430 return
431 }
432 {
433 var cr?/eax: boolean <- string-equal? f-name, "cr"
434 compare cr?, 0/false
435 break-if-=
436 apply-cr args-ah, out, trace
437 return
438 }
439 {
440 var pixel?/eax: boolean <- string-equal? f-name, "pixel"
441 compare pixel?, 0/false
442 break-if-=
443 apply-pixel args-ah, out, trace
444 return
445 }
446 {
447 var line?/eax: boolean <- string-equal? f-name, "line"
448 compare line?, 0/false
449 break-if-=
450 apply-line args-ah, out, trace
451 return
452 }
453 {
454 var hline?/eax: boolean <- string-equal? f-name, "hline"
455 compare hline?, 0/false
456 break-if-=
457 apply-hline args-ah, out, trace
458 return
459 }
460 {
461 var vline?/eax: boolean <- string-equal? f-name, "vline"
462 compare vline?, 0/false
463 break-if-=
464 apply-vline args-ah, out, trace
465 return
466 }
467 {
468 var circle?/eax: boolean <- string-equal? f-name, "circle"
469 compare circle?, 0/false
470 break-if-=
471 apply-circle args-ah, out, trace
472 return
473 }
474 {
475 var bezier?/eax: boolean <- string-equal? f-name, "bezier"
476 compare bezier?, 0/false
477 break-if-=
478 apply-bezier args-ah, out, trace
479 return
480 }
481 {
482 var width?/eax: boolean <- string-equal? f-name, "width"
483 compare width?, 0/false
484 break-if-=
485 apply-width args-ah, out, trace
486 return
487 }
488 {
489 var height?/eax: boolean <- string-equal? f-name, "height"
490 compare height?, 0/false
491 break-if-=
492 apply-height args-ah, out, trace
493 return
494 }
495 {
496 var screen?/eax: boolean <- string-equal? f-name, "new_screen"
497 compare screen?, 0/false
498 break-if-=
499 apply-new-screen args-ah, out, trace
500 return
501 }
502 {
503 var blit?/eax: boolean <- string-equal? f-name, "blit"
504 compare blit?, 0/false
505 break-if-=
506 apply-blit args-ah, out, trace
507 return
508 }
509 {
510 var wait-for-key?/eax: boolean <- string-equal? f-name, "key"
511 compare wait-for-key?, 0/false
512 break-if-=
513 apply-wait-for-key args-ah, out, trace
514 return
515 }
516 {
517 var stream?/eax: boolean <- string-equal? f-name, "stream"
518 compare stream?, 0/false
519 break-if-=
520 apply-stream args-ah, out, trace
521 return
522 }
523 {
524 var write?/eax: boolean <- string-equal? f-name, "write"
525 compare write?, 0/false
526 break-if-=
527 apply-write args-ah, out, trace
528 return
529 }
530 {
531 var rewind?/eax: boolean <- string-equal? f-name, "rewind"
532 compare rewind?, 0/false
533 break-if-=
534 apply-rewind args-ah, out, trace
535 return
536 }
537 {
538 var read?/eax: boolean <- string-equal? f-name, "read"
539 compare read?, 0/false
540 break-if-=
541 apply-read args-ah, out, trace
542 return
543 }
544 {
545 var abort?/eax: boolean <- string-equal? f-name, "abort"
546 compare abort?, 0/false
547 break-if-=
548 apply-abort args-ah, out, trace
549 return
550 }
551 abort "unknown primitive function"
552 }
553
554 fn apply-add _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
555 trace-text trace, "eval", "apply +"
556 var args-ah/eax: (addr handle cell) <- copy _args-ah
557 var _args/eax: (addr cell) <- lookup *args-ah
558 var args/esi: (addr cell) <- copy _args
559 {
560 var args-type/eax: (addr int) <- get args, type
561 compare *args-type, 0/pair
562 break-if-=
563 error trace, "args to + are not a list"
564 return
565 }
566 var empty-args?/eax: boolean <- nil? args
567 compare empty-args?, 0/false
568 {
569 break-if-=
570 error trace, "+ needs 2 args but got 0"
571 return
572 }
573
574 var first-ah/eax: (addr handle cell) <- get args, left
575 var first/eax: (addr cell) <- lookup *first-ah
576 {
577 var first-type/eax: (addr int) <- get first, type
578 compare *first-type, 1/number
579 break-if-=
580 error trace, "first arg for + is not a number"
581 return
582 }
583 var first-value/ecx: (addr float) <- get first, number-data
584
585 var right-ah/eax: (addr handle cell) <- get args, right
586 var right/eax: (addr cell) <- lookup *right-ah
587 {
588 var right-type/eax: (addr int) <- get right, type
589 compare *right-type, 0/pair
590 break-if-=
591 error trace, "+ encountered non-pair"
592 return
593 }
594 {
595 var nil?/eax: boolean <- nil? right
596 compare nil?, 0/false
597 break-if-=
598 error trace, "+ needs 2 args but got 1"
599 return
600 }
601 var second-ah/eax: (addr handle cell) <- get right, left
602 var second/eax: (addr cell) <- lookup *second-ah
603 {
604 var second-type/eax: (addr int) <- get second, type
605 compare *second-type, 1/number
606 break-if-=
607 error trace, "second arg for + is not a number"
608 return
609 }
610 var second-value/edx: (addr float) <- get second, number-data
611
612 var result/xmm0: float <- copy *first-value
613 result <- add *second-value
614 new-float out, result
615 }
616
617 fn test-evaluate-missing-arg-in-add {
618 var t-storage: trace
619 var t/edi: (addr trace) <- address t-storage
620 initialize-trace t, 0x100/max-depth, 0x100/capacity, 0/visible
621
622 var nil-storage: (handle cell)
623 var nil-ah/ecx: (addr handle cell) <- address nil-storage
624 allocate-pair nil-ah
625 var one-storage: (handle cell)
626 var one-ah/edx: (addr handle cell) <- address one-storage
627 new-integer one-ah, 1
628 var add-storage: (handle cell)
629 var add-ah/ebx: (addr handle cell) <- address add-storage
630 new-symbol add-ah, "+"
631
632 var tmp-storage: (handle cell)
633 var tmp-ah/esi: (addr handle cell) <- address tmp-storage
634 new-pair tmp-ah, *one-ah, *nil-ah
635 new-pair tmp-ah, *add-ah, *tmp-ah
636
637
638 var globals-storage: global-table
639 var globals/edx: (addr global-table) <- address globals-storage
640 initialize-globals globals
641
642 evaluate tmp-ah, tmp-ah, *nil-ah, globals, t, 0/no-screen, 0/no-keyboard, 0/definitions-created, 0/call-number
643
644 }
645
646 fn apply-subtract _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
647 trace-text trace, "eval", "apply -"
648 var args-ah/eax: (addr handle cell) <- copy _args-ah
649 var _args/eax: (addr cell) <- lookup *args-ah
650 var args/esi: (addr cell) <- copy _args
651 {
652 var args-type/eax: (addr int) <- get args, type
653 compare *args-type, 0/pair
654 break-if-=
655 error trace, "args to - are not a list"
656 return
657 }
658 var empty-args?/eax: boolean <- nil? args
659 compare empty-args?, 0/false
660 {
661 break-if-=
662 error trace, "- needs 2 args but got 0"
663 return
664 }
665
666 var first-ah/eax: (addr handle cell) <- get args, left
667 var first/eax: (addr cell) <- lookup *first-ah
668 {
669 var first-type/eax: (addr int) <- get first, type
670 compare *first-type, 1/number
671 break-if-=
672 error trace, "first arg for - is not a number"
673 return
674 }
675 var first-value/ecx: (addr float) <- get first, number-data
676
677 var right-ah/eax: (addr handle cell) <- get args, right
678 var right/eax: (addr cell) <- lookup *right-ah
679 {
680 var right-type/eax: (addr int) <- get right, type
681 compare *right-type, 0/pair
682 break-if-=
683 error trace, "- encountered non-pair"
684 return
685 }
686 {
687 var nil?/eax: boolean <- nil? right
688 compare nil?, 0/false
689 break-if-=
690 error trace, "- needs 2 args but got 1"
691 return
692 }
693 var second-ah/eax: (addr handle cell) <- get right, left
694 var second/eax: (addr cell) <- lookup *second-ah
695 {
696 var second-type/eax: (addr int) <- get second, type
697 compare *second-type, 1/number
698 break-if-=
699 error trace, "second arg for - is not a number"
700 return
701 }
702 var second-value/edx: (addr float) <- get second, number-data
703
704 var result/xmm0: float <- copy *first-value
705 result <- subtract *second-value
706 new-float out, result
707 }
708
709 fn apply-multiply _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
710 trace-text trace, "eval", "apply *"
711 var args-ah/eax: (addr handle cell) <- copy _args-ah
712 var _args/eax: (addr cell) <- lookup *args-ah
713 var args/esi: (addr cell) <- copy _args
714 {
715 var args-type/eax: (addr int) <- get args, type
716 compare *args-type, 0/pair
717 break-if-=
718 error trace, "args to * are not a list"
719 return
720 }
721 var empty-args?/eax: boolean <- nil? args
722 compare empty-args?, 0/false
723 {
724 break-if-=
725 error trace, "* needs 2 args but got 0"
726 return
727 }
728
729 var first-ah/eax: (addr handle cell) <- get args, left
730 var first/eax: (addr cell) <- lookup *first-ah
731 {
732 var first-type/eax: (addr int) <- get first, type
733 compare *first-type, 1/number
734 break-if-=
735 error trace, "first arg for * is not a number"
736 return
737 }
738 var first-value/ecx: (addr float) <- get first, number-data
739
740 var right-ah/eax: (addr handle cell) <- get args, right
741 var right/eax: (addr cell) <- lookup *right-ah
742 {
743 var right-type/eax: (addr int) <- get right, type
744 compare *right-type, 0/pair
745 break-if-=
746 error trace, "* encountered non-pair"
747 return
748 }
749 {
750 var nil?/eax: boolean <- nil? right
751 compare nil?, 0/false
752 break-if-=
753 error trace, "* needs 2 args but got 1"
754 return
755 }
756 var second-ah/eax: (addr handle cell) <- get right, left
757 var second/eax: (addr cell) <- lookup *second-ah
758 {
759 var second-type/eax: (addr int) <- get second, type
760 compare *second-type, 1/number
761 break-if-=
762 error trace, "second arg for * is not a number"
763 return
764 }
765 var second-value/edx: (addr float) <- get second, number-data
766
767 var result/xmm0: float <- copy *first-value
768 result <- multiply *second-value
769 new-float out, result
770 }
771
772 fn apply-divide _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
773 trace-text trace, "eval", "apply /"
774 var args-ah/eax: (addr handle cell) <- copy _args-ah
775 var _args/eax: (addr cell) <- lookup *args-ah
776 var args/esi: (addr cell) <- copy _args
777 {
778 var args-type/eax: (addr int) <- get args, type
779 compare *args-type, 0/pair
780 break-if-=
781 error trace, "args to / are not a list"
782 return
783 }
784 var empty-args?/eax: boolean <- nil? args
785 compare empty-args?, 0/false
786 {
787 break-if-=
788 error trace, "/ needs 2 args but got 0"
789 return
790 }
791
792 var first-ah/eax: (addr handle cell) <- get args, left
793 var first/eax: (addr cell) <- lookup *first-ah
794 {
795 var first-type/eax: (addr int) <- get first, type
796 compare *first-type, 1/number
797 break-if-=
798 error trace, "first arg for / is not a number"
799 return
800 }
801 var first-value/ecx: (addr float) <- get first, number-data
802
803 var right-ah/eax: (addr handle cell) <- get args, right
804 var right/eax: (addr cell) <- lookup *right-ah
805 {
806 var right-type/eax: (addr int) <- get right, type
807 compare *right-type, 0/pair
808 break-if-=
809 error trace, "/ encountered non-pair"
810 return
811 }
812 {
813 var nil?/eax: boolean <- nil? right
814 compare nil?, 0/false
815 break-if-=
816 error trace, "/ needs 2 args but got 1"
817 return
818 }
819 var second-ah/eax: (addr handle cell) <- get right, left
820 var second/eax: (addr cell) <- lookup *second-ah
821 {
822 var second-type/eax: (addr int) <- get second, type
823 compare *second-type, 1/number
824 break-if-=
825 error trace, "second arg for / is not a number"
826 return
827 }
828 var second-value/edx: (addr float) <- get second, number-data
829
830 var result/xmm0: float <- copy *first-value
831 result <- divide *second-value
832 new-float out, result
833 }
834
835 fn apply-remainder _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
836 trace-text trace, "eval", "apply %"
837 var args-ah/eax: (addr handle cell) <- copy _args-ah
838 var _args/eax: (addr cell) <- lookup *args-ah
839 var args/esi: (addr cell) <- copy _args
840 {
841 var args-type/eax: (addr int) <- get args, type
842 compare *args-type, 0/pair
843 break-if-=
844 error trace, "args to % are not a list"
845 return
846 }
847 var empty-args?/eax: boolean <- nil? args
848 compare empty-args?, 0/false
849 {
850 break-if-=
851 error trace, "% needs 2 args but got 0"
852 return
853 }
854
855 var first-ah/eax: (addr handle cell) <- get args, left
856 var first/eax: (addr cell) <- lookup *first-ah
857 {
858 var first-type/eax: (addr int) <- get first, type
859 compare *first-type, 1/number
860 break-if-=
861 error trace, "first arg for % is not a number"
862 return
863 }
864 var first-value/ecx: (addr float) <- get first, number-data
865
866 var right-ah/eax: (addr handle cell) <- get args, right
867 var right/eax: (addr cell) <- lookup *right-ah
868 {
869 var right-type/eax: (addr int) <- get right, type
870 compare *right-type, 0/pair
871 break-if-=
872 error trace, "% encountered non-pair"
873 return
874 }
875 {
876 var nil?/eax: boolean <- nil? right
877 compare nil?, 0/false
878 break-if-=
879 error trace, "% needs 2 args but got 1"
880 return
881 }
882 var second-ah/eax: (addr handle cell) <- get right, left
883 var second/eax: (addr cell) <- lookup *second-ah
884 {
885 var second-type/eax: (addr int) <- get second, type
886 compare *second-type, 1/number
887 break-if-=
888 error trace, "second arg for % is not a number"
889 return
890 }
891 var second-value/edx: (addr float) <- get second, number-data
892
893 var quotient/xmm0: float <- copy *first-value
894 quotient <- divide *second-value
895 var quotient-int/eax: int <- truncate quotient
896 quotient <- convert quotient-int
897 var sub-result/xmm1: float <- copy quotient
898 sub-result <- multiply *second-value
899 var result/xmm0: float <- copy *first-value
900 result <- subtract sub-result
901 new-float out, result
902 }
903
904 fn apply-square-root _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
905 trace-text trace, "eval", "apply sqrt"
906 var args-ah/eax: (addr handle cell) <- copy _args-ah
907 var _args/eax: (addr cell) <- lookup *args-ah
908 var args/esi: (addr cell) <- copy _args
909 {
910 var args-type/eax: (addr int) <- get args, type
911 compare *args-type, 0/pair
912 break-if-=
913 error trace, "args to sqrt are not a list"
914 return
915 }
916 var empty-args?/eax: boolean <- nil? args
917 compare empty-args?, 0/false
918 {
919 break-if-=
920 error trace, "sqrt needs 1 arg but got 0"
921 return
922 }
923
924 var first-ah/eax: (addr handle cell) <- get args, left
925 var first/eax: (addr cell) <- lookup *first-ah
926 {
927 var first-type/eax: (addr int) <- get first, type
928 compare *first-type, 1/number
929 break-if-=
930 error trace, "arg for sqrt is not a number"
931 return
932 }
933 var first-value/eax: (addr float) <- get first, number-data
934
935 var result/xmm0: float <- square-root *first-value
936 new-float out, result
937 }
938
939 fn apply-abs _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
940 trace-text trace, "eval", "apply abs"
941 var args-ah/eax: (addr handle cell) <- copy _args-ah
942 var _args/eax: (addr cell) <- lookup *args-ah
943 var args/esi: (addr cell) <- copy _args
944 {
945 var args-type/eax: (addr int) <- get args, type
946 compare *args-type, 0/pair
947 break-if-=
948 error trace, "args to abs are not a list"
949 return
950 }
951 var empty-args?/eax: boolean <- nil? args
952 compare empty-args?, 0/false
953 {
954 break-if-=
955 error trace, "abs needs 1 arg but got 0"
956 return
957 }
958
959 var first-ah/eax: (addr handle cell) <- get args, left
960 var first/eax: (addr cell) <- lookup *first-ah
961 {
962 var first-type/eax: (addr int) <- get first, type
963 compare *first-type, 1/number
964 break-if-=
965 error trace, "arg for abs is not a number"
966 return
967 }
968 var first-value/ecx: (addr float) <- get first, number-data
969
970 var result/xmm0: float <- copy *first-value
971 var zero: float
972 compare result, zero
973 {
974 break-if-float>=
975 var neg1/eax: int <- copy -1
976 var neg1-f/xmm1: float <- convert neg1
977 result <- multiply neg1-f
978 }
979 new-float out, result
980 }
981
982 fn apply-sgn _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
983 trace-text trace, "eval", "apply sgn"
984 var args-ah/eax: (addr handle cell) <- copy _args-ah
985 var _args/eax: (addr cell) <- lookup *args-ah
986 var args/esi: (addr cell) <- copy _args
987 {
988 var args-type/eax: (addr int) <- get args, type
989 compare *args-type, 0/pair
990 break-if-=
991 error trace, "args to sgn are not a list"
992 return
993 }
994 var empty-args?/eax: boolean <- nil? args
995 compare empty-args?, 0/false
996 {
997 break-if-=
998 error trace, "sgn needs 1 arg but got 0"
999 return
1000 }
1001
1002 var first-ah/eax: (addr handle cell) <- get args, left
1003 var first/eax: (addr cell) <- lookup *first-ah
1004 {
1005 var first-type/eax: (addr int) <- get first, type
1006 compare *first-type, 1/number
1007 break-if-=
1008 error trace, "arg for sgn is not a number"
1009 return
1010 }
1011 var first-value/ecx: (addr float) <- get first, number-data
1012
1013 var result/xmm0: float <- copy *first-value
1014 var zero: float
1015 $apply-sgn:core: {
1016 compare result, zero
1017 break-if-=
1018 {
1019 break-if-float>
1020 var neg1/eax: int <- copy -1
1021 result <- convert neg1
1022 break $apply-sgn:core
1023 }
1024 {
1025 break-if-float<
1026 var one/eax: int <- copy 1
1027 result <- convert one
1028 break $apply-sgn:core
1029 }
1030 }
1031 new-float out, result
1032 }
1033
1034 fn apply-car _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1035 trace-text trace, "eval", "apply car"
1036 var args-ah/eax: (addr handle cell) <- copy _args-ah
1037 var _args/eax: (addr cell) <- lookup *args-ah
1038 var args/esi: (addr cell) <- copy _args
1039 {
1040 var args-type/eax: (addr int) <- get args, type
1041 compare *args-type, 0/pair
1042 break-if-=
1043 error trace, "args to car are not a list"
1044 return
1045 }
1046 var empty-args?/eax: boolean <- nil? args
1047 compare empty-args?, 0/false
1048 {
1049 break-if-=
1050 error trace, "car needs 1 arg but got 0"
1051 return
1052 }
1053
1054 var first-ah/edx: (addr handle cell) <- get args, left
1055 var first/eax: (addr cell) <- lookup *first-ah
1056 {
1057 var first-type/eax: (addr int) <- get first, type
1058 compare *first-type, 0/pair
1059 break-if-=
1060 error trace, "arg for car is not a pair"
1061 return
1062 }
1063
1064 {
1065 var nil?/eax: boolean <- nil? first
1066 compare nil?, 0/false
1067 break-if-=
1068 copy-object first-ah, out
1069 return
1070 }
1071
1072 var result/eax: (addr handle cell) <- get first, left
1073 copy-object result, out
1074 }
1075
1076 fn apply-cdr _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1077 trace-text trace, "eval", "apply cdr"
1078 var args-ah/eax: (addr handle cell) <- copy _args-ah
1079 var _args/eax: (addr cell) <- lookup *args-ah
1080 var args/esi: (addr cell) <- copy _args
1081 {
1082 var args-type/eax: (addr int) <- get args, type
1083 compare *args-type, 0/pair
1084 break-if-=
1085 error trace, "args to cdr are not a list"
1086 return
1087 }
1088 var empty-args?/eax: boolean <- nil? args
1089 compare empty-args?, 0/false
1090 {
1091 break-if-=
1092 error trace, "cdr needs 1 arg but got 0"
1093 return
1094 }
1095
1096 var first-ah/edx: (addr handle cell) <- get args, left
1097 var first/eax: (addr cell) <- lookup *first-ah
1098 {
1099 var first-type/eax: (addr int) <- get first, type
1100 compare *first-type, 0/pair
1101 break-if-=
1102 error trace, "arg for cdr is not a pair"
1103 return
1104 }
1105
1106 {
1107 var nil?/eax: boolean <- nil? first
1108 compare nil?, 0/false
1109 break-if-=
1110 copy-object first-ah, out
1111 return
1112 }
1113
1114 var result/eax: (addr handle cell) <- get first, right
1115 copy-object result, out
1116 }
1117
1118 fn apply-cons _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1119 trace-text trace, "eval", "apply cons"
1120 var args-ah/eax: (addr handle cell) <- copy _args-ah
1121 var _args/eax: (addr cell) <- lookup *args-ah
1122 var args/esi: (addr cell) <- copy _args
1123 {
1124 var args-type/eax: (addr int) <- get args, type
1125 compare *args-type, 0/pair
1126 break-if-=
1127 error trace, "args to 'cons' are not a list"
1128 return
1129 }
1130 var empty-args?/eax: boolean <- nil? args
1131 compare empty-args?, 0/false
1132 {
1133 break-if-=
1134 error trace, "cons needs 2 args but got 0"
1135 return
1136 }
1137
1138 var first-ah/ecx: (addr handle cell) <- get args, left
1139
1140 var right-ah/eax: (addr handle cell) <- get args, right
1141 var right/eax: (addr cell) <- lookup *right-ah
1142 {
1143 var right-type/eax: (addr int) <- get right, type
1144 compare *right-type, 0/pair
1145 break-if-=
1146 error trace, "'cons' encountered non-pair"
1147 return
1148 }
1149 {
1150 var nil?/eax: boolean <- nil? right
1151 compare nil?, 0/false
1152 break-if-=
1153 error trace, "'cons' needs 2 args but got 1"
1154 return
1155 }
1156 var second-ah/eax: (addr handle cell) <- get right, left
1157
1158 new-pair out, *first-ah, *second-ah
1159 }
1160
1161 fn apply-cons-check _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1162 trace-text trace, "eval", "apply cons?"
1163 var args-ah/eax: (addr handle cell) <- copy _args-ah
1164 var _args/eax: (addr cell) <- lookup *args-ah
1165 var args/esi: (addr cell) <- copy _args
1166 {
1167 var args-type/eax: (addr int) <- get args, type
1168 compare *args-type, 0/pair
1169 break-if-=
1170 error trace, "args to cons? are not a list"
1171 return
1172 }
1173 var empty-args?/eax: boolean <- nil? args
1174 compare empty-args?, 0/false
1175 {
1176 break-if-=
1177 error trace, "cons? needs 1 arg but got 0"
1178 return
1179 }
1180
1181 var first-ah/edx: (addr handle cell) <- get args, left
1182 var first/eax: (addr cell) <- lookup *first-ah
1183 {
1184 var first-type/eax: (addr int) <- get first, type
1185 compare *first-type, 0/pair
1186 break-if-=
1187 nil out
1188 return
1189 }
1190 new-integer out, 1
1191 }
1192
1193
1194 fn apply-cell-isomorphic _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1195 trace-text trace, "eval", "apply '='"
1196 var args-ah/eax: (addr handle cell) <- copy _args-ah
1197 var _args/eax: (addr cell) <- lookup *args-ah
1198 var args/esi: (addr cell) <- copy _args
1199 {
1200 var args-type/eax: (addr int) <- get args, type
1201 compare *args-type, 0/pair
1202 break-if-=
1203 error trace, "args to '=' are not a list"
1204 return
1205 }
1206 var empty-args?/eax: boolean <- nil? args
1207 compare empty-args?, 0/false
1208 {
1209 break-if-=
1210 error trace, "'=' needs 2 args but got 0"
1211 return
1212 }
1213
1214 var first-ah/ecx: (addr handle cell) <- get args, left
1215
1216 var right-ah/eax: (addr handle cell) <- get args, right
1217 var right/eax: (addr cell) <- lookup *right-ah
1218 {
1219 var right-type/eax: (addr int) <- get right, type
1220 compare *right-type, 0/pair
1221 break-if-=
1222 error trace, "'=' encountered non-pair"
1223 return
1224 }
1225 {
1226 var nil?/eax: boolean <- nil? right
1227 compare nil?, 0/false
1228 break-if-=
1229 error trace, "'=' needs 2 args but got 1"
1230 return
1231 }
1232 var second-ah/edx: (addr handle cell) <- get right, left
1233
1234 var _first/eax: (addr cell) <- lookup *first-ah
1235 var first/ecx: (addr cell) <- copy _first
1236 var second/eax: (addr cell) <- lookup *second-ah
1237 var match?/eax: boolean <- cell-isomorphic? first, second, trace
1238 compare match?, 0/false
1239 {
1240 break-if-!=
1241 nil out
1242 return
1243 }
1244 new-integer out, 1/true
1245 }
1246
1247 fn apply-not _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1248 trace-text trace, "eval", "apply 'not'"
1249 var args-ah/eax: (addr handle cell) <- copy _args-ah
1250 var _args/eax: (addr cell) <- lookup *args-ah
1251 var args/esi: (addr cell) <- copy _args
1252 {
1253 var args-type/eax: (addr int) <- get args, type
1254 compare *args-type, 0/pair
1255 break-if-=
1256 error trace, "args to 'not' are not a list"
1257 return
1258 }
1259 var empty-args?/eax: boolean <- nil? args
1260 compare empty-args?, 0/false
1261 {
1262 break-if-=
1263 error trace, "'not' needs 1 arg but got 0"
1264 return
1265 }
1266
1267 var first-ah/eax: (addr handle cell) <- get args, left
1268 var first/eax: (addr cell) <- lookup *first-ah
1269
1270 var nil?/eax: boolean <- nil? first
1271 compare nil?, 0/false
1272 {
1273 break-if-!=
1274 nil out
1275 return
1276 }
1277 new-integer out, 1
1278 }
1279
1280 fn apply-debug _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1281 trace-text trace, "eval", "apply 'debug'"
1282 var args-ah/eax: (addr handle cell) <- copy _args-ah
1283 var _args/eax: (addr cell) <- lookup *args-ah
1284 var args/esi: (addr cell) <- copy _args
1285 {
1286 var args-type/eax: (addr int) <- get args, type
1287 compare *args-type, 0/pair
1288 break-if-=
1289 error trace, "args to 'debug' are not a list"
1290 return
1291 }
1292 var empty-args?/eax: boolean <- nil? args
1293 compare empty-args?, 0/false
1294 {
1295 break-if-=
1296 error trace, "'debug' needs 1 arg but got 0"
1297 return
1298 }
1299
1300 var first-ah/eax: (addr handle cell) <- get args, left
1301 dump-cell-from-cursor-over-full-screen first-ah, 7/fg 0/bg
1302 {
1303 var foo/eax: byte <- read-key 0/keyboard
1304 compare foo, 0
1305 loop-if-=
1306 }
1307
1308 }
1309
1310 fn apply-< _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1311 trace-text trace, "eval", "apply '<'"
1312 var args-ah/eax: (addr handle cell) <- copy _args-ah
1313 var _args/eax: (addr cell) <- lookup *args-ah
1314 var args/esi: (addr cell) <- copy _args
1315 {
1316 var args-type/eax: (addr int) <- get args, type
1317 compare *args-type, 0/pair
1318 break-if-=
1319 error trace, "args to '<' are not a list"
1320 return
1321 }
1322 var empty-args?/eax: boolean <- nil? args
1323 compare empty-args?, 0/false
1324 {
1325 break-if-=
1326 error trace, "'<' needs 2 args but got 0"
1327 return
1328 }
1329
1330 var first-ah/ecx: (addr handle cell) <- get args, left
1331
1332 var right-ah/eax: (addr handle cell) <- get args, right
1333 var right/eax: (addr cell) <- lookup *right-ah
1334 {
1335 var right-type/eax: (addr int) <- get right, type
1336 compare *right-type, 0/pair
1337 break-if-=
1338 error trace, "'<' encountered non-pair"
1339 return
1340 }
1341 {
1342 var nil?/eax: boolean <- nil? right
1343 compare nil?, 0/false
1344 break-if-=
1345 error trace, "'<' needs 2 args but got 1"
1346 return
1347 }
1348 var second-ah/edx: (addr handle cell) <- get right, left
1349
1350 var _first/eax: (addr cell) <- lookup *first-ah
1351 var first/ecx: (addr cell) <- copy _first
1352 {
1353 var first-type/eax: (addr int) <- get first, type
1354 compare *first-type, 1/number
1355 break-if-=
1356 error trace, "first arg for '<' is not a number"
1357 return
1358 }
1359 var first-value/ecx: (addr float) <- get first, number-data
1360 var first-float/xmm0: float <- copy *first-value
1361 var second/eax: (addr cell) <- lookup *second-ah
1362 {
1363 var second-type/eax: (addr int) <- get second, type
1364 compare *second-type, 1/number
1365 break-if-=
1366 error trace, "second arg for '<' is not a number"
1367 return
1368 }
1369 var second-value/eax: (addr float) <- get second, number-data
1370 compare first-float, *second-value
1371 {
1372 break-if-float<
1373 nil out
1374 return
1375 }
1376 new-integer out, 1/true
1377 }
1378
1379 fn apply-> _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1380 trace-text trace, "eval", "apply '>'"
1381 var args-ah/eax: (addr handle cell) <- copy _args-ah
1382 var _args/eax: (addr cell) <- lookup *args-ah
1383 var args/esi: (addr cell) <- copy _args
1384 {
1385 var args-type/eax: (addr int) <- get args, type
1386 compare *args-type, 0/pair
1387 break-if-=
1388 error trace, "args to '>' are not a list"
1389 return
1390 }
1391 var empty-args?/eax: boolean <- nil? args
1392 compare empty-args?, 0/false
1393 {
1394 break-if-=
1395 error trace, "'>' needs 2 args but got 0"
1396 return
1397 }
1398
1399 var first-ah/ecx: (addr handle cell) <- get args, left
1400
1401 var right-ah/eax: (addr handle cell) <- get args, right
1402 var right/eax: (addr cell) <- lookup *right-ah
1403 {
1404 var right-type/eax: (addr int) <- get right, type
1405 compare *right-type, 0/pair
1406 break-if-=
1407 error trace, "'>' encountered non-pair"
1408 return
1409 }
1410 {
1411 var nil?/eax: boolean <- nil? right
1412 compare nil?, 0/false
1413 break-if-=
1414 error trace, "'>' needs 2 args but got 1"
1415 return
1416 }
1417 var second-ah/edx: (addr handle cell) <- get right, left
1418
1419 var _first/eax: (addr cell) <- lookup *first-ah
1420 var first/ecx: (addr cell) <- copy _first
1421 {
1422 var first-type/eax: (addr int) <- get first, type
1423 compare *first-type, 1/number
1424 break-if-=
1425 error trace, "first arg for '>' is not a number"
1426 return
1427 }
1428 var first-value/ecx: (addr float) <- get first, number-data
1429 var first-float/xmm0: float <- copy *first-value
1430 var second/eax: (addr cell) <- lookup *second-ah
1431 {
1432 var second-type/eax: (addr int) <- get second, type
1433 compare *second-type, 1/number
1434 break-if-=
1435 error trace, "second arg for '>' is not a number"
1436 return
1437 }
1438 var second-value/eax: (addr float) <- get second, number-data
1439 compare first-float, *second-value
1440 {
1441 break-if-float>
1442 nil out
1443 return
1444 }
1445 new-integer out, 1/true
1446 }
1447
1448 fn apply-<= _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1449 trace-text trace, "eval", "apply '<='"
1450 var args-ah/eax: (addr handle cell) <- copy _args-ah
1451 var _args/eax: (addr cell) <- lookup *args-ah
1452 var args/esi: (addr cell) <- copy _args
1453 {
1454 var args-type/eax: (addr int) <- get args, type
1455 compare *args-type, 0/pair
1456 break-if-=
1457 error trace, "args to '<=' are not a list"
1458 return
1459 }
1460 var empty-args?/eax: boolean <- nil? args
1461 compare empty-args?, 0/false
1462 {
1463 break-if-=
1464 error trace, "'<=' needs 2 args but got 0"
1465 return
1466 }
1467
1468 var first-ah/ecx: (addr handle cell) <- get args, left
1469
1470 var right-ah/eax: (addr handle cell) <- get args, right
1471 var right/eax: (addr cell) <- lookup *right-ah
1472 {
1473 var right-type/eax: (addr int) <- get right, type
1474 compare *right-type, 0/pair
1475 break-if-=
1476 error trace, "'<=' encountered non-pair"
1477 return
1478 }
1479 {
1480 var nil?/eax: boolean <- nil? right
1481 compare nil?, 0/false
1482 break-if-=
1483 error trace, "'<=' needs 2 args but got 1"
1484 return
1485 }
1486 var second-ah/edx: (addr handle cell) <- get right, left
1487
1488 var _first/eax: (addr cell) <- lookup *first-ah
1489 var first/ecx: (addr cell) <- copy _first
1490 {
1491 var first-type/eax: (addr int) <- get first, type
1492 compare *first-type, 1/number
1493 break-if-=
1494 error trace, "first arg for '<=' is not a number"
1495 return
1496 }
1497 var first-value/ecx: (addr float) <- get first, number-data
1498 var first-float/xmm0: float <- copy *first-value
1499 var second/eax: (addr cell) <- lookup *second-ah
1500 {
1501 var second-type/eax: (addr int) <- get second, type
1502 compare *second-type, 1/number
1503 break-if-=
1504 error trace, "second arg for '<=' is not a number"
1505 return
1506 }
1507 var second-value/eax: (addr float) <- get second, number-data
1508 compare first-float, *second-value
1509 {
1510 break-if-float<=
1511 nil out
1512 return
1513 }
1514 new-integer out, 1/true
1515 }
1516
1517 fn apply->= _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1518 trace-text trace, "eval", "apply '>='"
1519 var args-ah/eax: (addr handle cell) <- copy _args-ah
1520 var _args/eax: (addr cell) <- lookup *args-ah
1521 var args/esi: (addr cell) <- copy _args
1522 {
1523 var args-type/eax: (addr int) <- get args, type
1524 compare *args-type, 0/pair
1525 break-if-=
1526 error trace, "args to '>=' are not a list"
1527 return
1528 }
1529 var empty-args?/eax: boolean <- nil? args
1530 compare empty-args?, 0/false
1531 {
1532 break-if-=
1533 error trace, "'>=' needs 2 args but got 0"
1534 return
1535 }
1536
1537 var first-ah/ecx: (addr handle cell) <- get args, left
1538
1539 var right-ah/eax: (addr handle cell) <- get args, right
1540 var right/eax: (addr cell) <- lookup *right-ah
1541 {
1542 var right-type/eax: (addr int) <- get right, type
1543 compare *right-type, 0/pair
1544 break-if-=
1545 error trace, "'>=' encountered non-pair"
1546 return
1547 }
1548 {
1549 var nil?/eax: boolean <- nil? right
1550 compare nil?, 0/false
1551 break-if-=
1552 error trace, "'>=' needs 2 args but got 1"
1553 return
1554 }
1555 var second-ah/edx: (addr handle cell) <- get right, left
1556
1557 var _first/eax: (addr cell) <- lookup *first-ah
1558 var first/ecx: (addr cell) <- copy _first
1559 {
1560 var first-type/eax: (addr int) <- get first, type
1561 compare *first-type, 1/number
1562 break-if-=
1563 error trace, "first arg for '>=' is not a number"
1564 return
1565 }
1566 var first-value/ecx: (addr float) <- get first, number-data
1567 var first-float/xmm0: float <- copy *first-value
1568 var second/eax: (addr cell) <- lookup *second-ah
1569 {
1570 var second-type/eax: (addr int) <- get second, type
1571 compare *second-type, 1/number
1572 break-if-=
1573 error trace, "second arg for '>=' is not a number"
1574 return
1575 }
1576 var second-value/eax: (addr float) <- get second, number-data
1577 compare first-float, *second-value
1578 {
1579 break-if-float>=
1580 nil out
1581 return
1582 }
1583 new-integer out, 1/true
1584 }
1585
1586 fn apply-print _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1587 trace-text trace, "eval", "apply 'print'"
1588 var args-ah/eax: (addr handle cell) <- copy _args-ah
1589 var _args/eax: (addr cell) <- lookup *args-ah
1590 var args/esi: (addr cell) <- copy _args
1591 {
1592 var args-type/eax: (addr int) <- get args, type
1593 compare *args-type, 0/pair
1594 break-if-=
1595 error trace, "args to 'print' are not a list"
1596 return
1597 }
1598 var empty-args?/eax: boolean <- nil? args
1599 compare empty-args?, 0/false
1600 {
1601 break-if-=
1602 error trace, "'print' needs 2 args but got 0"
1603 return
1604 }
1605
1606 var first-ah/eax: (addr handle cell) <- get args, left
1607 var first/eax: (addr cell) <- lookup *first-ah
1608 {
1609 var first-type/eax: (addr int) <- get first, type
1610 compare *first-type, 5/screen
1611 break-if-=
1612 error trace, "first arg for 'print' is not a screen"
1613 return
1614 }
1615 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1616 var _screen/eax: (addr screen) <- lookup *screen-ah
1617 var screen/ecx: (addr screen) <- copy _screen
1618
1619 var right-ah/eax: (addr handle cell) <- get args, right
1620 var right/eax: (addr cell) <- lookup *right-ah
1621 {
1622 var right-type/eax: (addr int) <- get right, type
1623 compare *right-type, 0/pair
1624 break-if-=
1625 error trace, "'print' encountered non-pair"
1626 return
1627 }
1628 {
1629 var nil?/eax: boolean <- nil? right
1630 compare nil?, 0/false
1631 break-if-=
1632 error trace, "'print' needs 2 args but got 1"
1633 return
1634 }
1635 var second-ah/eax: (addr handle cell) <- get right, left
1636 var stream-storage: (stream byte 0x100)
1637 var stream/edi: (addr stream byte) <- address stream-storage
1638 print-cell second-ah, stream, trace
1639 draw-stream-wrapping-right-then-down-from-cursor-over-full-screen screen, stream, 7/fg, 0/bg
1640
1641 copy-object second-ah, out
1642 }
1643
1644 fn apply-clear _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1645 trace-text trace, "eval", "apply 'clear'"
1646 var args-ah/eax: (addr handle cell) <- copy _args-ah
1647 var _args/eax: (addr cell) <- lookup *args-ah
1648 var args/esi: (addr cell) <- copy _args
1649 {
1650 var args-type/eax: (addr int) <- get args, type
1651 compare *args-type, 0/pair
1652 break-if-=
1653 error trace, "args to 'clear' are not a list"
1654 return
1655 }
1656 var empty-args?/eax: boolean <- nil? args
1657 compare empty-args?, 0/false
1658 {
1659 break-if-=
1660 error trace, "'clear' needs 1 arg but got 0"
1661 return
1662 }
1663
1664 var first-ah/eax: (addr handle cell) <- get args, left
1665 var first/eax: (addr cell) <- lookup *first-ah
1666 var first-type/ecx: (addr int) <- get first, type
1667 compare *first-type, 3/stream
1668 {
1669 break-if-!=
1670 var stream-data-ah/eax: (addr handle stream byte) <- get first, text-data
1671 var _stream-data/eax: (addr stream byte) <- lookup *stream-data-ah
1672 var stream-data/ebx: (addr stream byte) <- copy _stream-data
1673 clear-stream stream-data
1674 return
1675 }
1676 compare *first-type, 5/screen
1677 {
1678 break-if-!=
1679 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1680 var _screen/eax: (addr screen) <- lookup *screen-ah
1681 var screen/ecx: (addr screen) <- copy _screen
1682 clear-screen screen
1683 return
1684 }
1685 error trace, "first arg for 'clear' is not a screen or a stream"
1686 }
1687
1688 fn apply-up _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1689 trace-text trace, "eval", "apply 'up'"
1690 var args-ah/eax: (addr handle cell) <- copy _args-ah
1691 var _args/eax: (addr cell) <- lookup *args-ah
1692 var args/esi: (addr cell) <- copy _args
1693 {
1694 var args-type/eax: (addr int) <- get args, type
1695 compare *args-type, 0/pair
1696 break-if-=
1697 error trace, "args to 'up' are not a list"
1698 return
1699 }
1700 var empty-args?/eax: boolean <- nil? args
1701 compare empty-args?, 0/false
1702 {
1703 break-if-=
1704 error trace, "'up' needs 1 arg but got 0"
1705 return
1706 }
1707
1708 var first-ah/eax: (addr handle cell) <- get args, left
1709 var first/eax: (addr cell) <- lookup *first-ah
1710 {
1711 var first-type/eax: (addr int) <- get first, type
1712 compare *first-type, 5/screen
1713 break-if-=
1714 error trace, "first arg for 'up' is not a screen"
1715 return
1716 }
1717 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1718 var _screen/eax: (addr screen) <- lookup *screen-ah
1719 var screen/ecx: (addr screen) <- copy _screen
1720
1721 move-cursor-up screen
1722 }
1723
1724 fn apply-down _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1725 trace-text trace, "eval", "apply 'down'"
1726 var args-ah/eax: (addr handle cell) <- copy _args-ah
1727 var _args/eax: (addr cell) <- lookup *args-ah
1728 var args/esi: (addr cell) <- copy _args
1729 {
1730 var args-type/eax: (addr int) <- get args, type
1731 compare *args-type, 0/pair
1732 break-if-=
1733 error trace, "args to 'down' are not a list"
1734 return
1735 }
1736 var empty-args?/eax: boolean <- nil? args
1737 compare empty-args?, 0/false
1738 {
1739 break-if-=
1740 error trace, "'down' needs 1 arg but got 0"
1741 return
1742 }
1743
1744 var first-ah/eax: (addr handle cell) <- get args, left
1745 var first/eax: (addr cell) <- lookup *first-ah
1746 {
1747 var first-type/eax: (addr int) <- get first, type
1748 compare *first-type, 5/screen
1749 break-if-=
1750 error trace, "first arg for 'down' is not a screen"
1751 return
1752 }
1753 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1754 var _screen/eax: (addr screen) <- lookup *screen-ah
1755 var screen/ecx: (addr screen) <- copy _screen
1756
1757 move-cursor-down screen
1758 }
1759
1760 fn apply-left _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1761 trace-text trace, "eval", "apply 'left'"
1762 var args-ah/eax: (addr handle cell) <- copy _args-ah
1763 var _args/eax: (addr cell) <- lookup *args-ah
1764 var args/esi: (addr cell) <- copy _args
1765 {
1766 var args-type/eax: (addr int) <- get args, type
1767 compare *args-type, 0/pair
1768 break-if-=
1769 error trace, "args to 'left' are not a list"
1770 return
1771 }
1772 var empty-args?/eax: boolean <- nil? args
1773 compare empty-args?, 0/false
1774 {
1775 break-if-=
1776 error trace, "'left' needs 1 arg but got 0"
1777 return
1778 }
1779
1780 var first-ah/eax: (addr handle cell) <- get args, left
1781 var first/eax: (addr cell) <- lookup *first-ah
1782 {
1783 var first-type/eax: (addr int) <- get first, type
1784 compare *first-type, 5/screen
1785 break-if-=
1786 error trace, "first arg for 'left' is not a screen"
1787 return
1788 }
1789 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1790 var _screen/eax: (addr screen) <- lookup *screen-ah
1791 var screen/ecx: (addr screen) <- copy _screen
1792
1793 move-cursor-left screen
1794 }
1795
1796 fn apply-right _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1797 trace-text trace, "eval", "apply 'right'"
1798 var args-ah/eax: (addr handle cell) <- copy _args-ah
1799 var _args/eax: (addr cell) <- lookup *args-ah
1800 var args/esi: (addr cell) <- copy _args
1801 {
1802 var args-type/eax: (addr int) <- get args, type
1803 compare *args-type, 0/pair
1804 break-if-=
1805 error trace, "args to 'right' are not a list"
1806 return
1807 }
1808 var empty-args?/eax: boolean <- nil? args
1809 compare empty-args?, 0/false
1810 {
1811 break-if-=
1812 error trace, "'right' needs 1 arg but got 0"
1813 return
1814 }
1815
1816 var first-ah/eax: (addr handle cell) <- get args, left
1817 var first/eax: (addr cell) <- lookup *first-ah
1818 {
1819 var first-type/eax: (addr int) <- get first, type
1820 compare *first-type, 5/screen
1821 break-if-=
1822 error trace, "first arg for 'right' is not a screen"
1823 return
1824 }
1825 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1826 var _screen/eax: (addr screen) <- lookup *screen-ah
1827 var screen/ecx: (addr screen) <- copy _screen
1828
1829 move-cursor-right screen
1830 }
1831
1832 fn apply-cr _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1833 trace-text trace, "eval", "apply 'cr'"
1834 var args-ah/eax: (addr handle cell) <- copy _args-ah
1835 var _args/eax: (addr cell) <- lookup *args-ah
1836 var args/esi: (addr cell) <- copy _args
1837 {
1838 var args-type/eax: (addr int) <- get args, type
1839 compare *args-type, 0/pair
1840 break-if-=
1841 error trace, "args to 'cr' are not a list"
1842 return
1843 }
1844 var empty-args?/eax: boolean <- nil? args
1845 compare empty-args?, 0/false
1846 {
1847 break-if-=
1848 error trace, "'cr' needs 1 arg but got 0"
1849 return
1850 }
1851
1852 var first-ah/eax: (addr handle cell) <- get args, left
1853 var first/eax: (addr cell) <- lookup *first-ah
1854 {
1855 var first-type/eax: (addr int) <- get first, type
1856 compare *first-type, 5/screen
1857 break-if-=
1858 error trace, "first arg for 'cr' is not a screen"
1859 return
1860 }
1861 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1862 var _screen/eax: (addr screen) <- lookup *screen-ah
1863 var screen/ecx: (addr screen) <- copy _screen
1864
1865 move-cursor-to-left-margin-of-next-line screen
1866 }
1867
1868 fn apply-pixel _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1869 trace-text trace, "eval", "apply 'pixel'"
1870 var args-ah/eax: (addr handle cell) <- copy _args-ah
1871 var _args/eax: (addr cell) <- lookup *args-ah
1872 var args/esi: (addr cell) <- copy _args
1873 {
1874 var args-type/eax: (addr int) <- get args, type
1875 compare *args-type, 0/pair
1876 break-if-=
1877 error trace, "args to 'pixel' are not a list"
1878 return
1879 }
1880 var empty-args?/eax: boolean <- nil? args
1881 compare empty-args?, 0/false
1882 {
1883 break-if-=
1884 error trace, "'pixel' needs 4 args but got 0"
1885 return
1886 }
1887
1888 var first-ah/eax: (addr handle cell) <- get args, left
1889 var first/eax: (addr cell) <- lookup *first-ah
1890 {
1891 var first-type/eax: (addr int) <- get first, type
1892 compare *first-type, 5/screen
1893 break-if-=
1894 error trace, "first arg for 'pixel' is not a screen"
1895 return
1896 }
1897 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1898 var _screen/eax: (addr screen) <- lookup *screen-ah
1899 var screen/edi: (addr screen) <- copy _screen
1900
1901 var rest-ah/eax: (addr handle cell) <- get args, right
1902 var _rest/eax: (addr cell) <- lookup *rest-ah
1903 var rest/esi: (addr cell) <- copy _rest
1904 {
1905 var rest-type/eax: (addr int) <- get rest, type
1906 compare *rest-type, 0/pair
1907 break-if-=
1908 error trace, "'pixel' encountered non-pair"
1909 return
1910 }
1911 {
1912 var rest-nil?/eax: boolean <- nil? rest
1913 compare rest-nil?, 0/false
1914 break-if-=
1915 error trace, "'pixel' needs 4 args but got 1"
1916 return
1917 }
1918 var second-ah/eax: (addr handle cell) <- get rest, left
1919 var second/eax: (addr cell) <- lookup *second-ah
1920 {
1921 var second-type/eax: (addr int) <- get second, type
1922 compare *second-type, 1/number
1923 break-if-=
1924 error trace, "second arg for 'pixel' is not an int (x coordinate)"
1925 return
1926 }
1927 var second-value/eax: (addr float) <- get second, number-data
1928 var x/edx: int <- convert *second-value
1929
1930 var rest-ah/eax: (addr handle cell) <- get rest, right
1931 var _rest/eax: (addr cell) <- lookup *rest-ah
1932 rest <- copy _rest
1933 {
1934 var rest-type/eax: (addr int) <- get rest, type
1935 compare *rest-type, 0/pair
1936 break-if-=
1937 error trace, "'pixel' encountered non-pair"
1938 return
1939 }
1940 {
1941 var rest-nil?/eax: boolean <- nil? rest
1942 compare rest-nil?, 0/false
1943 break-if-=
1944 error trace, "'pixel' needs 4 args but got 2"
1945 return
1946 }
1947 var third-ah/eax: (addr handle cell) <- get rest, left
1948 var third/eax: (addr cell) <- lookup *third-ah
1949 {
1950 var third-type/eax: (addr int) <- get third, type
1951 compare *third-type, 1/number
1952 break-if-=
1953 error trace, "third arg for 'pixel' is not an int (y coordinate)"
1954 return
1955 }
1956 var third-value/eax: (addr float) <- get third, number-data
1957 var y/ebx: int <- convert *third-value
1958
1959 var rest-ah/eax: (addr handle cell) <- get rest, right
1960 var _rest/eax: (addr cell) <- lookup *rest-ah
1961 rest <- copy _rest
1962 {
1963 var rest-type/eax: (addr int) <- get rest, type
1964 compare *rest-type, 0/pair
1965 break-if-=
1966 error trace, "'pixel' encountered non-pair"
1967 return
1968 }
1969 {
1970 var rest-nil?/eax: boolean <- nil? rest
1971 compare rest-nil?, 0/false
1972 break-if-=
1973 error trace, "'pixel' needs 4 args but got 3"
1974 return
1975 }
1976 var fourth-ah/eax: (addr handle cell) <- get rest, left
1977 var fourth/eax: (addr cell) <- lookup *fourth-ah
1978 {
1979 var fourth-type/eax: (addr int) <- get fourth, type
1980 compare *fourth-type, 1/number
1981 break-if-=
1982 error trace, "fourth arg for 'pixel' is not an int (color; 0..0xff)"
1983 return
1984 }
1985 var fourth-value/eax: (addr float) <- get fourth, number-data
1986 var color/eax: int <- convert *fourth-value
1987 pixel screen, x, y, color
1988
1989 }
1990
1991 fn apply-line _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1992 trace-text trace, "eval", "apply 'line'"
1993 var args-ah/eax: (addr handle cell) <- copy _args-ah
1994 var _args/eax: (addr cell) <- lookup *args-ah
1995 var args/esi: (addr cell) <- copy _args
1996 {
1997 var args-type/eax: (addr int) <- get args, type
1998 compare *args-type, 0/pair
1999 break-if-=
2000 error trace, "args to 'line' are not a list"
2001 return
2002 }
2003 var empty-args?/eax: boolean <- nil? args
2004 compare empty-args?, 0/false
2005 {
2006 break-if-=
2007 error trace, "'line' needs 6 args but got 0"
2008 return
2009 }
2010
2011 var first-ah/eax: (addr handle cell) <- get args, left
2012 var first/eax: (addr cell) <- lookup *first-ah
2013 {
2014 var first-type/eax: (addr int) <- get first, type
2015 compare *first-type, 5/screen
2016 break-if-=
2017 error trace, "first arg for 'line' is not a screen"
2018 return
2019 }
2020 var screen-ah/eax: (addr handle screen) <- get first, screen-data
2021 var _screen/eax: (addr screen) <- lookup *screen-ah
2022 var screen/edi: (addr screen) <- copy _screen
2023
2024 var rest-ah/eax: (addr handle cell) <- get args, right
2025 var _rest/eax: (addr cell) <- lookup *rest-ah
2026 var rest/esi: (addr cell) <- copy _rest
2027 {
2028 var rest-type/eax: (addr int) <- get rest, type
2029 compare *rest-type, 0/pair
2030 break-if-=
2031 error trace, "'line' encountered non-pair"
2032 return
2033 }
2034 {
2035 var rest-nil?/eax: boolean <- nil? rest
2036 compare rest-nil?, 0/false
2037 break-if-=
2038 error trace, "'line' needs 6 args but got 1"
2039 return
2040 }
2041 var second-ah/eax: (addr handle cell) <- get rest, left
2042 var second/eax: (addr cell) <- lookup *second-ah
2043 {
2044 var second-type/eax: (addr int) <- get second, type
2045 compare *second-type, 1/number
2046 break-if-=
2047 error trace, "second arg for 'line' is not a number (screen x coordinate of start point)"
2048 return
2049 }
2050 var second-value/eax: (addr float) <- get second, number-data
2051 var x1/edx: int <- convert *second-value
2052
2053 var rest-ah/eax: (addr handle cell) <- get rest, right
2054 var _rest/eax: (addr cell) <- lookup *rest-ah
2055 rest <- copy _rest
2056 {
2057 var rest-type/eax: (addr int) <- get rest, type
2058 compare *rest-type, 0/pair
2059 break-if-=
2060 error trace, "'line' encountered non-pair"
2061 return
2062 }
2063 {
2064 var rest-nil?/eax: boolean <- nil? rest
2065 compare rest-nil?, 0/false
2066 break-if-=
2067 error trace, "'line' needs 6 args but got 2"
2068 return
2069 }
2070 var third-ah/eax: (addr handle cell) <- get rest, left
2071 var third/eax: (addr cell) <- lookup *third-ah
2072 {
2073 var third-type/eax: (addr int) <- get third, type
2074 compare *third-type, 1/number
2075 break-if-=
2076 error trace, "third arg for 'line' is not a number (screen y coordinate of start point)"
2077 return
2078 }
2079 var third-value/eax: (addr float) <- get third, number-data
2080 var y1/ebx: int <- convert *third-value
2081
2082 var rest-ah/eax: (addr handle cell) <- get rest, right
2083 var _rest/eax: (addr cell) <- lookup *rest-ah
2084 var rest/esi: (addr cell) <- copy _rest
2085 {
2086 var rest-type/eax: (addr int) <- get rest, type
2087 compare *rest-type, 0/pair
2088 break-if-=
2089 error trace, "'line' encountered non-pair"
2090 return
2091 }
2092 {
2093 var rest-nil?/eax: boolean <- nil? rest
2094 compare rest-nil?, 0/false
2095 break-if-=
2096 error trace, "'line' needs 6 args but got 3"
2097 return
2098 }
2099 var fourth-ah/eax: (addr handle cell) <- get rest, left
2100 var fourth/eax: (addr cell) <- lookup *fourth-ah
2101 {
2102 var fourth-type/eax: (addr int) <- get fourth, type
2103 compare *fourth-type, 1/number
2104 break-if-=
2105 error trace, "fourth arg for 'line' is not a number (screen x coordinate of end point)"
2106 return
2107 }
2108 var fourth-value/eax: (addr float) <- get fourth, number-data
2109 var x2/ecx: int <- convert *fourth-value
2110
2111 var rest-ah/eax: (addr handle cell) <- get rest, right
2112 var _rest/eax: (addr cell) <- lookup *rest-ah
2113 rest <- copy _rest
2114 {
2115 var rest-type/eax: (addr int) <- get rest, type
2116 compare *rest-type, 0/pair
2117 break-if-=
2118 error trace, "'line' encountered non-pair"
2119 return
2120 }
2121 {
2122 var rest-nil?/eax: boolean <- nil? rest
2123 compare rest-nil?, 0/false
2124 break-if-=
2125 error trace, "'line' needs 6 args but got 4"
2126 return
2127 }
2128 var fifth-ah/eax: (addr handle cell) <- get rest, left
2129 var fifth/eax: (addr cell) <- lookup *fifth-ah
2130 {
2131 var fifth-type/eax: (addr int) <- get fifth, type
2132 compare *fifth-type, 1/number
2133 break-if-=
2134 error trace, "fifth arg for 'line' is not a number (screen y coordinate of end point)"
2135 return
2136 }
2137 var fifth-value/eax: (addr float) <- get fifth, number-data
2138 var tmp/eax: int <- convert *fifth-value
2139 var y2: int
2140 copy-to y2, tmp
2141
2142 var rest-ah/eax: (addr handle cell) <- get rest, right
2143 var _rest/eax: (addr cell) <- lookup *rest-ah
2144 rest <- copy _rest
2145 {
2146 var rest-type/eax: (addr int) <- get rest, type
2147 compare *rest-type, 0/pair
2148 break-if-=
2149 error trace, "'line' encountered non-pair"
2150 return
2151 }
2152 {
2153 var rest-nil?/eax: boolean <- nil? rest
2154 compare rest-nil?, 0/false
2155 break-if-=
2156 error trace, "'line' needs 6 args but got 5"
2157 return
2158 }
2159 var sixth-ah/eax: (addr handle cell) <- get rest, left
2160 var sixth/eax: (addr cell) <- lookup *sixth-ah
2161 {
2162 var sixth-type/eax: (addr int) <- get sixth, type
2163 compare *sixth-type, 1/number
2164 break-if-=
2165 error trace, "sixth arg for 'line' is not an int (color; 0..0xff)"
2166 return
2167 }
2168 var sixth-value/eax: (addr float) <- get sixth, number-data
2169 var color/eax: int <- convert *sixth-value
2170 draw-line screen, x1, y1, x2, y2, color
2171
2172 }
2173
2174 fn apply-hline _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
2175 trace-text trace, "eval", "apply 'hline'"
2176 var args-ah/eax: (addr handle cell) <- copy _args-ah
2177 var _args/eax: (addr cell) <- lookup *args-ah
2178 var args/esi: (addr cell) <- copy _args
2179 {
2180 var args-type/eax: (addr int) <- get args, type
2181 compare *args-type, 0/pair
2182 break-if-=
2183 error trace, "args to 'hline' are not a list"
2184 return
2185 }
2186 var empty-args?/eax: boolean <- nil? args
2187 compare empty-args?, 0/false
2188 {
2189 break-if-=
2190 error trace, "'hline' needs 5 args but got 0"
2191 return
2192 }
2193
2194 var first-ah/eax: (addr handle cell) <- get args, left
2195 var first/eax: (addr cell) <- lookup *first-ah
2196 {
2197 var first-type/eax: (addr int) <- get first, type
2198 compare *first-type, 5/screen
2199 break-if-=
2200 error trace, "first arg for 'hline' is not a screen"
2201 return
2202 }
2203 var screen-ah/eax: (addr handle screen) <- get first, screen-data
2204 var _screen/eax: (addr screen) <- lookup *screen-ah
2205 var screen/edi: (addr screen) <- copy _screen
2206
2207 var rest-ah/eax: (addr handle cell) <- get args, right
2208 var _rest/eax: (addr cell) <- lookup *rest-ah
2209 var rest/esi: (addr cell) <- copy _rest
2210 {
2211 var rest-type/eax: (addr int) <- get rest, type
2212 compare *rest-type, 0/pair
2213 break-if-=
2214 error trace, "'hline' encountered non-pair"
2215 return
2216 }
2217 {
2218 var rest-nil?/eax: boolean <- nil? rest
2219 compare rest-nil?, 0/false
2220 break-if-=
2221 error trace, "'hline' needs 5 args but got 1"
2222 return
2223 }
2224 var second-ah/eax: (addr handle cell) <- get rest, left
2225 var second/eax: (addr cell) <- lookup *second-ah
2226 {
2227 var second-type/eax: (addr int) <- get second, type
2228 compare *second-type, 1/number
2229 break-if-=
2230 error trace, "second arg for 'hline' is not a number (screen y coordinate)"
2231 return
2232 }
2233 var second-value/eax: (addr float) <- get second, number-data
2234 var y/edx: int <- convert *second-value
2235
2236 var rest-ah/eax: (addr handle cell) <- get rest, right
2237 var _rest/eax: (addr cell) <- lookup *rest-ah
2238 rest <- copy _rest
2239 {
2240 var rest-type/eax: (addr int) <- get rest, type
2241 compare *rest-type, 0/pair
2242 break-if-=
2243 error trace, "'hline' encountered non-pair"
2244 return
2245 }
2246 {
2247 var rest-nil?/eax: boolean <- nil? rest
2248 compare rest-nil?, 0/false
2249 break-if-=
2250 error trace, "'hline' needs 5 args but got 2"
2251 return
2252 }
2253 var third-ah/eax: (addr handle cell) <- get rest, left
2254 var third/eax: (addr cell) <- lookup *third-ah
2255 {
2256 var third-type/eax: (addr int) <- get third, type
2257 compare *third-type, 1/number
2258 break-if-=
2259 error trace, "third arg for 'hline' is not a number (screen x coordinate of start point)"
2260 return
2261 }
2262 var third-value/eax: (addr float) <- get third, number-data
2263 var x1/ebx: int <- convert *third-value
2264
2265 var rest-ah/eax: (addr handle cell) <- get rest, right
2266 var _rest/eax: (addr cell) <- lookup *rest-ah
2267 var rest/esi: (addr cell) <- copy _rest
2268 {
2269 var rest-type/eax: (addr int) <- get rest, type
2270 compare *rest-type, 0/pair
2271 break-if-=
2272 error trace, "'hline' encountered non-pair"
2273 return
2274 }
2275 {
2276 var rest-nil?/eax: boolean <- nil? rest
2277 compare rest-nil?, 0/false
2278 break-if-=
2279 error trace, "'hline' needs 5 args but got 3"
2280 return
2281 }
2282 var fourth-ah/eax: (addr handle cell) <- get rest, left
2283 var fourth/eax: (addr cell) <- lookup *fourth-ah
2284 {
2285 var fourth-type/eax: (addr int) <- get fourth, type
2286 compare *fourth-type, 1/number
2287 break-if-=
2288 error trace, "fourth arg for 'hline' is not a number (screen x coordinate of end point)"
2289 return
2290 }
2291 var fourth-value/eax: (addr float) <- get fourth, number-data
2292 var x2/ecx: int <- convert *fourth-value
2293
2294 var rest-ah/eax: (addr handle cell) <- get rest, right
2295 var _rest/eax: (addr cell) <- lookup *rest-ah
2296 rest <- copy _rest
2297 {
2298 var rest-type/eax: (addr int) <- get rest, type
2299 compare *rest-type, 0/pair
2300 break-if-=
2301 error trace, "'hline' encountered non-pair"
2302 return
2303 }
2304 {
2305 var rest-nil?/eax: boolean <- nil? rest
2306 compare rest-nil?, 0/false
2307 break-if-=
2308 error trace, "'hline' needs 5 args but got 5"
2309 return
2310 }
2311 var fifth-ah/eax: (addr handle cell) <- get rest, left
2312 var fifth/eax: (addr cell) <- lookup *fifth-ah
2313 {
2314 var fifth-type/eax: (addr int) <- get fifth, type
2315 compare *fifth-type, 1/number
2316 break-if-=
2317 error trace, "fifth arg for 'hline' is not an int (color; 0..0xff)"
2318 return
2319 }
2320 var fifth-value/eax: (addr float) <- get fifth, number-data
2321 var color/eax: int <- convert *fifth-value
2322 draw-horizontal-line screen, y, x1, x2, color
2323
2324 }
2325
2326 fn apply-vline _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
2327 trace-text trace, "eval", "apply 'vline'"
2328 var args-ah/eax: (addr handle cell) <- copy _args-ah
2329 var _args/eax: (addr cell) <- lookup *args-ah
2330 var args/esi: (addr cell) <- copy _args
2331 {
2332 var args-type/eax: (addr int) <- get args, type
2333 compare *args-type, 0/pair
2334 break-if-=
2335 error trace, "args to 'vline' are not a list"
2336 return
2337 }
2338 var empty-args?/eax: boolean <- nil? args
2339 compare empty-args?, 0/false
2340 {
2341 break-if-=
2342 error trace, "'vline' needs 5 args but got 0"
2343 return
2344 }
2345
2346 var first-ah/eax: (addr handle cell) <- get args, left
2347 var first/eax: (addr cell) <- lookup *first-ah
2348 {
2349 var first-type/eax: (addr int) <- get first, type
2350 compare *first-type, 5/screen
2351 break-if-=
2352 error trace, "first arg for 'vline' is not a screen"
2353 return
2354 }
2355 var screen-ah/eax: (addr handle screen) <- get first, screen-data
2356 var _screen/eax: (addr screen) <- lookup *screen-ah
2357 var screen/edi: (addr screen) <- copy _screen
2358
2359 var rest-ah/eax: (addr handle cell) <- get args, right
2360 var _rest/eax: (addr cell) <- lookup *rest-ah
2361 var rest/esi: (addr cell) <- copy _rest
2362 {
2363 var rest-type/eax: (addr int) <- get rest, type
2364 compare *rest-type, 0/pair
2365 break-if-=
2366 error trace, "'vline' encountered non-pair"
2367 return
2368 }
2369 {
2370 var rest-nil?/eax: boolean <- nil? rest
2371 compare rest-nil?, 0/false
2372 break-if-=
2373 error trace, "'vline' needs 5 args but got 1"
2374 return
2375 }
2376 var second-ah/eax: (addr handle cell) <- get rest, left
2377 var second/eax: (addr cell) <- lookup *second-ah
2378 {
2379 var second-type/eax: (addr int) <- get second, type
2380 compare *second-type, 1/number
2381 break-if-=
2382 error trace, "second arg for 'vline' is not a number (screen x coordinate)"
2383 return
2384 }
2385 var second-value/eax: (addr float) <- get second, number-data
2386 var x/edx: int <- convert *second-value
2387
2388 var rest-ah/eax: (addr handle cell) <- get rest, right
2389 var _rest/eax: (addr cell) <- lookup *rest-ah
2390 rest <- copy _rest
2391 {
2392 var rest-type/eax: (addr int) <- get rest, type
2393 compare *rest-type, 0/pair
2394 break-if-=
2395 error trace, "'vline' encountered non-pair"
2396 return
2397 }
2398 {
2399 var rest-nil?/eax: boolean <- nil? rest
2400 compare rest-nil?, 0/false
2401 break-if-=
2402 error trace, "'vline' needs 5 args but got 2"
2403 return
2404 }
2405 var third-ah/eax: (addr handle cell) <- get rest, left
2406 var third/eax: (addr cell) <- lookup *third-ah
2407 {
2408 var third-type/eax: (addr int) <- get third, type
2409 compare *third-type, 1/number
2410 break-if-=
2411 error trace, "third arg for 'vline' is not a number (screen y coordinate of start point)"
2412 return
2413 }
2414 var third-value/eax: (addr float) <- get third, number-data
2415 var y1/ebx: int <- convert *third-value
2416
2417 var rest-ah/eax: (addr handle cell) <- get rest, right
2418 var _rest/eax: (addr cell) <- lookup *rest-ah
2419 var rest/esi: (addr cell) <- copy _rest
2420 {
2421 var rest-type/eax: (addr int) <- get rest, type
2422 compare *rest-type, 0/pair
2423 break-if-=
2424 error trace, "'vline' encountered non-pair"
2425 return
2426 }
2427 {
2428 var rest-nil?/eax: boolean <- nil? rest
2429 compare rest-nil?, 0/false
2430 break-if-=
2431 error trace, "'vline' needs 5 args but got 3"
2432 return
2433 }
2434 var fourth-ah/eax: (addr handle cell) <- get rest, left
2435 var fourth/eax: (addr cell) <- lookup *fourth-ah
2436 {
2437 var fourth-type/eax: (addr int) <- get fourth, type
2438 compare *fourth-type, 1/number
2439 break-if-=
2440 error trace, "fourth arg for 'vline' is not a number (screen y coordinate of end point)"
2441 return
2442 }
2443 var fourth-value/eax: (addr float) <- get fourth, number-data
2444 var y2/ecx: int <- convert *fourth-value
2445
2446 var rest-ah/eax: (addr handle cell) <- get rest, right
2447 var _rest/eax: (addr cell) <- lookup *rest-ah
2448 rest <- copy _rest
2449 {
2450 var rest-type/eax: (addr int) <- get rest, type
2451 compare *rest-type, 0/pair
2452 break-if-=
2453 error trace, "'vline' encountered non-pair"
2454 return
2455 }
2456 {
2457 var rest-nil?/eax: boolean <- nil? rest
2458 compare rest-nil?, 0/false
2459 break-if-=
2460 error trace, "'vline' needs 5 args but got 5"
2461 return
2462 }
2463 var fifth-ah/eax: (addr handle cell) <- get rest, left
2464 var fifth/eax: (addr cell) <- lookup *fifth-ah
2465 {
2466 var fifth-type/eax: (addr int) <- get fifth, type
2467 compare *fifth-type, 1/number
2468 break-if-=
2469 error trace, "fifth arg for 'vline' is not an int (color; 0..0xff)"
2470 return
2471 }
2472 var fifth-value/eax: (addr float) <- get fifth, number-data
2473 var color/eax: int <- convert *fifth-value
2474 draw-vertical-line screen, x, y1, y2, color
2475
2476 }
2477
2478 fn apply-circle _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
2479 trace-text trace, "eval", "apply 'circle'"
2480 var args-ah/eax: (addr handle cell) <- copy _args-ah
2481 var _args/eax: (addr cell) <- lookup *args-ah
2482 var args/esi: (addr cell) <- copy _args
2483 {
2484 var args-type/eax: (addr int) <- get args, type
2485 compare *args-type, 0/pair
2486 break-if-=
2487 error trace, "args to 'circle' are not a list"
2488 return
2489 }
2490 var empty-args?/eax: boolean <- nil? args
2491 compare empty-args?, 0/false
2492 {
2493 break-if-=
2494 error trace, "'circle' needs 5 args but got 0"
2495 return
2496 }
2497
2498 var first-ah/eax: (addr handle cell) <- get args, left
2499 var first/eax: (addr cell) <- lookup *first-ah
2500 {
2501 var first-type/eax: (addr int) <- get first, type
2502 compare *first-type, 5/screen
2503 break-if-=
2504 error trace, "first arg for 'circle' is not a screen"
2505 return
2506 }
2507 var screen-ah/eax: (addr handle screen) <- get first, screen-data
2508 var _screen/eax: (addr screen) <- lookup *screen-ah
2509 var screen/edi: (addr screen) <- copy _screen
2510
2511 var rest-ah/eax: (addr handle cell) <- get args, right
2512 var _rest/eax: (addr cell) <- lookup *rest-ah
2513 var rest/esi: (addr cell) <- copy _rest
2514 {
2515 var rest-type/eax: (addr int) <- get rest, type
2516 compare *rest-type, 0/pair
2517 break-if-=
2518 error trace, "'circle' encountered non-pair"
2519 return
2520 }
2521 {
2522 var rest-nil?/eax: boolean <- nil? rest
2523 compare rest-nil?, 0/false
2524 break-if-=
2525 error trace, "'circle' needs 5 args but got 1"
2526 return
2527 }
2528 var second-ah/eax: (addr handle cell) <- get rest, left
2529 var second/eax: (addr cell) <- lookup *second-ah
2530 {
2531 var second-type/eax: (addr int) <- get second, type
2532 compare *second-type, 1/number
2533 break-if-=
2534 error trace, "second arg for 'circle' is not a number (screen x coordinate of center)"
2535 return
2536 }
2537 var second-value/eax: (addr float) <- get second, number-data
2538 var cx/edx: int <- convert *second-value
2539
2540 var rest-ah/eax: (addr handle cell) <- get rest, right
2541 var _rest/eax: (addr cell) <- lookup *rest-ah
2542 rest <- copy _rest
2543 {
2544 var rest-type/eax: (addr int) <- get rest, type
2545 compare *rest-type, 0/pair
2546 break-if-=
2547 error trace, "'circle' encountered non-pair"
2548 return
2549 }
2550 {
2551 var rest-nil?/eax: boolean <- nil? rest
2552 compare rest-nil?, 0/false
2553 break-if-=
2554 error trace, "'circle' needs 5 args but got 2"
2555 return
2556 }
2557 var third-ah/eax: (addr handle cell) <- get rest, left
2558 var third/eax: (addr cell) <- lookup *third-ah
2559 {
2560 var third-type/eax: (addr int) <- get third, type
2561 compare *third-type, 1/number
2562 break-if-=
2563 error trace, "third arg for 'circle' is not a number (screen y coordinate of center)"
2564 return
2565 }
2566 var third-value/eax: (addr float) <- get third, number-data
2567 var cy/ebx: int <- convert *third-value
2568
2569 var rest-ah/eax: (addr handle cell) <- get rest, right
2570 var _rest/eax: (addr cell) <- lookup *rest-ah
2571 var rest/esi: (addr cell) <- copy _rest
2572 {
2573 var rest-type/eax: (addr int) <- get rest, type
2574 compare *rest-type, 0/pair
2575 break-if-=
2576 error trace, "'circle' encountered non-pair"
2577 return
2578 }
2579 {
2580 var rest-nil?/eax: boolean <- nil? rest
2581 compare rest-nil?, 0/false
2582 break-if-=
2583 error trace, "'circle' needs 5 args but got 3"
2584 return
2585 }
2586 var fourth-ah/eax: (addr handle cell) <- get rest, left
2587 var fourth/eax: (addr cell) <- lookup *fourth-ah
2588 {
2589 var fourth-type/eax: (addr int) <- get fourth, type
2590 compare *fourth-type, 1/number
2591 break-if-=
2592 error trace, "fourth arg for 'circle' is not a number (screen radius)"
2593 return
2594 }
2595 var fourth-value/eax: (addr float) <- get fourth, number-data
2596 var r/ecx: int <- convert *fourth-value
2597
2598 var rest-ah/eax: (addr handle cell) <- get rest, right
2599 var _rest/eax: (addr cell) <- lookup *rest-ah
2600 rest <- copy _rest
2601 {
2602 var rest-type/eax: (addr int) <- get rest, type
2603 compare *rest-type, 0/pair
2604 break-if-=
2605 error trace, "'circle' encountered non-pair"
2606 return
2607 }
2608 {
2609 var rest-nil?/eax: boolean <- nil? rest
2610 compare rest-nil?, 0/false
2611 break-if-=
2612 error trace, "'circle' needs 5 args but got 5"
2613 return
2614 }
2615 var fifth-ah/eax: (addr handle cell) <- get rest, left
2616 var fifth/eax: (addr cell) <- lookup *fifth-ah
2617 {
2618 var fifth-type/eax: (addr int) <- get fifth, type
2619 compare *fifth-type, 1/number
2620 break-if-=
2621 error trace, "fifth arg for 'circle' is not an int (color; 0..0xff)"
2622 return
2623 }
2624 var fifth-value/eax: (addr float) <- get fifth, number-data
2625 var color/eax: int <- convert *fifth-value
2626 draw-circle screen, cx, cy, r, color
2627
2628 }
2629
2630 fn apply-bezier _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
2631 trace-text trace, "eval", "apply 'bezier'"
2632 var args-ah/eax: (addr handle cell) <- copy _args-ah
2633 var _args/eax: (addr cell) <- lookup *args-ah
2634 var args/esi: (addr cell) <- copy _args
2635 {
2636 var args-type/eax: (addr int) <- get args, type
2637 compare *args-type, 0/pair
2638 break-if-=
2639 error trace, "args to 'bezier' are not a list"
2640 return
2641 }
2642 var empty-args?/eax: boolean <- nil? args
2643 compare empty-args?, 0/false
2644 {
2645 break-if-=
2646 error trace, "'bezier' needs 8 args but got 0"
2647 return
2648 }
2649
2650 var first-ah/eax: (addr handle cell) <- get args, left
2651 var first/eax: (addr cell) <- lookup *first-ah
2652 {
2653 var first-type/eax: (addr int) <- get first, type
2654 compare *first-type, 5/screen
2655 break-if-=
2656 error trace, "first arg for 'bezier' is not a screen"
2657 return
2658 }
2659 var screen-ah/eax: (addr handle screen) <- get first, screen-data
2660 var _screen/eax: (addr screen) <- lookup *screen-ah
2661 var screen/edi: (addr screen) <- copy _screen
2662
2663 var rest-ah/eax: (addr handle cell) <- get args, right
2664 var _rest/eax: (addr cell) <- lookup *rest-ah
2665 var rest/esi: (addr cell) <- copy _rest
2666 {
2667 var rest-type/eax: (addr int) <- get rest, type
2668 compare *rest-type, 0/pair
2669 break-if-=
2670 error trace, "'bezier' encountered non-pair"
2671 return
2672 }
2673 {
2674 var rest-nil?/eax: boolean <- nil? rest
2675 compare rest-nil?, 0/false
2676 break-if-=
2677 error trace, "'bezier' needs 8 args but got 1"
2678 return
2679 }
2680 var second-ah/eax: (addr handle cell) <- get rest, left
2681 var second/eax: (addr cell) <- lookup *second-ah
2682 {
2683 var second-type/eax: (addr int) <- get second, type
2684 compare *second-type, 1/number
2685 break-if-=
2686 error trace, "second arg for 'bezier' is not a number (screen x coordinate of start point)"
2687 return
2688 }
2689 var second-value/eax: (addr float) <- get second, number-data
2690 var x0/edx: int <- convert *second-value
2691
2692 var rest-ah/eax: (addr handle cell) <- get rest, right
2693 var _rest/eax: (addr cell) <- lookup *rest-ah
2694 rest <- copy _rest
2695 {
2696 var rest-type/eax: (addr int) <- get rest, type
2697 compare *rest-type, 0/pair
2698 break-if-=
2699 error trace, "'bezier' encountered non-pair"
2700 return
2701 }
2702 {
2703 var rest-nil?/eax: boolean <- nil? rest
2704 compare rest-nil?, 0/false
2705 break-if-=
2706 error trace, "'bezier' needs 8 args but got 2"
2707 return
2708 }
2709 var third-ah/eax: (addr handle cell) <- get rest, left
2710 var third/eax: (addr cell) <- lookup *third-ah
2711 {
2712 var third-type/eax: (addr int) <- get third, type
2713 compare *third-type, 1/number
2714 break-if-=
2715 error trace, "third arg for 'bezier' is not a number (screen y coordinate of start point)"
2716 return
2717 }
2718 var third-value/eax: (addr float) <- get third, number-data
2719 var y0/ebx: int <- convert *third-value
2720
2721 var rest-ah/eax: (addr handle cell) <- get rest, right
2722 var _rest/eax: (addr cell) <- lookup *rest-ah
2723 var rest/esi: (addr cell) <- copy _rest
2724 {
2725 var rest-type/eax: (addr int) <- get rest, type
2726 compare *rest-type, 0/pair
2727 break-if-=
2728 error trace, "'bezier' encountered non-pair"
2729 return
2730 }
2731 {
2732 var rest-nil?/eax: boolean <- nil? rest
2733 compare rest-nil?, 0/false
2734 break-if-=
2735 error trace, "'bezier' needs 8 args but got 3"
2736 return
2737 }
2738 var fourth-ah/eax: (addr handle cell) <- get rest, left
2739 var fourth/eax: (addr cell) <- lookup *fourth-ah
2740 {
2741 var fourth-type/eax: (addr int) <- get fourth, type
2742 compare *fourth-type, 1/number
2743 break-if-=
2744 error trace, "fourth arg for 'bezier' is not a number (screen x coordinate of control point)"
2745 return
2746 }
2747 var fourth-value/eax: (addr float) <- get fourth, number-data
2748 var tmp/eax: int <- convert *fourth-value
2749 var x1: int
2750 copy-to x1, tmp
2751
2752 var rest-ah/eax: (addr handle cell) <- get rest, right
2753 var _rest/eax: (addr cell) <- lookup *rest-ah
2754 rest <- copy _rest
2755 {
2756 var rest-type/eax: (addr int) <- get rest, type
2757 compare *rest-type, 0/pair
2758 break-if-=
2759 error trace, "'bezier' encountered non-pair"
2760 return
2761 }
2762 {
2763 var rest-nil?/eax: boolean <- nil? rest
2764 compare rest-nil?, 0/false
2765 break-if-=
2766 error trace, "'bezier' needs 8 args but got 4"
2767 return
2768 }
2769 var fifth-ah/eax: (addr handle cell) <- get rest, left
2770 var fifth/eax: (addr cell) <- lookup *fifth-ah
2771 {
2772 var fifth-type/eax: (addr int) <- get fifth, type
2773 compare *fifth-type, 1/number
2774 break-if-=
2775 error trace, "fifth arg for 'bezier' is not a number (screen y coordinate of control point)"
2776 return
2777 }
2778 var fifth-value/eax: (addr float) <- get fifth, number-data
2779 var tmp/eax: int <- convert *fifth-value
2780 var y1: int
2781 copy-to y1, tmp
2782
2783 var rest-ah/eax: (addr handle cell) <- get rest, right
2784 var _rest/eax: (addr cell) <- lookup *rest-ah
2785 var rest/esi: (addr cell) <- copy _rest
2786 {
2787 var rest-type/eax: (addr int) <- get rest, type
2788 compare *rest-type, 0/pair
2789 break-if-=
2790 error trace, "'bezier' encountered non-pair"
2791 return
2792 }
2793 {
2794 var rest-nil?/eax: boolean <- nil? rest
2795 compare rest-nil?, 0/false
2796 break-if-=
2797 error trace, "'bezier' needs 8 args but got 3"
2798 return
2799 }
2800 var sixth-ah/eax: (addr handle cell) <- get rest, left
2801 var sixth/eax: (addr cell) <- lookup *sixth-ah
2802 {
2803 var sixth-type/eax: (addr int) <- get sixth, type
2804 compare *sixth-type, 1/number
2805 break-if-=
2806 error trace, "sixth arg for 'bezier' is not a number (screen x coordinate of end point)"
2807 return
2808 }
2809 var sixth-value/eax: (addr float) <- get sixth, number-data
2810 var tmp/eax: int <- convert *sixth-value
2811 var x2: int
2812 copy-to x2, tmp
2813
2814 var rest-ah/eax: (addr handle cell) <- get rest, right
2815 var _rest/eax: (addr cell) <- lookup *rest-ah
2816 rest <- copy _rest
2817 {
2818 var rest-type/eax: (addr int) <- get rest, type
2819 compare *rest-type, 0/pair
2820 break-if-=
2821 error trace, "'bezier' encountered non-pair"
2822 return
2823 }
2824 {
2825 var rest-nil?/eax: boolean <- nil? rest
2826 compare rest-nil?, 0/false
2827 break-if-=
2828 error trace, "'bezier' needs 8 args but got 4"
2829 return
2830 }
2831 var seventh-ah/eax: (addr handle cell) <- get rest, left
2832 var seventh/eax: (addr cell) <- lookup *seventh-ah
2833 {
2834 var seventh-type/eax: (addr int) <- get seventh, type
2835 compare *seventh-type, 1/number
2836 break-if-=
2837 error trace, "seventh arg for 'bezier' is not a number (screen y coordinate of end point)"
2838 return
2839 }
2840 var seventh-value/eax: (addr float) <- get seventh, number-data
2841 var tmp/eax: int <- convert *seventh-value
2842 var y2: int
2843 copy-to y2, tmp
2844
2845 var rest-ah/eax: (addr handle cell) <- get rest, right
2846 var _rest/eax: (addr cell) <- lookup *rest-ah
2847 rest <- copy _rest
2848 {
2849 var rest-type/eax: (addr int) <- get rest, type
2850 compare *rest-type, 0/pair
2851 break-if-=
2852 error trace, "'bezier' encountered non-pair"
2853 return
2854 }
2855 {
2856 var rest-nil?/eax: boolean <- nil? rest
2857 compare rest-nil?, 0/false
2858 break-if-=
2859 error trace, "'bezier' needs 8 args but got 5"
2860 return
2861 }
2862 var eighth-ah/eax: (addr handle cell) <- get rest, left
2863 var eighth/eax: (addr cell) <- lookup *eighth-ah
2864 {
2865 var eighth-type/eax: (addr int) <- get eighth, type
2866 compare *eighth-type, 1/number
2867 break-if-=
2868 error trace, "eighth arg for 'bezier' is not an int (color; 0..0xff)"
2869 return
2870 }
2871 var eighth-value/eax: (addr float) <- get eighth, number-data
2872 var color/eax: int <- convert *eighth-value
2873 draw-monotonic-bezier screen, x0, y0, x1, y1, x2, y2, color
2874
2875 }
2876
2877 fn apply-wait-for-key _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
2878 trace-text trace, "eval", "apply 'key'"
2879 var args-ah/eax: (addr handle cell) <- copy _args-ah
2880 var _args/eax: (addr cell) <- lookup *args-ah
2881 var args/esi: (addr cell) <- copy _args
2882 {
2883 var args-type/eax: (addr int) <- get args, type
2884 compare *args-type, 0/pair
2885 break-if-=
2886 error trace, "args to 'key' are not a list"
2887 return
2888 }
2889 var empty-args?/eax: boolean <- nil? args
2890 compare empty-args?, 0/false
2891 {
2892 break-if-=
2893 error trace, "'key' needs 1 arg but got 0"
2894 return
2895 }
2896
2897 var first-ah/eax: (addr handle cell) <- get args, left
2898 var first/eax: (addr cell) <- lookup *first-ah
2899 {
2900 var first-type/eax: (addr int) <- get first, type
2901 compare *first-type, 6/keyboard
2902 break-if-=
2903 error trace, "first arg for 'key' is not a keyboard"
2904 return
2905 }
2906 var keyboard-ah/eax: (addr handle gap-buffer) <- get first, keyboard-data
2907 var _keyboard/eax: (addr gap-buffer) <- lookup *keyboard-ah
2908 var keyboard/ecx: (addr gap-buffer) <- copy _keyboard
2909 var result/eax: int <- wait-for-key keyboard
2910
2911 new-integer out, result
2912 }
2913
2914 fn wait-for-key keyboard: (addr gap-buffer) -> _/eax: int {
2915
2916 {
2917 compare keyboard, 0/real-keyboard
2918 break-if-!=
2919 var key/eax: byte <- read-key 0/real-keyboard
2920 var result/eax: int <- copy key
2921 return result
2922 }
2923
2924 var g/eax: grapheme <- read-from-gap-buffer keyboard
2925 var result/eax: int <- copy g
2926 return result
2927 }
2928
2929 fn apply-stream _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
2930 trace-text trace, "eval", "apply stream"
2931 allocate-stream out
2932 }
2933
2934 fn apply-write _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
2935 trace-text trace, "eval", "apply 'write'"
2936 var args-ah/eax: (addr handle cell) <- copy _args-ah
2937 var _args/eax: (addr cell) <- lookup *args-ah
2938 var args/esi: (addr cell) <- copy _args
2939 {
2940 var args-type/eax: (addr int) <- get args, type
2941 compare *args-type, 0/pair
2942 break-if-=
2943 error trace, "args to 'write' are not a list"
2944 return
2945 }
2946 var empty-args?/eax: boolean <- nil? args
2947 compare empty-args?, 0/false
2948 {
2949 break-if-=
2950 error trace, "'write' needs 2 args but got 0"
2951 return
2952 }
2953
2954 var first-ah/edx: (addr handle cell) <- get args, left
2955 var first/eax: (addr cell) <- lookup *first-ah
2956 {
2957 var first-type/eax: (addr int) <- get first, type
2958 compare *first-type, 3/stream
2959 break-if-=
2960 error trace, "first arg for 'write' is not a stream"
2961 return
2962 }
2963 var stream-data-ah/eax: (addr handle stream byte) <- get first, text-data
2964 var _stream-data/eax: (addr stream byte) <- lookup *stream-data-ah
2965 var stream-data/ebx: (addr stream byte) <- copy _stream-data
2966
2967 var right-ah/eax: (addr handle cell) <- get args, right
2968 var right/eax: (addr cell) <- lookup *right-ah
2969 {
2970 var right-type/eax: (addr int) <- get right, type
2971 compare *right-type, 0/pair
2972 break-if-=
2973 error trace, "'write' encountered non-pair"
2974 return
2975 }
2976 {
2977 var nil?/eax: boolean <- nil? right
2978 compare nil?, 0/false
2979 break-if-=
2980 error trace, "'write' needs 2 args but got 1"
2981 return
2982 }
2983 var second-ah/eax: (addr handle cell) <- get right, left
2984 var second/eax: (addr cell) <- lookup *second-ah
2985 {
2986 var second-type/eax: (addr int) <- get second, type
2987 compare *second-type, 1/number
2988 break-if-=
2989 error trace, "second arg for 'write' is not a number/grapheme"
2990 return
2991 }
2992 var second-value/eax: (addr float) <- get second, number-data
2993 var x-float/xmm0: float <- copy *second-value
2994 var x/eax: int <- convert x-float
2995 var x-grapheme/eax: grapheme <- copy x
2996 write-grapheme stream-data, x-grapheme
2997
2998 copy-object first-ah, out
2999 }
3000
3001 fn apply-rewind _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
3002 trace-text trace, "eval", "apply 'rewind'"
3003 var args-ah/eax: (addr handle cell) <- copy _args-ah
3004 var _args/eax: (addr cell) <- lookup *args-ah
3005 var args/esi: (addr cell) <- copy _args
3006 {
3007 var args-type/eax: (addr int) <- get args, type
3008 compare *args-type, 0/pair
3009 break-if-=
3010 error trace, "args to 'rewind' are not a list"
3011 return
3012 }
3013 var empty-args?/eax: boolean <- nil? args
3014 compare empty-args?, 0/false
3015 {
3016 break-if-=
3017 error trace, "'rewind' needs 1 arg but got 0"
3018 return
3019 }
3020
3021 var first-ah/edx: (addr handle cell) <- get args, left
3022 var first/eax: (addr cell) <- lookup *first-ah
3023 {
3024 var first-type/eax: (addr int) <- get first, type
3025 compare *first-type, 3/stream
3026 break-if-=
3027 error trace, "first arg for 'rewind' is not a stream"
3028 return
3029 }
3030 var stream-data-ah/eax: (addr handle stream byte) <- get first, text-data
3031 var _stream-data/eax: (addr stream byte) <- lookup *stream-data-ah
3032 var stream-data/ebx: (addr stream byte) <- copy _stream-data
3033 rewind-stream stream-data
3034 copy-object first-ah, out
3035 }
3036
3037 fn apply-read _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
3038 trace-text trace, "eval", "apply 'read'"
3039 var args-ah/eax: (addr handle cell) <- copy _args-ah
3040 var _args/eax: (addr cell) <- lookup *args-ah
3041 var args/esi: (addr cell) <- copy _args
3042 {
3043 var args-type/eax: (addr int) <- get args, type
3044 compare *args-type, 0/pair
3045 break-if-=
3046 error trace, "args to 'read' are not a list"
3047 return
3048 }
3049 var empty-args?/eax: boolean <- nil? args
3050 compare empty-args?, 0/false
3051 {
3052 break-if-=
3053 error trace, "'read' needs 1 arg but got 0"
3054 return
3055 }
3056
3057 var first-ah/edx: (addr handle cell) <- get args, left
3058 var first/eax: (addr cell) <- lookup *first-ah
3059 {
3060 var first-type/eax: (addr int) <- get first, type
3061 compare *first-type, 3/stream
3062 break-if-=
3063 error trace, "first arg for 'read' is not a stream"
3064 return
3065 }
3066 var stream-data-ah/eax: (addr handle stream byte) <- get first, text-data
3067 var _stream-data/eax: (addr stream byte) <- lookup *stream-data-ah
3068 var stream-data/ebx: (addr stream byte) <- copy _stream-data
3069
3070 var result-grapheme/eax: grapheme <- read-grapheme stream-data
3071 var result/eax: int <- copy result-grapheme
3072 new-integer out, result
3073 }
3074
3075 fn apply-lines _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
3076 trace-text trace, "eval", "apply 'lines'"
3077 var args-ah/eax: (addr handle cell) <- copy _args-ah
3078 var _args/eax: (addr cell) <- lookup *args-ah
3079 var args/esi: (addr cell) <- copy _args
3080 {
3081 var args-type/eax: (addr int) <- get args, type
3082 compare *args-type, 0/pair
3083 break-if-=
3084 error trace, "args to 'lines' are not a list"
3085 return
3086 }
3087 var empty-args?/eax: boolean <- nil? args
3088 compare empty-args?, 0/false
3089 {
3090 break-if-=
3091 error trace, "'lines' needs 1 arg but got 0"
3092 return
3093 }
3094
3095 var first-ah/eax: (addr handle cell) <- get args, left
3096 var first/eax: (addr cell) <- lookup *first-ah
3097 {
3098 var first-type/eax: (addr int) <- get first, type
3099 compare *first-type, 5/screen
3100 break-if-=
3101 error trace, "first arg for 'lines' is not a screen"
3102 return
3103 }
3104 var screen-ah/eax: (addr handle screen) <- get first, screen-data
3105 var _screen/eax: (addr screen) <- lookup *screen-ah
3106 var screen/edx: (addr screen) <- copy _screen
3107
3108 var dummy/eax: int <- copy 0
3109 var height/ecx: int <- copy 0
3110 dummy, height <- screen-size screen
3111 var result/xmm0: float <- convert height
3112 new-float out, result
3113 }
3114
3115 fn apply-abort _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
3116 abort "aa"
3117 }
3118
3119 fn apply-columns _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
3120 trace-text trace, "eval", "apply 'columns'"
3121 var args-ah/eax: (addr handle cell) <- copy _args-ah
3122 var _args/eax: (addr cell) <- lookup *args-ah
3123 var args/esi: (addr cell) <- copy _args
3124 {
3125 var args-type/eax: (addr int) <- get args, type
3126 compare *args-type, 0/pair
3127 break-if-=
3128 error trace, "args to 'columns' are not a list"
3129 return
3130 }
3131 var empty-args?/eax: boolean <- nil? args
3132 compare empty-args?, 0/false
3133 {
3134 break-if-=
3135 error trace, "'columns' needs 1 arg but got 0"
3136 return
3137 }
3138
3139 var first-ah/eax: (addr handle cell) <- get args, left
3140 var first/eax: (addr cell) <- lookup *first-ah
3141 {
3142 var first-type/eax: (addr int) <- get first, type
3143 compare *first-type, 5/screen
3144 break-if-=
3145 error trace, "first arg for 'columns' is not a screen"
3146 return
3147 }
3148 var screen-ah/eax: (addr handle screen) <- get first, screen-data
3149 var _screen/eax: (addr screen) <- lookup *screen-ah
3150 var screen/edx: (addr screen) <- copy _screen
3151
3152 var width/eax: int <- copy 0
3153 var dummy/ecx: int <- copy 0
3154 width, dummy <- screen-size screen
3155 var result/xmm0: float <- convert width
3156 new-float out, result
3157 }
3158
3159 fn apply-width _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
3160 trace-text trace, "eval", "apply 'width'"
3161 var args-ah/eax: (addr handle cell) <- copy _args-ah
3162 var _args/eax: (addr cell) <- lookup *args-ah
3163 var args/esi: (addr cell) <- copy _args
3164 {
3165 var args-type/eax: (addr int) <- get args, type
3166 compare *args-type, 0/pair
3167 break-if-=
3168 error trace, "args to 'width' are not a list"
3169 return
3170 }
3171 var empty-args?/eax: boolean <- nil? args
3172 compare empty-args?, 0/false
3173 {
3174 break-if-=
3175 error trace, "'width' needs 1 arg but got 0"
3176 return
3177 }
3178
3179 var first-ah/eax: (addr handle cell) <- get args, left
3180 var first/eax: (addr cell) <- lookup *first-ah
3181 {
3182 var first-type/eax: (addr int) <- get first, type
3183 compare *first-type, 5/screen
3184 break-if-=
3185 error trace, "first arg for 'width' is not a screen"
3186 return
3187 }
3188 var screen-ah/eax: (addr handle screen) <- get first, screen-data
3189 var _screen/eax: (addr screen) <- lookup *screen-ah
3190 var screen/edx: (addr screen) <- copy _screen
3191
3192 var width/eax: int <- copy 0
3193 var dummy/ecx: int <- copy 0
3194 width, dummy <- screen-size screen
3195 width <- shift-left 3/log2-font-width
3196 var result/xmm0: float <- convert width
3197 new-float out, result
3198 }
3199
3200 fn apply-height _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
3201 trace-text trace, "eval", "apply 'height'"
3202 var args-ah/eax: (addr handle cell) <- copy _args-ah
3203 var _args/eax: (addr cell) <- lookup *args-ah
3204 var args/esi: (addr cell) <- copy _args
3205 {
3206 var args-type/eax: (addr int) <- get args, type
3207 compare *args-type, 0/pair
3208 break-if-=
3209 error trace, "args to 'height' are not a list"
3210 return
3211 }
3212 var empty-args?/eax: boolean <- nil? args
3213 compare empty-args?, 0/false
3214 {
3215 break-if-=
3216 error trace, "'height' needs 1 arg but got 0"
3217 return
3218 }
3219
3220 var first-ah/eax: (addr handle cell) <- get args, left
3221 var first/eax: (addr cell) <- lookup *first-ah
3222 {
3223 var first-type/eax: (addr int) <- get first, type
3224 compare *first-type, 5/screen
3225 break-if-=
3226 error trace, "first arg for 'height' is not a screen"
3227 return
3228 }
3229 var screen-ah/eax: (addr handle screen) <- get first, screen-data
3230 var _screen/eax: (addr screen) <- lookup *screen-ah
3231 var screen/edx: (addr screen) <- copy _screen
3232
3233 var dummy/eax: int <- copy 0
3234 var height/ecx: int <- copy 0
3235 dummy, height <- screen-size screen
3236 height <- shift-left 4/log2-font-height
3237 var result/xmm0: float <- convert height
3238 new-float out, result
3239 }
3240
3241 fn apply-new-screen _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
3242 trace-text trace, "eval", "apply 'screen'"
3243 var args-ah/eax: (addr handle cell) <- copy _args-ah
3244 var _args/eax: (addr cell) <- lookup *args-ah
3245 var args/esi: (addr cell) <- copy _args
3246 {
3247 var args-type/eax: (addr int) <- get args, type
3248 compare *args-type, 0/pair
3249 break-if-=
3250 error trace, "args to 'screen' are not a list"
3251 return
3252 }
3253 var empty-args?/eax: boolean <- nil? args
3254 compare empty-args?, 0/false
3255 {
3256 break-if-=
3257 error trace, "'screen' needs 2 args but got 0"
3258 return
3259 }
3260
3261 var first-ah/eax: (addr handle cell) <- get args, left
3262 var first/eax: (addr cell) <- lookup *first-ah
3263 {
3264 var first-type/eax: (addr int) <- get first, type
3265 compare *first-type, 1/number
3266 break-if-=
3267 error trace, "first arg for 'screen' is not a number (screen width in pixels)"
3268 return
3269 }
3270 var first-value-a/ecx: (addr float) <- get first, number-data
3271 var first-value/ecx: int <- convert *first-value-a
3272
3273 var right-ah/eax: (addr handle cell) <- get args, right
3274 var right/eax: (addr cell) <- lookup *right-ah
3275 {
3276 var right-type/eax: (addr int) <- get right, type
3277 compare *right-type, 0/pair
3278 break-if-=
3279 error trace, "'screen' encountered non-pair"
3280 return
3281 }
3282 {
3283 var nil?/eax: boolean <- nil? right
3284 compare nil?, 0/false
3285 break-if-=
3286 error trace, "'screen' needs 2 args but got 1"
3287 return
3288 }
3289 var second-ah/eax: (addr handle cell) <- get right, left
3290 var second/eax: (addr cell) <- lookup *second-ah
3291 {
3292 var second-type/eax: (addr int) <- get second, type
3293 compare *second-type, 1/number
3294 break-if-=
3295 error trace, "second arg for 'screen' is not a number (screen height in pixels)"
3296 return
3297 }
3298 var second-value-a/edx: (addr float) <- get second, number-data
3299 var second-value/edx: int <- convert *second-value-a
3300
3301 new-fake-screen out, first-value, second-value, 1/pixel-graphics
3302 }
3303
3304 fn apply-blit _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
3305 trace-text trace, "eval", "apply 'blit'"
3306 var args-ah/eax: (addr handle cell) <- copy _args-ah
3307 var _args/eax: (addr cell) <- lookup *args-ah
3308 var args/esi: (addr cell) <- copy _args
3309 {
3310 var args-type/eax: (addr int) <- get args, type
3311 compare *args-type, 0/pair
3312 break-if-=
3313 error trace, "args to 'blit' are not a list"
3314 return
3315 }
3316 var empty-args?/eax: boolean <- nil? args
3317 compare empty-args?, 0/false
3318 {
3319 break-if-=
3320 error trace, "'blit' needs 2 args but got 0"
3321 return
3322 }
3323
3324 var first-ah/eax: (addr handle cell) <- get args, left
3325 var first/eax: (addr cell) <- lookup *first-ah
3326 {
3327 var first-type/eax: (addr int) <- get first, type
3328 compare *first-type, 5/screen
3329 break-if-=
3330 error trace, "first arg for 'blit' is not a screen"
3331 return
3332 }
3333 var src-ah/eax: (addr handle screen) <- get first, screen-data
3334 var _src/eax: (addr screen) <- lookup *src-ah
3335 var src/ecx: (addr screen) <- copy _src
3336
3337 var right-ah/eax: (addr handle cell) <- get args, right
3338 var right/eax: (addr cell) <- lookup *right-ah
3339 {
3340 var right-type/eax: (addr int) <- get right, type
3341 compare *right-type, 0/pair
3342 break-if-=
3343 error trace, "'blit' encountered non-pair"
3344 return
3345 }
3346 {
3347 var nil?/eax: boolean <- nil? right
3348 compare nil?, 0/false
3349 break-if-=
3350 error trace, "'blit' needs 2 args but got 1"
3351 return
3352 }
3353 var second-ah/eax: (addr handle cell) <- get right, left
3354 var second/eax: (addr cell) <- lookup *second-ah
3355 {
3356 var second-type/eax: (addr int) <- get second, type
3357 compare *second-type, 5/screen
3358 break-if-=
3359 error trace, "second arg for 'blit' is not a screen"
3360 return
3361 }
3362 var dest-ah/eax: (addr handle screen) <- get second, screen-data
3363 var dest/eax: (addr screen) <- lookup *dest-ah
3364
3365 convert-graphemes-to-pixels src
3366 copy-pixels src, dest
3367 }