https://github.com/akkartik/mu/blob/main/shell/primitives.mu
1 fn initialize-primitives _self: (addr global-table) {
2 var self/esi: (addr global-table) <- copy _self
3
4 append-primitive self, "+"
5 append-primitive self, "-"
6 append-primitive self, "*"
7 append-primitive self, "/"
8 append-primitive self, "sqrt"
9 append-primitive self, "abs"
10 append-primitive self, "sgn"
11 append-primitive self, "<"
12 append-primitive self, ">"
13 append-primitive self, "<="
14 append-primitive self, ">="
15
16 append-primitive self, "="
17 append-primitive self, "no"
18 append-primitive self, "not"
19 append-primitive self, "dbg"
20
21 append-primitive self, "car"
22 append-primitive self, "cdr"
23 append-primitive self, "cons"
24
25 append-primitive self, "print"
26 append-primitive self, "clear"
27 append-primitive self, "lines"
28 append-primitive self, "columns"
29 append-primitive self, "up"
30 append-primitive self, "down"
31 append-primitive self, "left"
32 append-primitive self, "right"
33 append-primitive self, "cr"
34 append-primitive self, "pixel"
35 append-primitive self, "width"
36 append-primitive self, "height"
37
38 append-primitive self, "key"
39
40 append-primitive self, "stream"
41 append-primitive self, "write"
42
43 append-primitive self, "abort"
44
45 }
46
47 fn render-primitives screen: (addr screen), xmin: int, xmax: int, ymax: int {
48 var y/ecx: int <- copy ymax
49 y <- subtract 0x10
50 clear-rect screen, xmin, y, xmax, ymax, 0xdc/bg=green-bg
51 y <- increment
52 var tmpx/eax: int <- copy xmin
53 tmpx <- draw-text-rightward screen, "cursor graphics", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
54 y <- increment
55 var tmpx/eax: int <- copy xmin
56 tmpx <- draw-text-rightward screen, " print", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
57 tmpx <- draw-text-rightward screen, ": screen a -> a", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
58 y <- increment
59 var tmpx/eax: int <- copy xmin
60 tmpx <- draw-text-rightward screen, " lines columns", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
61 tmpx <- draw-text-rightward screen, ": screen -> number", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
62 y <- increment
63 var tmpx/eax: int <- copy xmin
64 tmpx <- draw-text-rightward screen, " up down left right", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
65 tmpx <- draw-text-rightward screen, ": screen", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
66 y <- increment
67 var tmpx/eax: int <- copy xmin
68 tmpx <- draw-text-rightward screen, " cr", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
69 tmpx <- draw-text-rightward screen, ": screen ", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
70 tmpx <- draw-text-rightward screen, "# move cursor down and to left margin", tmpx, xmax, y, 0x38/fg=trace, 0xdc/bg=green-bg
71 y <- increment
72 var tmpx/eax: int <- copy xmin
73 tmpx <- draw-text-rightward screen, "pixel graphics", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
74 y <- increment
75 var tmpx/eax: int <- copy xmin
76 tmpx <- draw-text-rightward screen, " width height", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
77 tmpx <- draw-text-rightward screen, ": screen -> number", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
78 y <- increment
79 var tmpx/eax: int <- copy xmin
80 tmpx <- draw-text-rightward screen, " pixel", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
81 tmpx <- draw-text-rightward screen, ": screen x y color", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
82 y <- increment
83 var tmpx/eax: int <- copy xmin
84 tmpx <- draw-text-rightward screen, "screen/keyboard", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
85 y <- increment
86 var tmpx/eax: int <- copy xmin
87 tmpx <- draw-text-rightward screen, " clear", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
88 tmpx <- draw-text-rightward screen, ": screen", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
89 y <- increment
90 var tmpx/eax: int <- copy xmin
91 tmpx <- draw-text-rightward screen, " key", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
92 tmpx <- draw-text-rightward screen, ": () -> grapheme?", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
93 y <- increment
94 var tmpx/eax: int <- copy xmin
95 tmpx <- draw-text-rightward screen, "streams", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
96 y <- increment
97 var tmpx/eax: int <- copy xmin
98 tmpx <- draw-text-rightward screen, " stream", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
99 tmpx <- draw-text-rightward screen, ": () -> stream ", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
100 y <- increment
101 var tmpx/eax: int <- copy xmin
102 tmpx <- draw-text-rightward screen, " write", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
103 tmpx <- draw-text-rightward screen, ": stream grapheme -> stream", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
104 y <- increment
105 var tmpx/eax: int <- copy xmin
106 tmpx <- draw-text-rightward screen, "fn def set if while = no(t) car cdr cons ", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
107 tmpx <- draw-text-rightward screen, "num: ", tmpx, xmax, y, 7/fg=grey, 0xdc/bg=green-bg
108 tmpx <- draw-text-rightward screen, "+ - * / sqrt abs sgn < > <= >= ", tmpx, xmax, y, 0x2a/fg=orange, 0xdc/bg=green-bg
109 }
110
111 fn primitive-global? _x: (addr global) -> _/eax: boolean {
112 var x/eax: (addr global) <- copy _x
113 var value-ah/eax: (addr handle cell) <- get x, value
114 var value/eax: (addr cell) <- lookup *value-ah
115 compare value, 0/null
116 {
117 break-if-!=
118 return 0/false
119 }
120 var value-type/eax: (addr int) <- get value, type
121 compare *value-type, 4/primitive
122 {
123 break-if-=
124 return 0/false
125 }
126 return 1/true
127 }
128
129 fn append-primitive _self: (addr global-table), name: (addr array byte) {
130 var self/esi: (addr global-table) <- copy _self
131 compare self, 0
132 {
133 break-if-!=
134 abort "append primitive"
135 return
136 }
137 var final-index-addr/ecx: (addr int) <- get self, final-index
138 increment *final-index-addr
139 var curr-index/ecx: int <- copy *final-index-addr
140 var data-ah/eax: (addr handle array global) <- get self, data
141 var data/eax: (addr array global) <- lookup *data-ah
142 var curr-offset/esi: (offset global) <- compute-offset data, curr-index
143 var curr/esi: (addr global) <- index data, curr-offset
144 var curr-name-ah/eax: (addr handle array byte) <- get curr, name
145 copy-array-object name, curr-name-ah
146 var curr-value-ah/eax: (addr handle cell) <- get curr, value
147 new-primitive-function curr-value-ah, curr-index
148 }
149
150
151 fn apply-primitive _f: (addr cell), args-ah: (addr handle cell), out: (addr handle cell), _globals: (addr global-table), trace: (addr trace) {
152 var f/esi: (addr cell) <- copy _f
153 var f-index-a/ecx: (addr int) <- get f, index-data
154 var f-index/ecx: int <- copy *f-index-a
155 var globals/eax: (addr global-table) <- copy _globals
156 compare globals, 0
157 {
158 break-if-!=
159 abort "apply primitive"
160 return
161 }
162 var global-data-ah/eax: (addr handle array global) <- get globals, data
163 var global-data/eax: (addr array global) <- lookup *global-data-ah
164 var f-offset/ecx: (offset global) <- compute-offset global-data, f-index
165 var f-value/ecx: (addr global) <- index global-data, f-offset
166 var f-name-ah/ecx: (addr handle array byte) <- get f-value, name
167 var f-name/eax: (addr array byte) <- lookup *f-name-ah
168 {
169 var add?/eax: boolean <- string-equal? f-name, "+"
170 compare add?, 0/false
171 break-if-=
172 apply-add args-ah, out, trace
173 return
174 }
175 {
176 var subtract?/eax: boolean <- string-equal? f-name, "-"
177 compare subtract?, 0/false
178 break-if-=
179 apply-subtract args-ah, out, trace
180 return
181 }
182 {
183 var multiply?/eax: boolean <- string-equal? f-name, "*"
184 compare multiply?, 0/false
185 break-if-=
186 apply-multiply args-ah, out, trace
187 return
188 }
189 {
190 var divide?/eax: boolean <- string-equal? f-name, "/"
191 compare divide?, 0/false
192 break-if-=
193 apply-divide args-ah, out, trace
194 return
195 }
196 {
197 var square-root?/eax: boolean <- string-equal? f-name, "sqrt"
198 compare square-root?, 0/false
199 break-if-=
200 apply-square-root args-ah, out, trace
201 return
202 }
203 {
204 var abs?/eax: boolean <- string-equal? f-name, "abs"
205 compare abs?, 0/false
206 break-if-=
207 apply-abs args-ah, out, trace
208 return
209 }
210 {
211 var sgn?/eax: boolean <- string-equal? f-name, "sgn"
212 compare sgn?, 0/false
213 break-if-=
214 apply-sgn args-ah, out, trace
215 return
216 }
217 {
218 var car?/eax: boolean <- string-equal? f-name, "car"
219 compare car?, 0/false
220 break-if-=
221 apply-car args-ah, out, trace
222 return
223 }
224 {
225 var cdr?/eax: boolean <- string-equal? f-name, "cdr"
226 compare cdr?, 0/false
227 break-if-=
228 apply-cdr args-ah, out, trace
229 return
230 }
231 {
232 var cons?/eax: boolean <- string-equal? f-name, "cons"
233 compare cons?, 0/false
234 break-if-=
235 apply-cons args-ah, out, trace
236 return
237 }
238 {
239 var structurally-equal?/eax: boolean <- string-equal? f-name, "="
240 compare structurally-equal?, 0/false
241 break-if-=
242 apply-structurally-equal args-ah, out, trace
243 return
244 }
245 {
246 var not?/eax: boolean <- string-equal? f-name, "no"
247 compare not?, 0/false
248 break-if-=
249 apply-not args-ah, out, trace
250 return
251 }
252 {
253 var not?/eax: boolean <- string-equal? f-name, "not"
254 compare not?, 0/false
255 break-if-=
256 apply-not args-ah, out, trace
257 return
258 }
259 {
260 var debug?/eax: boolean <- string-equal? f-name, "dbg"
261 compare debug?, 0/false
262 break-if-=
263 apply-debug args-ah, out, trace
264 return
265 }
266 {
267 var lesser?/eax: boolean <- string-equal? f-name, "<"
268 compare lesser?, 0/false
269 break-if-=
270 apply-< args-ah, out, trace
271 return
272 }
273 {
274 var greater?/eax: boolean <- string-equal? f-name, ">"
275 compare greater?, 0/false
276 break-if-=
277 apply-> args-ah, out, trace
278 return
279 }
280 {
281 var lesser-or-equal?/eax: boolean <- string-equal? f-name, "<="
282 compare lesser-or-equal?, 0/false
283 break-if-=
284 apply-<= args-ah, out, trace
285 return
286 }
287 {
288 var greater-or-equal?/eax: boolean <- string-equal? f-name, ">="
289 compare greater-or-equal?, 0/false
290 break-if-=
291 apply->= args-ah, out, trace
292 return
293 }
294 {
295 var print?/eax: boolean <- string-equal? f-name, "print"
296 compare print?, 0/false
297 break-if-=
298 apply-print args-ah, out, trace
299 return
300 }
301 {
302 var clear?/eax: boolean <- string-equal? f-name, "clear"
303 compare clear?, 0/false
304 break-if-=
305 apply-clear args-ah, out, trace
306 return
307 }
308 {
309 var lines?/eax: boolean <- string-equal? f-name, "lines"
310 compare lines?, 0/false
311 break-if-=
312 apply-lines args-ah, out, trace
313 return
314 }
315 {
316 var columns?/eax: boolean <- string-equal? f-name, "columns"
317 compare columns?, 0/false
318 break-if-=
319 apply-columns args-ah, out, trace
320 return
321 }
322 {
323 var up?/eax: boolean <- string-equal? f-name, "up"
324 compare up?, 0/false
325 break-if-=
326 apply-up args-ah, out, trace
327 return
328 }
329 {
330 var down?/eax: boolean <- string-equal? f-name, "down"
331 compare down?, 0/false
332 break-if-=
333 apply-down args-ah, out, trace
334 return
335 }
336 {
337 var left?/eax: boolean <- string-equal? f-name, "left"
338 compare left?, 0/false
339 break-if-=
340 apply-left args-ah, out, trace
341 return
342 }
343 {
344 var right?/eax: boolean <- string-equal? f-name, "right"
345 compare right?, 0/false
346 break-if-=
347 apply-right args-ah, out, trace
348 return
349 }
350 {
351 var cr?/eax: boolean <- string-equal? f-name, "cr"
352 compare cr?, 0/false
353 break-if-=
354 apply-cr args-ah, out, trace
355 return
356 }
357 {
358 var pixel?/eax: boolean <- string-equal? f-name, "pixel"
359 compare pixel?, 0/false
360 break-if-=
361 apply-pixel args-ah, out, trace
362 return
363 }
364 {
365 var width?/eax: boolean <- string-equal? f-name, "width"
366 compare width?, 0/false
367 break-if-=
368 apply-width args-ah, out, trace
369 return
370 }
371 {
372 var height?/eax: boolean <- string-equal? f-name, "height"
373 compare height?, 0/false
374 break-if-=
375 apply-height args-ah, out, trace
376 return
377 }
378 {
379 var wait-for-key?/eax: boolean <- string-equal? f-name, "key"
380 compare wait-for-key?, 0/false
381 break-if-=
382 apply-wait-for-key args-ah, out, trace
383 return
384 }
385 {
386 var stream?/eax: boolean <- string-equal? f-name, "stream"
387 compare stream?, 0/false
388 break-if-=
389 apply-stream args-ah, out, trace
390 return
391 }
392 {
393 var write?/eax: boolean <- string-equal? f-name, "write"
394 compare write?, 0/false
395 break-if-=
396 apply-write args-ah, out, trace
397 return
398 }
399 {
400 var abort?/eax: boolean <- string-equal? f-name, "abort"
401 compare abort?, 0/false
402 break-if-=
403 apply-abort args-ah, out, trace
404 return
405 }
406 abort "unknown primitive function"
407 }
408
409 fn apply-add _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
410 trace-text trace, "eval", "apply +"
411 var args-ah/eax: (addr handle cell) <- copy _args-ah
412 var _args/eax: (addr cell) <- lookup *args-ah
413 var args/esi: (addr cell) <- copy _args
414
415 var empty-args?/eax: boolean <- nil? args
416 compare empty-args?, 0/false
417 {
418 break-if-=
419 error trace, "+ needs 2 args but got 0"
420 return
421 }
422
423 var first-ah/eax: (addr handle cell) <- get args, left
424 var first/eax: (addr cell) <- lookup *first-ah
425 var first-type/ecx: (addr int) <- get first, type
426 compare *first-type, 1/number
427 {
428 break-if-=
429 error trace, "first arg for + is not a number"
430 return
431 }
432 var first-value/ecx: (addr float) <- get first, number-data
433
434 var right-ah/eax: (addr handle cell) <- get args, right
435
436
437 var right/eax: (addr cell) <- lookup *right-ah
438
439 var second-ah/eax: (addr handle cell) <- get right, left
440 var second/eax: (addr cell) <- lookup *second-ah
441 var second-type/edx: (addr int) <- get second, type
442 compare *second-type, 1/number
443 {
444 break-if-=
445 error trace, "second arg for + is not a number"
446 return
447 }
448 var second-value/edx: (addr float) <- get second, number-data
449
450 var result/xmm0: float <- copy *first-value
451 result <- add *second-value
452 new-float out, result
453 }
454
455 fn apply-subtract _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
456 trace-text trace, "eval", "apply -"
457 var args-ah/eax: (addr handle cell) <- copy _args-ah
458 var _args/eax: (addr cell) <- lookup *args-ah
459 var args/esi: (addr cell) <- copy _args
460
461 var empty-args?/eax: boolean <- nil? args
462 compare empty-args?, 0/false
463 {
464 break-if-=
465 error trace, "- needs 2 args but got 0"
466 return
467 }
468
469 var first-ah/eax: (addr handle cell) <- get args, left
470 var first/eax: (addr cell) <- lookup *first-ah
471 var first-type/ecx: (addr int) <- get first, type
472 compare *first-type, 1/number
473 {
474 break-if-=
475 error trace, "first arg for - is not a number"
476 return
477 }
478 var first-value/ecx: (addr float) <- get first, number-data
479
480 var right-ah/eax: (addr handle cell) <- get args, right
481 var right/eax: (addr cell) <- lookup *right-ah
482
483 var second-ah/eax: (addr handle cell) <- get right, left
484 var second/eax: (addr cell) <- lookup *second-ah
485 var second-type/edx: (addr int) <- get second, type
486 compare *second-type, 1/number
487 {
488 break-if-=
489 error trace, "second arg for - is not a number"
490 return
491 }
492 var second-value/edx: (addr float) <- get second, number-data
493
494 var result/xmm0: float <- copy *first-value
495 result <- subtract *second-value
496 new-float out, result
497 }
498
499 fn apply-multiply _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
500 trace-text trace, "eval", "apply *"
501 var args-ah/eax: (addr handle cell) <- copy _args-ah
502 var _args/eax: (addr cell) <- lookup *args-ah
503 var args/esi: (addr cell) <- copy _args
504
505 var empty-args?/eax: boolean <- nil? args
506 compare empty-args?, 0/false
507 {
508 break-if-=
509 error trace, "* needs 2 args but got 0"
510 return
511 }
512
513 var first-ah/eax: (addr handle cell) <- get args, left
514 var first/eax: (addr cell) <- lookup *first-ah
515 var first-type/ecx: (addr int) <- get first, type
516 compare *first-type, 1/number
517 {
518 break-if-=
519 error trace, "first arg for * is not a number"
520 return
521 }
522 var first-value/ecx: (addr float) <- get first, number-data
523
524 var right-ah/eax: (addr handle cell) <- get args, right
525 var right/eax: (addr cell) <- lookup *right-ah
526
527 var second-ah/eax: (addr handle cell) <- get right, left
528 var second/eax: (addr cell) <- lookup *second-ah
529 var second-type/edx: (addr int) <- get second, type
530 compare *second-type, 1/number
531 {
532 break-if-=
533 error trace, "second arg for * is not a number"
534 return
535 }
536 var second-value/edx: (addr float) <- get second, number-data
537
538 var result/xmm0: float <- copy *first-value
539 result <- multiply *second-value
540 new-float out, result
541 }
542
543 fn apply-divide _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
544 trace-text trace, "eval", "apply /"
545 var args-ah/eax: (addr handle cell) <- copy _args-ah
546 var _args/eax: (addr cell) <- lookup *args-ah
547 var args/esi: (addr cell) <- copy _args
548
549 var empty-args?/eax: boolean <- nil? args
550 compare empty-args?, 0/false
551 {
552 break-if-=
553 error trace, "/ needs 2 args but got 0"
554 return
555 }
556
557 var first-ah/eax: (addr handle cell) <- get args, left
558 var first/eax: (addr cell) <- lookup *first-ah
559 var first-type/ecx: (addr int) <- get first, type
560 compare *first-type, 1/number
561 {
562 break-if-=
563 error trace, "first arg for / is not a number"
564 return
565 }
566 var first-value/ecx: (addr float) <- get first, number-data
567
568 var right-ah/eax: (addr handle cell) <- get args, right
569 var right/eax: (addr cell) <- lookup *right-ah
570
571 var second-ah/eax: (addr handle cell) <- get right, left
572 var second/eax: (addr cell) <- lookup *second-ah
573 var second-type/edx: (addr int) <- get second, type
574 compare *second-type, 1/number
575 {
576 break-if-=
577 error trace, "second arg for / is not a number"
578 return
579 }
580 var second-value/edx: (addr float) <- get second, number-data
581
582 var result/xmm0: float <- copy *first-value
583 result <- divide *second-value
584 new-float out, result
585 }
586
587 fn apply-square-root _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
588 trace-text trace, "eval", "apply sqrt"
589 var args-ah/eax: (addr handle cell) <- copy _args-ah
590 var _args/eax: (addr cell) <- lookup *args-ah
591 var args/esi: (addr cell) <- copy _args
592
593 var empty-args?/eax: boolean <- nil? args
594 compare empty-args?, 0/false
595 {
596 break-if-=
597 error trace, "sqrt needs 1 arg but got 0"
598 return
599 }
600
601 var first-ah/eax: (addr handle cell) <- get args, left
602 var first/eax: (addr cell) <- lookup *first-ah
603 var first-type/ecx: (addr int) <- get first, type
604 compare *first-type, 1/number
605 {
606 break-if-=
607 error trace, "arg for sqrt is not a number"
608 return
609 }
610 var first-value/ecx: (addr float) <- get first, number-data
611
612 var result/xmm0: float <- square-root *first-value
613 new-float out, result
614 }
615
616 fn apply-abs _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
617 trace-text trace, "eval", "apply abs"
618 var args-ah/eax: (addr handle cell) <- copy _args-ah
619 var _args/eax: (addr cell) <- lookup *args-ah
620 var args/esi: (addr cell) <- copy _args
621
622 var empty-args?/eax: boolean <- nil? args
623 compare empty-args?, 0/false
624 {
625 break-if-=
626 error trace, "abs needs 1 arg but got 0"
627 return
628 }
629
630 var first-ah/eax: (addr handle cell) <- get args, left
631 var first/eax: (addr cell) <- lookup *first-ah
632 var first-type/ecx: (addr int) <- get first, type
633 compare *first-type, 1/number
634 {
635 break-if-=
636 error trace, "arg for abs is not a number"
637 return
638 }
639 var first-value/ecx: (addr float) <- get first, number-data
640
641 var result/xmm0: float <- copy *first-value
642 var zero: float
643 compare result, zero
644 {
645 break-if-float>=
646 var neg1/eax: int <- copy -1
647 var neg1-f/xmm1: float <- convert neg1
648 result <- multiply neg1-f
649 }
650 new-float out, result
651 }
652
653 fn apply-sgn _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
654 trace-text trace, "eval", "apply sgn"
655 var args-ah/eax: (addr handle cell) <- copy _args-ah
656 var _args/eax: (addr cell) <- lookup *args-ah
657 var args/esi: (addr cell) <- copy _args
658
659 var empty-args?/eax: boolean <- nil? args
660 compare empty-args?, 0/false
661 {
662 break-if-=
663 error trace, "sgn needs 1 arg but got 0"
664 return
665 }
666
667 var first-ah/eax: (addr handle cell) <- get args, left
668 var first/eax: (addr cell) <- lookup *first-ah
669 var first-type/ecx: (addr int) <- get first, type
670 compare *first-type, 1/number
671 {
672 break-if-=
673 error trace, "arg for sgn is not a number"
674 return
675 }
676 var first-value/ecx: (addr float) <- get first, number-data
677
678 var result/xmm0: float <- copy *first-value
679 var zero: float
680 $apply-sgn:core: {
681 compare result, zero
682 break-if-=
683 {
684 break-if-float>
685 var neg1/eax: int <- copy -1
686 result <- convert neg1
687 break $apply-sgn:core
688 }
689 {
690 break-if-float<
691 var one/eax: int <- copy 1
692 result <- convert one
693 break $apply-sgn:core
694 }
695 }
696 new-float out, result
697 }
698
699 fn apply-car _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
700 trace-text trace, "eval", "apply car"
701 var args-ah/eax: (addr handle cell) <- copy _args-ah
702 var _args/eax: (addr cell) <- lookup *args-ah
703 var args/esi: (addr cell) <- copy _args
704
705 var empty-args?/eax: boolean <- nil? args
706 compare empty-args?, 0/false
707 {
708 break-if-=
709 error trace, "car needs 1 arg but got 0"
710 return
711 }
712
713 var first-ah/eax: (addr handle cell) <- get args, left
714 var first/eax: (addr cell) <- lookup *first-ah
715 var first-type/ecx: (addr int) <- get first, type
716 compare *first-type, 0/pair
717 {
718 break-if-=
719 error trace, "arg for car is not a pair"
720 return
721 }
722
723 var result/eax: (addr handle cell) <- get first, left
724 copy-object result, out
725 }
726
727 fn apply-cdr _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
728 trace-text trace, "eval", "apply cdr"
729 var args-ah/eax: (addr handle cell) <- copy _args-ah
730 var _args/eax: (addr cell) <- lookup *args-ah
731 var args/esi: (addr cell) <- copy _args
732
733 var empty-args?/eax: boolean <- nil? args
734 compare empty-args?, 0/false
735 {
736 break-if-=
737 error trace, "cdr needs 1 arg but got 0"
738 return
739 }
740
741 var first-ah/eax: (addr handle cell) <- get args, left
742 var first/eax: (addr cell) <- lookup *first-ah
743 var first-type/ecx: (addr int) <- get first, type
744 compare *first-type, 0/pair
745 {
746 break-if-=
747 error trace, "arg for cdr is not a pair"
748 return
749 }
750
751 var result/eax: (addr handle cell) <- get first, right
752 copy-object result, out
753 }
754
755 fn apply-cons _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
756 trace-text trace, "eval", "apply cons"
757 var args-ah/eax: (addr handle cell) <- copy _args-ah
758 var _args/eax: (addr cell) <- lookup *args-ah
759 var args/esi: (addr cell) <- copy _args
760
761 var empty-args?/eax: boolean <- nil? args
762 compare empty-args?, 0/false
763 {
764 break-if-=
765 error trace, "cons needs 2 args but got 0"
766 return
767 }
768
769 var first-ah/ecx: (addr handle cell) <- get args, left
770
771 var right-ah/eax: (addr handle cell) <- get args, right
772 var right/eax: (addr cell) <- lookup *right-ah
773
774 var second-ah/eax: (addr handle cell) <- get right, left
775
776 new-pair out, *first-ah, *second-ah
777 }
778
779 fn apply-structurally-equal _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
780 trace-text trace, "eval", "apply '='"
781 var args-ah/eax: (addr handle cell) <- copy _args-ah
782 var _args/eax: (addr cell) <- lookup *args-ah
783 var args/esi: (addr cell) <- copy _args
784
785 var empty-args?/eax: boolean <- nil? args
786 compare empty-args?, 0/false
787 {
788 break-if-=
789 error trace, "'=' needs 2 args but got 0"
790 return
791 }
792
793 var first-ah/ecx: (addr handle cell) <- get args, left
794
795 var right-ah/eax: (addr handle cell) <- get args, right
796 var right/eax: (addr cell) <- lookup *right-ah
797
798 var second-ah/edx: (addr handle cell) <- get right, left
799
800 var _first/eax: (addr cell) <- lookup *first-ah
801 var first/ecx: (addr cell) <- copy _first
802 var second/eax: (addr cell) <- lookup *second-ah
803 var match?/eax: boolean <- cell-isomorphic? first, second, trace
804 compare match?, 0/false
805 {
806 break-if-!=
807 nil out
808 return
809 }
810 new-integer out, 1/true
811 }
812
813 fn apply-not _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
814 trace-text trace, "eval", "apply not"
815 var args-ah/eax: (addr handle cell) <- copy _args-ah
816 var _args/eax: (addr cell) <- lookup *args-ah
817 var args/esi: (addr cell) <- copy _args
818
819 var empty-args?/eax: boolean <- nil? args
820 compare empty-args?, 0/false
821 {
822 break-if-=
823 error trace, "not needs 1 arg but got 0"
824 return
825 }
826
827 var first-ah/eax: (addr handle cell) <- get args, left
828 var first/eax: (addr cell) <- lookup *first-ah
829
830 var nil?/eax: boolean <- nil? first
831 compare nil?, 0/false
832 {
833 break-if-!=
834 nil out
835 return
836 }
837 new-integer out, 1
838 }
839
840 fn apply-debug _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
841 trace-text trace, "eval", "apply debug"
842 var args-ah/eax: (addr handle cell) <- copy _args-ah
843 var _args/eax: (addr cell) <- lookup *args-ah
844 var args/esi: (addr cell) <- copy _args
845
846 var empty-args?/eax: boolean <- nil? args
847 compare empty-args?, 0/false
848 {
849 break-if-=
850 error trace, "not needs 1 arg but got 0"
851 return
852 }
853
854 var first-ah/eax: (addr handle cell) <- get args, left
855 dump-cell-from-cursor-over-full-screen first-ah
856 {
857 var foo/eax: byte <- read-key 0/keyboard
858 compare foo, 0
859 loop-if-=
860 }
861
862 }
863
864 fn apply-< _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
865 trace-text trace, "eval", "apply '<'"
866 var args-ah/eax: (addr handle cell) <- copy _args-ah
867 var _args/eax: (addr cell) <- lookup *args-ah
868 var args/esi: (addr cell) <- copy _args
869
870 var empty-args?/eax: boolean <- nil? args
871 compare empty-args?, 0/false
872 {
873 break-if-=
874 error trace, "'<' needs 2 args but got 0"
875 return
876 }
877
878 var first-ah/ecx: (addr handle cell) <- get args, left
879
880 var right-ah/eax: (addr handle cell) <- get args, right
881 var right/eax: (addr cell) <- lookup *right-ah
882
883 var second-ah/edx: (addr handle cell) <- get right, left
884
885 var _first/eax: (addr cell) <- lookup *first-ah
886 var first/ecx: (addr cell) <- copy _first
887 var first-type/eax: (addr int) <- get first, type
888 compare *first-type, 1/number
889 {
890 break-if-=
891 error trace, "first arg for '<' is not a number"
892 return
893 }
894 var first-value/ecx: (addr float) <- get first, number-data
895 var first-float/xmm0: float <- copy *first-value
896 var second/eax: (addr cell) <- lookup *second-ah
897 var second-type/edx: (addr int) <- get second, type
898 compare *second-type, 1/number
899 {
900 break-if-=
901 error trace, "first arg for '<' is not a number"
902 return
903 }
904 var second-value/eax: (addr float) <- get second, number-data
905 compare first-float, *second-value
906 {
907 break-if-float<
908 nil out
909 return
910 }
911 new-integer out, 1/true
912 }
913
914 fn apply-> _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
915 trace-text trace, "eval", "apply '>'"
916 var args-ah/eax: (addr handle cell) <- copy _args-ah
917 var _args/eax: (addr cell) <- lookup *args-ah
918 var args/esi: (addr cell) <- copy _args
919
920 var empty-args?/eax: boolean <- nil? args
921 compare empty-args?, 0/false
922 {
923 break-if-=
924 error trace, "'>' needs 2 args but got 0"
925 return
926 }
927
928 var first-ah/ecx: (addr handle cell) <- get args, left
929
930 var right-ah/eax: (addr handle cell) <- get args, right
931 var right/eax: (addr cell) <- lookup *right-ah
932
933 var second-ah/edx: (addr handle cell) <- get right, left
934
935 var _first/eax: (addr cell) <- lookup *first-ah
936 var first/ecx: (addr cell) <- copy _first
937 var first-type/eax: (addr int) <- get first, type
938 compare *first-type, 1/number
939 {
940 break-if-=
941 error trace, "first arg for '>' is not a number"
942 return
943 }
944 var first-value/ecx: (addr float) <- get first, number-data
945 var first-float/xmm0: float <- copy *first-value
946 var second/eax: (addr cell) <- lookup *second-ah
947 var second-type/edx: (addr int) <- get second, type
948 compare *second-type, 1/number
949 {
950 break-if-=
951 error trace, "first arg for '>' is not a number"
952 return
953 }
954 var second-value/eax: (addr float) <- get second, number-data
955 compare first-float, *second-value
956 {
957 break-if-float>
958 nil out
959 return
960 }
961 new-integer out, 1/true
962 }
963
964 fn apply-<= _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
965 trace-text trace, "eval", "apply '<='"
966 var args-ah/eax: (addr handle cell) <- copy _args-ah
967 var _args/eax: (addr cell) <- lookup *args-ah
968 var args/esi: (addr cell) <- copy _args
969
970 var empty-args?/eax: boolean <- nil? args
971 compare empty-args?, 0/false
972 {
973 break-if-=
974 error trace, "'<=' needs 2 args but got 0"
975 return
976 }
977
978 var first-ah/ecx: (addr handle cell) <- get args, left
979
980 var right-ah/eax: (addr handle cell) <- get args, right
981 var right/eax: (addr cell) <- lookup *right-ah
982
983 var second-ah/edx: (addr handle cell) <- get right, left
984
985 var _first/eax: (addr cell) <- lookup *first-ah
986 var first/ecx: (addr cell) <- copy _first
987 var first-type/eax: (addr int) <- get first, type
988 compare *first-type, 1/number
989 {
990 break-if-=
991 error trace, "first arg for '<=' is not a number"
992 return
993 }
994 var first-value/ecx: (addr float) <- get first, number-data
995 var first-float/xmm0: float <- copy *first-value
996 var second/eax: (addr cell) <- lookup *second-ah
997 var second-type/edx: (addr int) <- get second, type
998 compare *second-type, 1/number
999 {
1000 break-if-=
1001 error trace, "first arg for '<=' is not a number"
1002 return
1003 }
1004 var second-value/eax: (addr float) <- get second, number-data
1005 compare first-float, *second-value
1006 {
1007 break-if-float<=
1008 nil out
1009 return
1010 }
1011 new-integer out, 1/true
1012 }
1013
1014 fn apply->= _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1015 trace-text trace, "eval", "apply '>='"
1016 var args-ah/eax: (addr handle cell) <- copy _args-ah
1017 var _args/eax: (addr cell) <- lookup *args-ah
1018 var args/esi: (addr cell) <- copy _args
1019
1020 var empty-args?/eax: boolean <- nil? args
1021 compare empty-args?, 0/false
1022 {
1023 break-if-=
1024 error trace, "'>=' needs 2 args but got 0"
1025 return
1026 }
1027
1028 var first-ah/ecx: (addr handle cell) <- get args, left
1029
1030 var right-ah/eax: (addr handle cell) <- get args, right
1031 var right/eax: (addr cell) <- lookup *right-ah
1032
1033 var second-ah/edx: (addr handle cell) <- get right, left
1034
1035 var _first/eax: (addr cell) <- lookup *first-ah
1036 var first/ecx: (addr cell) <- copy _first
1037 var first-type/eax: (addr int) <- get first, type
1038 compare *first-type, 1/number
1039 {
1040 break-if-=
1041 error trace, "first arg for '>=' is not a number"
1042 return
1043 }
1044 var first-value/ecx: (addr float) <- get first, number-data
1045 var first-float/xmm0: float <- copy *first-value
1046 var second/eax: (addr cell) <- lookup *second-ah
1047 var second-type/edx: (addr int) <- get second, type
1048 compare *second-type, 1/number
1049 {
1050 break-if-=
1051 error trace, "first arg for '>=' is not a number"
1052 return
1053 }
1054 var second-value/eax: (addr float) <- get second, number-data
1055 compare first-float, *second-value
1056 {
1057 break-if-float>=
1058 nil out
1059 return
1060 }
1061 new-integer out, 1/true
1062 }
1063
1064 fn apply-print _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1065 trace-text trace, "eval", "apply print"
1066 var args-ah/eax: (addr handle cell) <- copy _args-ah
1067 var _args/eax: (addr cell) <- lookup *args-ah
1068 var args/esi: (addr cell) <- copy _args
1069
1070 var empty-args?/eax: boolean <- nil? args
1071 compare empty-args?, 0/false
1072 {
1073 break-if-=
1074 error trace, "print needs 2 args but got 0"
1075 return
1076 }
1077
1078 var first-ah/eax: (addr handle cell) <- get args, left
1079 var first/eax: (addr cell) <- lookup *first-ah
1080 var first-type/ecx: (addr int) <- get first, type
1081 compare *first-type, 5/screen
1082 {
1083 break-if-=
1084 error trace, "first arg for 'print' is not a screen"
1085 return
1086 }
1087 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1088 var _screen/eax: (addr screen) <- lookup *screen-ah
1089 var screen/ecx: (addr screen) <- copy _screen
1090
1091 var right-ah/eax: (addr handle cell) <- get args, right
1092 var right/eax: (addr cell) <- lookup *right-ah
1093
1094 var second-ah/eax: (addr handle cell) <- get right, left
1095 var stream-storage: (stream byte 0x100)
1096 var stream/edi: (addr stream byte) <- address stream-storage
1097 print-cell second-ah, stream, trace
1098 draw-stream-wrapping-right-then-down-from-cursor-over-full-screen screen, stream, 7/fg, 0/bg
1099
1100 copy-object second-ah, out
1101 }
1102
1103 fn apply-clear _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1104 trace-text trace, "eval", "apply clear"
1105 var args-ah/eax: (addr handle cell) <- copy _args-ah
1106 var _args/eax: (addr cell) <- lookup *args-ah
1107 var args/esi: (addr cell) <- copy _args
1108
1109 var empty-args?/eax: boolean <- nil? args
1110 compare empty-args?, 0/false
1111 {
1112 break-if-=
1113 error trace, "'clear' needs 1 arg but got 0"
1114 return
1115 }
1116
1117 var first-ah/eax: (addr handle cell) <- get args, left
1118 var first/eax: (addr cell) <- lookup *first-ah
1119 var first-type/ecx: (addr int) <- get first, type
1120 compare *first-type, 5/screen
1121 {
1122 break-if-=
1123 error trace, "first arg for 'clear' is not a screen"
1124 return
1125 }
1126 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1127 var _screen/eax: (addr screen) <- lookup *screen-ah
1128 var screen/ecx: (addr screen) <- copy _screen
1129
1130 clear-screen screen
1131 }
1132
1133 fn apply-up _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1134 trace-text trace, "eval", "apply up"
1135 var args-ah/eax: (addr handle cell) <- copy _args-ah
1136 var _args/eax: (addr cell) <- lookup *args-ah
1137 var args/esi: (addr cell) <- copy _args
1138
1139 var empty-args?/eax: boolean <- nil? args
1140 compare empty-args?, 0/false
1141 {
1142 break-if-=
1143 error trace, "'up' needs 1 arg but got 0"
1144 return
1145 }
1146
1147 var first-ah/eax: (addr handle cell) <- get args, left
1148 var first/eax: (addr cell) <- lookup *first-ah
1149 var first-type/ecx: (addr int) <- get first, type
1150 compare *first-type, 5/screen
1151 {
1152 break-if-=
1153 error trace, "first arg for 'up' is not a screen"
1154 return
1155 }
1156 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1157 var _screen/eax: (addr screen) <- lookup *screen-ah
1158 var screen/ecx: (addr screen) <- copy _screen
1159
1160 move-cursor-up screen
1161 }
1162
1163 fn apply-down _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1164 trace-text trace, "eval", "apply 'down'"
1165 var args-ah/eax: (addr handle cell) <- copy _args-ah
1166 var _args/eax: (addr cell) <- lookup *args-ah
1167 var args/esi: (addr cell) <- copy _args
1168
1169 var empty-args?/eax: boolean <- nil? args
1170 compare empty-args?, 0/false
1171 {
1172 break-if-=
1173 error trace, "'down' needs 1 arg but got 0"
1174 return
1175 }
1176
1177 var first-ah/eax: (addr handle cell) <- get args, left
1178 var first/eax: (addr cell) <- lookup *first-ah
1179 var first-type/ecx: (addr int) <- get first, type
1180 compare *first-type, 5/screen
1181 {
1182 break-if-=
1183 error trace, "first arg for 'down' is not a screen"
1184 return
1185 }
1186 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1187 var _screen/eax: (addr screen) <- lookup *screen-ah
1188 var screen/ecx: (addr screen) <- copy _screen
1189
1190 move-cursor-down screen
1191 }
1192
1193 fn apply-left _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1194 trace-text trace, "eval", "apply 'left'"
1195 var args-ah/eax: (addr handle cell) <- copy _args-ah
1196 var _args/eax: (addr cell) <- lookup *args-ah
1197 var args/esi: (addr cell) <- copy _args
1198
1199 var empty-args?/eax: boolean <- nil? args
1200 compare empty-args?, 0/false
1201 {
1202 break-if-=
1203 error trace, "'left' needs 1 arg but got 0"
1204 return
1205 }
1206
1207 var first-ah/eax: (addr handle cell) <- get args, left
1208 var first/eax: (addr cell) <- lookup *first-ah
1209 var first-type/ecx: (addr int) <- get first, type
1210 compare *first-type, 5/screen
1211 {
1212 break-if-=
1213 error trace, "first arg for 'left' is not a screen"
1214 return
1215 }
1216 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1217 var _screen/eax: (addr screen) <- lookup *screen-ah
1218 var screen/ecx: (addr screen) <- copy _screen
1219
1220 move-cursor-left screen
1221 }
1222
1223 fn apply-right _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1224 trace-text trace, "eval", "apply 'right'"
1225 var args-ah/eax: (addr handle cell) <- copy _args-ah
1226 var _args/eax: (addr cell) <- lookup *args-ah
1227 var args/esi: (addr cell) <- copy _args
1228
1229 var empty-args?/eax: boolean <- nil? args
1230 compare empty-args?, 0/false
1231 {
1232 break-if-=
1233 error trace, "'right' needs 1 arg but got 0"
1234 return
1235 }
1236
1237 var first-ah/eax: (addr handle cell) <- get args, left
1238 var first/eax: (addr cell) <- lookup *first-ah
1239 var first-type/ecx: (addr int) <- get first, type
1240 compare *first-type, 5/screen
1241 {
1242 break-if-=
1243 error trace, "first arg for 'right' is not a screen"
1244 return
1245 }
1246 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1247 var _screen/eax: (addr screen) <- lookup *screen-ah
1248 var screen/ecx: (addr screen) <- copy _screen
1249
1250 move-cursor-right screen
1251 }
1252
1253 fn apply-cr _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1254 trace-text trace, "eval", "apply 'cr'"
1255 var args-ah/eax: (addr handle cell) <- copy _args-ah
1256 var _args/eax: (addr cell) <- lookup *args-ah
1257 var args/esi: (addr cell) <- copy _args
1258
1259 var empty-args?/eax: boolean <- nil? args
1260 compare empty-args?, 0/false
1261 {
1262 break-if-=
1263 error trace, "'cr' 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 var first-type/ecx: (addr int) <- get first, type
1270 compare *first-type, 5/screen
1271 {
1272 break-if-=
1273 error trace, "first arg for 'cr' is not a screen"
1274 return
1275 }
1276 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1277 var _screen/eax: (addr screen) <- lookup *screen-ah
1278 var screen/ecx: (addr screen) <- copy _screen
1279
1280 move-cursor-to-left-margin-of-next-line screen
1281 }
1282
1283 fn apply-pixel _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1284 trace-text trace, "eval", "apply pixel"
1285 var args-ah/eax: (addr handle cell) <- copy _args-ah
1286 var _args/eax: (addr cell) <- lookup *args-ah
1287 var args/esi: (addr cell) <- copy _args
1288
1289 var empty-args?/eax: boolean <- nil? args
1290 compare empty-args?, 0/false
1291 {
1292 break-if-=
1293 error trace, "pixel needs 4 args but got 0"
1294 return
1295 }
1296
1297 var first-ah/eax: (addr handle cell) <- get args, left
1298 var first/eax: (addr cell) <- lookup *first-ah
1299 var first-type/ecx: (addr int) <- get first, type
1300 compare *first-type, 5/screen
1301 {
1302 break-if-=
1303 error trace, "first arg for 'pixel' is not a screen"
1304 return
1305 }
1306 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1307 var _screen/eax: (addr screen) <- lookup *screen-ah
1308 var screen/edi: (addr screen) <- copy _screen
1309
1310 var rest-ah/eax: (addr handle cell) <- get args, right
1311 var _rest/eax: (addr cell) <- lookup *rest-ah
1312 var rest/esi: (addr cell) <- copy _rest
1313
1314 var second-ah/eax: (addr handle cell) <- get rest, left
1315 var second/eax: (addr cell) <- lookup *second-ah
1316 var second-type/ecx: (addr int) <- get second, type
1317 compare *second-type, 1/number
1318 {
1319 break-if-=
1320 error trace, "second arg for 'pixel' is not an int (x coordinate)"
1321 return
1322 }
1323 var second-value/eax: (addr float) <- get second, number-data
1324 var x/edx: int <- convert *second-value
1325
1326 var rest-ah/eax: (addr handle cell) <- get rest, right
1327 var _rest/eax: (addr cell) <- lookup *rest-ah
1328 rest <- copy _rest
1329
1330 var third-ah/eax: (addr handle cell) <- get rest, left
1331 var third/eax: (addr cell) <- lookup *third-ah
1332 var third-type/ecx: (addr int) <- get third, type
1333 compare *third-type, 1/number
1334 {
1335 break-if-=
1336 error trace, "third arg for 'pixel' is not an int (y coordinate)"
1337 return
1338 }
1339 var third-value/eax: (addr float) <- get third, number-data
1340 var y/ebx: int <- convert *third-value
1341
1342 var rest-ah/eax: (addr handle cell) <- get rest, right
1343 var _rest/eax: (addr cell) <- lookup *rest-ah
1344 rest <- copy _rest
1345
1346 var fourth-ah/eax: (addr handle cell) <- get rest, left
1347 var fourth/eax: (addr cell) <- lookup *fourth-ah
1348 var fourth-type/ecx: (addr int) <- get fourth, type
1349 compare *fourth-type, 1/number
1350 {
1351 break-if-=
1352 error trace, "fourth arg for 'pixel' is not an int (color; 0..0xff)"
1353 return
1354 }
1355 var fourth-value/eax: (addr float) <- get fourth, number-data
1356 var color/eax: int <- convert *fourth-value
1357 pixel screen, x, y, color
1358
1359 }
1360
1361 fn apply-wait-for-key _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1362 trace-text trace, "eval", "apply key"
1363 var args-ah/eax: (addr handle cell) <- copy _args-ah
1364 var _args/eax: (addr cell) <- lookup *args-ah
1365 var args/esi: (addr cell) <- copy _args
1366
1367 var empty-args?/eax: boolean <- nil? args
1368 compare empty-args?, 0/false
1369 {
1370 break-if-=
1371 error trace, "key needs 1 arg but got 0"
1372 return
1373 }
1374
1375 var first-ah/eax: (addr handle cell) <- get args, left
1376 var first/eax: (addr cell) <- lookup *first-ah
1377 var first-type/ecx: (addr int) <- get first, type
1378 compare *first-type, 6/keyboard
1379 {
1380 break-if-=
1381 error trace, "first arg for 'key' is not a keyboard"
1382 return
1383 }
1384 var keyboard-ah/eax: (addr handle gap-buffer) <- get first, keyboard-data
1385 var _keyboard/eax: (addr gap-buffer) <- lookup *keyboard-ah
1386 var keyboard/ecx: (addr gap-buffer) <- copy _keyboard
1387 var result/eax: int <- wait-for-key keyboard
1388
1389 new-integer out, result
1390 }
1391
1392 fn wait-for-key keyboard: (addr gap-buffer) -> _/eax: int {
1393
1394 {
1395 compare keyboard, 0/real-keyboard
1396 break-if-!=
1397 var key/eax: byte <- read-key 0/real-keyboard
1398 var result/eax: int <- copy key
1399 return result
1400 }
1401
1402 var g/eax: grapheme <- read-from-gap-buffer keyboard
1403 var result/eax: int <- copy g
1404 return result
1405 }
1406
1407 fn apply-stream _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1408 trace-text trace, "eval", "apply stream"
1409 allocate-stream out
1410 }
1411
1412 fn apply-write _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1413 trace-text trace, "eval", "apply write"
1414 var args-ah/eax: (addr handle cell) <- copy _args-ah
1415 var _args/eax: (addr cell) <- lookup *args-ah
1416 var args/esi: (addr cell) <- copy _args
1417
1418 var empty-args?/eax: boolean <- nil? args
1419 compare empty-args?, 0/false
1420 {
1421 break-if-=
1422 error trace, "write needs 2 args but got 0"
1423 return
1424 }
1425
1426 var first-ah/edx: (addr handle cell) <- get args, left
1427 var first/eax: (addr cell) <- lookup *first-ah
1428 var first-type/ecx: (addr int) <- get first, type
1429 compare *first-type, 3/stream
1430 {
1431 break-if-=
1432 error trace, "first arg for 'write' is not a stream"
1433 return
1434 }
1435 var stream-data-ah/eax: (addr handle stream byte) <- get first, text-data
1436 var _stream-data/eax: (addr stream byte) <- lookup *stream-data-ah
1437 var stream-data/ebx: (addr stream byte) <- copy _stream-data
1438
1439 var right-ah/eax: (addr handle cell) <- get args, right
1440 var right/eax: (addr cell) <- lookup *right-ah
1441
1442 var second-ah/eax: (addr handle cell) <- get right, left
1443 var second/eax: (addr cell) <- lookup *second-ah
1444 var second-type/ecx: (addr int) <- get second, type
1445 compare *second-type, 1/number
1446 {
1447 break-if-=
1448 error trace, "second arg for stream is not a number/grapheme"
1449 return
1450 }
1451 var second-value/eax: (addr float) <- get second, number-data
1452 var x-float/xmm0: float <- copy *second-value
1453 var x/eax: int <- convert x-float
1454 var x-grapheme/eax: grapheme <- copy x
1455 write-grapheme stream-data, x-grapheme
1456
1457 copy-object first-ah, out
1458 }
1459
1460 fn apply-lines _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1461 trace-text trace, "eval", "apply lines"
1462 var args-ah/eax: (addr handle cell) <- copy _args-ah
1463 var _args/eax: (addr cell) <- lookup *args-ah
1464 var args/esi: (addr cell) <- copy _args
1465
1466 var empty-args?/eax: boolean <- nil? args
1467 compare empty-args?, 0/false
1468 {
1469 break-if-=
1470 error trace, "lines needs 1 arg but got 0"
1471 return
1472 }
1473
1474 var first-ah/eax: (addr handle cell) <- get args, left
1475 var first/eax: (addr cell) <- lookup *first-ah
1476 var first-type/ecx: (addr int) <- get first, type
1477 compare *first-type, 5/screen
1478 {
1479 break-if-=
1480 error trace, "first arg for 'lines' is not a screen"
1481 return
1482 }
1483 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1484 var _screen/eax: (addr screen) <- lookup *screen-ah
1485 var screen/edx: (addr screen) <- copy _screen
1486
1487 var dummy/eax: int <- copy 0
1488 var height/ecx: int <- copy 0
1489 dummy, height <- screen-size screen
1490 var result/xmm0: float <- convert height
1491 new-float out, result
1492 }
1493
1494 fn apply-abort _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1495 abort "aa"
1496 }
1497
1498 fn apply-columns _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1499 trace-text trace, "eval", "apply columns"
1500 var args-ah/eax: (addr handle cell) <- copy _args-ah
1501 var _args/eax: (addr cell) <- lookup *args-ah
1502 var args/esi: (addr cell) <- copy _args
1503
1504 var empty-args?/eax: boolean <- nil? args
1505 compare empty-args?, 0/false
1506 {
1507 break-if-=
1508 error trace, "columns needs 1 arg but got 0"
1509 return
1510 }
1511
1512 var first-ah/eax: (addr handle cell) <- get args, left
1513 var first/eax: (addr cell) <- lookup *first-ah
1514 var first-type/ecx: (addr int) <- get first, type
1515 compare *first-type, 5/screen
1516 {
1517 break-if-=
1518 error trace, "first arg for 'columns' is not a screen"
1519 return
1520 }
1521 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1522 var _screen/eax: (addr screen) <- lookup *screen-ah
1523 var screen/edx: (addr screen) <- copy _screen
1524
1525 var width/eax: int <- copy 0
1526 var dummy/ecx: int <- copy 0
1527 width, dummy <- screen-size screen
1528 var result/xmm0: float <- convert width
1529 new-float out, result
1530 }
1531
1532 fn apply-width _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1533 trace-text trace, "eval", "apply width"
1534 var args-ah/eax: (addr handle cell) <- copy _args-ah
1535 var _args/eax: (addr cell) <- lookup *args-ah
1536 var args/esi: (addr cell) <- copy _args
1537
1538 var empty-args?/eax: boolean <- nil? args
1539 compare empty-args?, 0/false
1540 {
1541 break-if-=
1542 error trace, "width needs 1 arg but got 0"
1543 return
1544 }
1545
1546 var first-ah/eax: (addr handle cell) <- get args, left
1547 var first/eax: (addr cell) <- lookup *first-ah
1548 var first-type/ecx: (addr int) <- get first, type
1549 compare *first-type, 5/screen
1550 {
1551 break-if-=
1552 error trace, "first arg for 'width' is not a screen"
1553 return
1554 }
1555 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1556 var _screen/eax: (addr screen) <- lookup *screen-ah
1557 var screen/edx: (addr screen) <- copy _screen
1558
1559 var width/eax: int <- copy 0
1560 var dummy/ecx: int <- copy 0
1561 width, dummy <- screen-size screen
1562 width <- shift-left 3/log2-font-width
1563 var result/xmm0: float <- convert width
1564 new-float out, result
1565 }
1566
1567 fn apply-height _args-ah: (addr handle cell), out: (addr handle cell), trace: (addr trace) {
1568 trace-text trace, "eval", "apply height"
1569 var args-ah/eax: (addr handle cell) <- copy _args-ah
1570 var _args/eax: (addr cell) <- lookup *args-ah
1571 var args/esi: (addr cell) <- copy _args
1572
1573 var empty-args?/eax: boolean <- nil? args
1574 compare empty-args?, 0/false
1575 {
1576 break-if-=
1577 error trace, "height needs 1 arg but got 0"
1578 return
1579 }
1580
1581 var first-ah/eax: (addr handle cell) <- get args, left
1582 var first/eax: (addr cell) <- lookup *first-ah
1583 var first-type/ecx: (addr int) <- get first, type
1584 compare *first-type, 5/screen
1585 {
1586 break-if-=
1587 error trace, "first arg for 'height' is not a screen"
1588 return
1589 }
1590 var screen-ah/eax: (addr handle screen) <- get first, screen-data
1591 var _screen/eax: (addr screen) <- lookup *screen-ah
1592 var screen/edx: (addr screen) <- copy _screen
1593
1594 var dummy/eax: int <- copy 0
1595 var height/ecx: int <- copy 0
1596 dummy, height <- screen-size screen
1597 height <- shift-left 4/log2-font-height
1598 var result/xmm0: float <- convert height
1599 new-float out, result
1600 }