https://github.com/akkartik/mu/blob/main/shell/global.mu
1 type global-table {
2 data: (handle array global)
3 final-index: int
4 cursor-index: int
5 }
6
7 type global {
8 name: (handle array byte)
9 input: (handle gap-buffer)
10 value: (handle cell)
11 }
12
13 fn initialize-globals _self: (addr global-table) {
14 var self/esi: (addr global-table) <- copy _self
15 compare self, 0
16 {
17 break-if-!=
18 abort "initialize globals"
19 return
20 }
21 var data-ah/eax: (addr handle array global) <- get self, data
22 populate data-ah, 0x40
23 initialize-primitives self
24 }
25
26 fn load-globals in: (addr handle cell), self: (addr global-table) {
27 draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "loading globals:", 3/fg, 0/bg
28 var remaining-ah/esi: (addr handle cell) <- copy in
29 {
30 var _remaining/eax: (addr cell) <- lookup *remaining-ah
31 var remaining/ebx: (addr cell) <- copy _remaining
32 var done?/eax: boolean <- nil? remaining
33 compare done?, 0/false
34 break-if-!=
35
36 var curr-ah/eax: (addr handle cell) <- get remaining, left
37 var _curr/eax: (addr cell) <- lookup *curr-ah
38 var curr/ecx: (addr cell) <- copy _curr
39 remaining-ah <- get remaining, right
40 draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, " ", 2/fg 0/bg
41 var name-ah/eax: (addr handle cell) <- get curr, left
42 var name/eax: (addr cell) <- lookup *name-ah
43 var name-data-ah/eax: (addr handle stream byte) <- get name, text-data
44 var _name-data/eax: (addr stream byte) <- lookup *name-data-ah
45 var name-data/edx: (addr stream byte) <- copy _name-data
46 rewind-stream name-data
47 draw-stream-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, name-data, 3/fg, 0/bg
48 var value-ah/eax: (addr handle cell) <- get curr, right
49 var value/eax: (addr cell) <- lookup *value-ah
50 var value-data-ah/eax: (addr handle stream byte) <- get value, text-data
51 var _value-data/eax: (addr stream byte) <- lookup *value-data-ah
52 var value-data/ecx: (addr stream byte) <- copy _value-data
53 var value-gap-buffer-storage: (handle gap-buffer)
54 var value-gap-buffer-ah/edi: (addr handle gap-buffer) <- address value-gap-buffer-storage
55 allocate value-gap-buffer-ah
56 var value-gap-buffer/eax: (addr gap-buffer) <- lookup *value-gap-buffer-ah
57 initialize-gap-buffer value-gap-buffer, 0x1000/4KB
58
59 load-gap-buffer-from-stream value-gap-buffer, value-data
60
61 read-evaluate-and-move-to-globals value-gap-buffer-ah, self, name-data
62
63 loop
64 }
65 move-cursor-to-left-margin-of-next-line 0/screen
66
67 }
68
69 fn write-globals out: (addr stream byte), _self: (addr global-table) {
70 var self/esi: (addr global-table) <- copy _self
71 compare self, 0
72 {
73 break-if-!=
74 abort "write globals"
75 return
76 }
77 write out, " (globals . (\n"
78 var data-ah/eax: (addr handle array global) <- get self, data
79 var data/eax: (addr array global) <- lookup *data-ah
80 var final-index/edx: (addr int) <- get self, final-index
81 var curr-index/ecx: int <- copy 1/skip-0
82 {
83 compare curr-index, *final-index
84 break-if->
85 var curr-offset/ebx: (offset global) <- compute-offset data, curr-index
86 var curr/ebx: (addr global) <- index data, curr-offset
87 var curr-value-ah/edx: (addr handle cell) <- get curr, value
88 var curr-value/eax: (addr cell) <- lookup *curr-value-ah
89 var curr-type/eax: (addr int) <- get curr-value, type
90 {
91 compare *curr-type, 4/primitive-function
92 break-if-=
93 compare *curr-type, 5/screen
94 break-if-=
95 compare *curr-type, 6/keyboard
96 break-if-=
97 compare *curr-type, 3/stream
98 break-if-=
99 write out, " ("
100 var curr-name-ah/eax: (addr handle array byte) <- get curr, name
101 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
102 write out, curr-name
103 write out, " . ["
104 var curr-input-ah/eax: (addr handle gap-buffer) <- get curr, input
105 var curr-input/eax: (addr gap-buffer) <- lookup *curr-input-ah
106 append-gap-buffer curr-input, out
107 write out, "])\n"
108 }
109 curr-index <- increment
110 loop
111 }
112 write out, " ))\n"
113 }
114
115
116 fn render-globals screen: (addr screen), _self: (addr global-table), show-cursor?: boolean {
117 clear-rect screen, 0/xmin, 0/ymin, 0x55/xmax, 0x2f/ymax=screen-height-without-menu, 0xdc/bg=green-bg
118 var self/esi: (addr global-table) <- copy _self
119 compare self, 0
120 {
121 break-if-!=
122 abort "render globals"
123 return
124 }
125 var data-ah/eax: (addr handle array global) <- get self, data
126 var data/eax: (addr array global) <- lookup *data-ah
127 var curr-index/edx: int <- copy 1
128 {
129 var curr-offset/ebx: (offset global) <- compute-offset data, curr-index
130 var curr/ebx: (addr global) <- index data, curr-offset
131 var continue?/eax: boolean <- primitive-global? curr
132 compare continue?, 0/false
133 break-if-=
134 curr-index <- increment
135 loop
136 }
137 var lowest-index/edi: int <- copy curr-index
138 var cursor-index/edx: (addr int) <- get self, cursor-index
139 var curr-index/edx: int <- copy *cursor-index
140 var y1: int
141 copy-to y1, 1/padding-top
142 var y2: int
143 copy-to y2, 1/padding-top
144 $render-globals:loop: {
145 compare curr-index, lowest-index
146 break-if-<
147 {
148 compare y1, 0x2f/ymax
149 break-if-<
150 compare y2, 0x2f/ymax
151 break-if-<
152 break $render-globals:loop
153 }
154 {
155 var show-cursor?/edi: boolean <- copy show-cursor?
156 {
157 compare show-cursor?, 0/false
158 break-if-=
159 var cursor-index/eax: (addr int) <- get self, cursor-index
160 compare *cursor-index, curr-index
161 break-if-=
162 show-cursor? <- copy 0/false
163 }
164 var curr-offset/edx: (offset global) <- compute-offset data, curr-index
165 var curr/edx: (addr global) <- index data, curr-offset
166 var curr-input-ah/edx: (addr handle gap-buffer) <- get curr, input
167 var _curr-input/eax: (addr gap-buffer) <- lookup *curr-input-ah
168 var curr-input/ebx: (addr gap-buffer) <- copy _curr-input
169 compare curr-input, 0
170 break-if-=
171 $render-globals:render-global: {
172 var x/eax: int <- copy 0
173 var y/ecx: int <- copy y1
174 compare y, y2
175 {
176 break-if->=
177 x, y <- render-gap-buffer-wrapping-right-then-down screen, curr-input, 1/padding-left, y1, 0x2a/xmax, 0x2f/ymax, show-cursor?, 7/fg=definition, 0xc5/bg=blue-bg
178 y <- add 2
179 copy-to y1, y
180 break $render-globals:render-global
181 }
182 x, y <- render-gap-buffer-wrapping-right-then-down screen, curr-input, 0x2b/xmin, y2, 0x54/xmax, 0x2f/ymax, show-cursor?, 7/fg=definition, 0xc5/bg=blue-bg
183 y <- add 2
184 copy-to y2, y
185 }
186 }
187 curr-index <- decrement
188 loop
189 }
190
191 render-primitives screen, 1/xmin=padding-left, 0x55/xmax, 0x2f/ymax
192 }
193
194 fn render-globals-menu screen: (addr screen), _self: (addr global-table) {
195 var _width/eax: int <- copy 0
196 var height/ecx: int <- copy 0
197 _width, height <- screen-size screen
198 var width/edx: int <- copy _width
199 var y/ecx: int <- copy height
200 y <- decrement
201 var height/ebx: int <- copy y
202 height <- increment
203 clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg
204 set-cursor-position screen, 0/x, y
205 draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight
206 draw-text-rightward-from-cursor screen, " run main ", width, 7/fg, 0xc5/bg=blue-bg
207 draw-text-rightward-from-cursor screen, " ^s ", width, 0/fg, 0x5c/bg=menu-highlight
208 draw-text-rightward-from-cursor screen, " run sandbox ", width, 7/fg, 0xc5/bg=blue-bg
209 draw-text-rightward-from-cursor screen, " ^g ", width, 0/fg, 0x5c/bg=menu-highlight
210 draw-text-rightward-from-cursor screen, " go to ", width, 7/fg, 0xc5/bg=blue-bg
211 draw-text-rightward-from-cursor screen, " ^a ", width, 0/fg, 0x5c/bg=menu-highlight
212 draw-text-rightward-from-cursor screen, " << ", width, 7/fg, 0xc5/bg=blue-bg
213 draw-text-rightward-from-cursor screen, " ^b ", width, 0/fg, 0x5c/bg=menu-highlight
214 draw-text-rightward-from-cursor screen, " <word ", width, 7/fg, 0xc5/bg=blue-bg
215 draw-text-rightward-from-cursor screen, " ^f ", width, 0/fg, 0x5c/bg=menu-highlight
216 draw-text-rightward-from-cursor screen, " word> ", width, 7/fg, 0xc5/bg=blue-bg
217 draw-text-rightward-from-cursor screen, " ^e ", width, 0/fg, 0x5c/bg=menu-highlight
218 draw-text-rightward-from-cursor screen, " >> ", width, 7/fg, 0xc5/bg=blue-bg
219 }
220
221 fn edit-globals _self: (addr global-table), key: grapheme {
222 var self/esi: (addr global-table) <- copy _self
223
224 {
225 compare key, 0x13/ctrl-s
226 break-if-!=
227
228 refresh-cursor-definition self
229 return
230 }
231 var cursor-index-addr/ecx: (addr int) <- get self, cursor-index
232 var cursor-index/ecx: int <- copy *cursor-index-addr
233 var data-ah/eax: (addr handle array global) <- get self, data
234 var data/eax: (addr array global) <- lookup *data-ah
235 var cursor-offset/ecx: (offset global) <- compute-offset data, cursor-index
236 var curr-global/eax: (addr global) <- index data, cursor-offset
237 var curr-editor-ah/eax: (addr handle gap-buffer) <- get curr-global, input
238 var curr-editor/eax: (addr gap-buffer) <- lookup *curr-editor-ah
239 edit-gap-buffer curr-editor, key
240 }
241
242 fn refresh-cursor-definition _self: (addr global-table) {
243 var self/esi: (addr global-table) <- copy _self
244 var cursor-index/edx: (addr int) <- get self, cursor-index
245 refresh-definition self, *cursor-index
246 }
247
248 fn refresh-definition _self: (addr global-table), _index: int {
249 var self/esi: (addr global-table) <- copy _self
250 var data-ah/eax: (addr handle array global) <- get self, data
251 var data/eax: (addr array global) <- lookup *data-ah
252 var index/ecx: int <- copy _index
253 var offset/ecx: (offset global) <- compute-offset data, index
254 var curr-global/ecx: (addr global) <- index data, offset
255 var curr-input-ah/eax: (addr handle gap-buffer) <- get curr-global, input
256 var curr-input/eax: (addr gap-buffer) <- lookup *curr-input-ah
257 var read-result-h: (handle cell)
258 var read-result-ah/edx: (addr handle cell) <- address read-result-h
259 var trace-storage: trace
260 var trace/ebx: (addr trace) <- address trace-storage
261 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
262 read-cell curr-input, read-result-ah, trace
263 macroexpand read-result-ah, self, trace
264 var nil-h: (handle cell)
265 {
266 var nil-ah/eax: (addr handle cell) <- address nil-h
267 allocate-pair nil-ah
268 }
269 var curr-value-ah/eax: (addr handle cell) <- get curr-global, value
270 debug-print "GL", 4/fg, 0/bg
271 evaluate read-result-ah, curr-value-ah, nil-h, self, trace, 0/no-screen-cell, 0/no-keyboard-cell, 1/call-number
272 debug-print "GZ", 4/fg, 0/bg
273 }
274
275 fn assign-or-create-global _self: (addr global-table), name: (addr array byte), value: (handle cell), trace: (addr trace) {
276 var self/esi: (addr global-table) <- copy _self
277 compare self, 0
278 {
279 break-if-!=
280 abort "assign global"
281 return
282 }
283 var curr-index/ecx: int <- find-symbol-name-in-globals self, name
284 {
285 compare curr-index, -1/not-found
286 break-if-!=
287 var final-index-addr/eax: (addr int) <- get self, final-index
288 increment *final-index-addr
289 curr-index <- copy *final-index-addr
290 var cursor-index-addr/eax: (addr int) <- get self, cursor-index
291 copy-to *cursor-index-addr, curr-index
292 }
293 var data-ah/eax: (addr handle array global) <- get self, data
294 var data/eax: (addr array global) <- lookup *data-ah
295 var curr-offset/esi: (offset global) <- compute-offset data, curr-index
296 var curr/esi: (addr global) <- index data, curr-offset
297 var curr-name-ah/eax: (addr handle array byte) <- get curr, name
298 copy-array-object name, curr-name-ah
299 var curr-value-ah/eax: (addr handle cell) <- get curr, value
300 copy-handle value, curr-value-ah
301 }
302
303 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) {
304 var sym/eax: (addr cell) <- copy _sym
305 var sym-name-ah/eax: (addr handle stream byte) <- get sym, text-data
306 var _sym-name/eax: (addr stream byte) <- lookup *sym-name-ah
307 var sym-name/edx: (addr stream byte) <- copy _sym-name
308 var globals/esi: (addr global-table) <- copy _globals
309 {
310 compare globals, 0
311 break-if-=
312 var curr-index/ecx: int <- find-symbol-in-globals globals, sym-name
313 compare curr-index, -1/not-found
314 break-if-=
315 var global-data-ah/eax: (addr handle array global) <- get globals, data
316 var global-data/eax: (addr array global) <- lookup *global-data-ah
317 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index
318 var curr/ebx: (addr global) <- index global-data, curr-offset
319 var curr-value/eax: (addr handle cell) <- get curr, value
320 copy-object curr-value, out
321 return
322 }
323
324 {
325 var sym-is-screen?/eax: boolean <- stream-data-equal? sym-name, "screen"
326 compare sym-is-screen?, 0/false
327 break-if-=
328 compare screen-cell, 0
329 break-if-=
330 copy-object screen-cell, out
331 return
332 }
333
334 {
335 var sym-is-keyboard?/eax: boolean <- stream-data-equal? sym-name, "keyboard"
336 compare sym-is-keyboard?, 0/false
337 break-if-=
338 compare keyboard-cell, 0
339 break-if-=
340 copy-object keyboard-cell, out
341 return
342 }
343
344 var stream-storage: (stream byte 0x40)
345 var stream/ecx: (addr stream byte) <- address stream-storage
346 write stream, "unbound symbol: "
347 rewind-stream sym-name
348 write-stream stream, sym-name
349 error-stream trace, stream
350 }
351
352 fn maybe-lookup-symbol-in-globals _sym: (addr cell), out: (addr handle cell), _globals: (addr global-table), trace: (addr trace) {
353 var sym/eax: (addr cell) <- copy _sym
354 var sym-name-ah/eax: (addr handle stream byte) <- get sym, text-data
355 var _sym-name/eax: (addr stream byte) <- lookup *sym-name-ah
356 var sym-name/edx: (addr stream byte) <- copy _sym-name
357 var globals/esi: (addr global-table) <- copy _globals
358 {
359 compare globals, 0
360 break-if-=
361 var curr-index/ecx: int <- find-symbol-in-globals globals, sym-name
362 compare curr-index, -1/not-found
363 break-if-=
364 var global-data-ah/eax: (addr handle array global) <- get globals, data
365 var global-data/eax: (addr array global) <- lookup *global-data-ah
366 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index
367 var curr/ebx: (addr global) <- index global-data, curr-offset
368 var curr-value/eax: (addr handle cell) <- get curr, value
369 copy-object curr-value, out
370 return
371 }
372 }
373
374
375
376 fn find-symbol-in-globals _globals: (addr global-table), sym-name: (addr stream byte) -> _/ecx: int {
377 var globals/esi: (addr global-table) <- copy _globals
378 compare globals, 0
379 {
380 break-if-!=
381 return -1/not-found
382 }
383 var global-data-ah/eax: (addr handle array global) <- get globals, data
384 var global-data/eax: (addr array global) <- lookup *global-data-ah
385 var final-index/ecx: (addr int) <- get globals, final-index
386 var curr-index/ecx: int <- copy *final-index
387 {
388 compare curr-index, 0
389 break-if-<
390 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index
391 var curr/ebx: (addr global) <- index global-data, curr-offset
392 var curr-name-ah/eax: (addr handle array byte) <- get curr, name
393 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
394 var found?/eax: boolean <- stream-data-equal? sym-name, curr-name
395 compare found?, 0/false
396 {
397 break-if-=
398 return curr-index
399 }
400 curr-index <- decrement
401 loop
402 }
403 return -1/not-found
404 }
405
406
407
408 fn find-symbol-name-in-globals _globals: (addr global-table), sym-name: (addr array byte) -> _/ecx: int {
409 var globals/esi: (addr global-table) <- copy _globals
410 compare globals, 0
411 {
412 break-if-!=
413 return -1/not-found
414 }
415 var global-data-ah/eax: (addr handle array global) <- get globals, data
416 var global-data/eax: (addr array global) <- lookup *global-data-ah
417 var final-index/ecx: (addr int) <- get globals, final-index
418 var curr-index/ecx: int <- copy *final-index
419 {
420 compare curr-index, 0
421 break-if-<
422 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index
423 var curr/ebx: (addr global) <- index global-data, curr-offset
424 var curr-name-ah/eax: (addr handle array byte) <- get curr, name
425 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
426 var found?/eax: boolean <- string-equal? sym-name, curr-name
427 compare found?, 0/false
428 {
429 break-if-=
430 return curr-index
431 }
432 curr-index <- decrement
433 loop
434 }
435 return -1/not-found
436 }
437
438 fn mutate-binding-in-globals name: (addr stream byte), val: (addr handle cell), _globals: (addr global-table), trace: (addr trace) {
439 var globals/esi: (addr global-table) <- copy _globals
440 {
441 compare globals, 0
442 break-if-=
443 var curr-index/ecx: int <- find-symbol-in-globals globals, name
444 compare curr-index, -1/not-found
445 break-if-=
446 var global-data-ah/eax: (addr handle array global) <- get globals, data
447 var global-data/eax: (addr array global) <- lookup *global-data-ah
448 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index
449 var curr/ebx: (addr global) <- index global-data, curr-offset
450 var dest/eax: (addr handle cell) <- get curr, value
451 copy-object val, dest
452 return
453 }
454
455 var stream-storage: (stream byte 0x40)
456 var stream/ecx: (addr stream byte) <- address stream-storage
457 write stream, "unbound symbol: "
458 rewind-stream name
459 write-stream stream, name
460 error-stream trace, stream
461 }
462
463
464
465
466 fn maybe-stash-gap-buffer-to-global _globals: (addr global-table), _definition-ah: (addr handle cell), gap: (addr handle gap-buffer) {
467
468 var definition-ah/eax: (addr handle cell) <- copy _definition-ah
469 var _definition/eax: (addr cell) <- lookup *definition-ah
470 var definition/esi: (addr cell) <- copy _definition
471 var definition-type/eax: (addr int) <- get definition, type
472 compare *definition-type, 0/pair
473 {
474 break-if-=
475 return
476 }
477
478 var left-ah/eax: (addr handle cell) <- get definition, left
479 var _left/eax: (addr cell) <- lookup *left-ah
480 var left/ecx: (addr cell) <- copy _left
481 {
482 var def?/eax: boolean <- symbol-equal? left, "define"
483 compare def?, 0/false
484 break-if-!=
485 var set?/eax: boolean <- symbol-equal? left, "set"
486 compare set?, 0/false
487 break-if-!=
488 return
489 }
490
491 var right-ah/eax: (addr handle cell) <- get definition, right
492 var right/eax: (addr cell) <- lookup *right-ah
493 var defined-symbol-ah/eax: (addr handle cell) <- get right, left
494 var defined-symbol/eax: (addr cell) <- lookup *defined-symbol-ah
495 var defined-symbol-name-ah/eax: (addr handle stream byte) <- get defined-symbol, text-data
496 var defined-symbol-name/eax: (addr stream byte) <- lookup *defined-symbol-name-ah
497 var index/ecx: int <- find-symbol-in-globals _globals, defined-symbol-name
498 {
499 compare index, -1/not-found
500 break-if-!=
501 return
502 }
503
504 var globals/eax: (addr global-table) <- copy _globals
505 compare globals, 0
506 {
507 break-if-!=
508 abort "stash to globals"
509 return
510 }
511 var global-data-ah/eax: (addr handle array global) <- get globals, data
512 var global-data/eax: (addr array global) <- lookup *global-data-ah
513 var offset/ebx: (offset global) <- compute-offset global-data, index
514 var dest-global/eax: (addr global) <- index global-data, offset
515 var dest-ah/eax: (addr handle gap-buffer) <- get dest-global, input
516 copy-object gap, dest-ah
517
518 var dest/eax: (addr gap-buffer) <- lookup *dest-ah
519 var capacity/ecx: int <- gap-buffer-capacity dest
520 var gap2/eax: (addr handle gap-buffer) <- copy gap
521 allocate gap2
522 var gap-addr/eax: (addr gap-buffer) <- lookup *gap2
523 initialize-gap-buffer gap-addr, capacity
524 }
525
526
527
528 fn move-gap-buffer-to-global _globals: (addr global-table), _definition-ah: (addr handle cell), gap: (addr handle gap-buffer) {
529
530 var definition-ah/eax: (addr handle cell) <- copy _definition-ah
531 var _definition/eax: (addr cell) <- lookup *definition-ah
532 var definition/esi: (addr cell) <- copy _definition
533 var definition-type/eax: (addr int) <- get definition, type
534 compare *definition-type, 0/pair
535 {
536 break-if-=
537 return
538 }
539
540 var left-ah/eax: (addr handle cell) <- get definition, left
541 var _left/eax: (addr cell) <- lookup *left-ah
542 var left/ecx: (addr cell) <- copy _left
543 {
544 var def?/eax: boolean <- symbol-equal? left, "define"
545 compare def?, 0/false
546 break-if-!=
547 var set?/eax: boolean <- symbol-equal? left, "set"
548 compare set?, 0/false
549 break-if-!=
550 return
551 }
552
553 var right-ah/eax: (addr handle cell) <- get definition, right
554 var right/eax: (addr cell) <- lookup *right-ah
555 var defined-symbol-ah/eax: (addr handle cell) <- get right, left
556 var defined-symbol/eax: (addr cell) <- lookup *defined-symbol-ah
557 var defined-symbol-name-ah/eax: (addr handle stream byte) <- get defined-symbol, text-data
558 var defined-symbol-name/eax: (addr stream byte) <- lookup *defined-symbol-name-ah
559 var index/ecx: int <- find-symbol-in-globals _globals, defined-symbol-name
560 {
561 compare index, -1/not-found
562 break-if-!=
563 return
564 }
565
566 var globals/eax: (addr global-table) <- copy _globals
567 compare globals, 0
568 {
569 break-if-!=
570 abort "move to globals"
571 return
572 }
573 var global-data-ah/eax: (addr handle array global) <- get globals, data
574 var global-data/eax: (addr array global) <- lookup *global-data-ah
575 var offset/ebx: (offset global) <- compute-offset global-data, index
576 var dest-global/eax: (addr global) <- index global-data, offset
577 var dest-ah/eax: (addr handle gap-buffer) <- get dest-global, input
578 copy-object gap, dest-ah
579 }
580
581 fn set-global-cursor-index _globals: (addr global-table), name-gap: (addr gap-buffer) {
582 var globals/esi: (addr global-table) <- copy _globals
583 var name-storage: (stream byte 0x40)
584 var name/ecx: (addr stream byte) <- address name-storage
585 emit-gap-buffer name-gap, name
586 var index/ecx: int <- find-symbol-in-globals globals, name
587 var dest/edi: (addr int) <- get globals, cursor-index
588 copy-to *dest, index
589 }