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