https://github.com/akkartik/mu/blob/main/shell/global.mu
1 type global-table {
2 data: (handle array global)
3 final-index: int
4 render-list: (handle array int)
5
6 }
7
8 type global {
9 name: (handle array byte)
10 input: (handle gap-buffer)
11 value: (handle cell)
12 trace: (handle trace)
13 }
14
15 fn initialize-globals _self: (addr global-table) {
16 var self/esi: (addr global-table) <- copy _self
17 compare self, 0
18 {
19 break-if-!=
20 abort "initialize globals"
21 return
22 }
23 var data-ah/eax: (addr handle array global) <- get self, data
24 populate data-ah, 0x80
25 initialize-primitives self
26 var render-ah/eax: (addr handle array int) <- get self, render-list
27 populate render-ah, 0x20/render-size
28 }
29
30 fn load-globals in: (addr handle cell), self: (addr global-table) {
31 draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "loading globals:", 3/fg, 0/bg
32 var remaining-ah/esi: (addr handle cell) <- copy in
33 {
34 var _remaining/eax: (addr cell) <- lookup *remaining-ah
35 var remaining/ebx: (addr cell) <- copy _remaining
36 var done?/eax: boolean <- nil? remaining
37 compare done?, 0/false
38 break-if-!=
39 var curr-ah/eax: (addr handle cell) <- get remaining, left
40 var _curr/eax: (addr cell) <- lookup *curr-ah
41 var curr/ecx: (addr cell) <- copy _curr
42 remaining-ah <- get remaining, right
43 var name-ah/eax: (addr handle cell) <- get curr, left
44 var name/eax: (addr cell) <- lookup *name-ah
45 var name-data-ah/eax: (addr handle stream byte) <- get name, text-data
46 var _name-data/eax: (addr stream byte) <- lookup *name-data-ah
47 var name-data/edx: (addr stream byte) <- copy _name-data
48 rewind-stream name-data
49 draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, " ", 3/fg 0/bg
50 draw-stream-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, name-data, 3/fg, 0/bg
51 var value-ah/eax: (addr handle cell) <- get curr, right
52 var value/eax: (addr cell) <- lookup *value-ah
53 var value-data-ah/eax: (addr handle stream byte) <- get value, text-data
54 var _value-data/eax: (addr stream byte) <- lookup *value-data-ah
55 var value-data/ecx: (addr stream byte) <- copy _value-data
56 var value-gap-buffer-storage: (handle gap-buffer)
57 var value-gap-buffer-ah/edi: (addr handle gap-buffer) <- address value-gap-buffer-storage
58 allocate value-gap-buffer-ah
59 var value-gap-buffer/eax: (addr gap-buffer) <- lookup *value-gap-buffer-ah
60 initialize-gap-buffer value-gap-buffer, 0x40000/256KB
61 load-gap-buffer-from-stream value-gap-buffer, value-data
62 load-lexical-scope value-gap-buffer-ah, self
63 loop
64 }
65 move-cursor-to-left-margin-of-next-line 0/screen
66 }
67
68 fn write-globals out: (addr stream byte), _self: (addr global-table) {
69 var self/esi: (addr global-table) <- copy _self
70 compare self, 0
71 {
72 break-if-!=
73 abort "write globals"
74 return
75 }
76 write out, " (globals . (\n"
77 var data-ah/eax: (addr handle array global) <- get self, data
78 var data/eax: (addr array global) <- lookup *data-ah
79 var final-index/edx: (addr int) <- get self, final-index
80 var curr-index/ecx: int <- copy 1/skip-0
81 {
82 compare curr-index, *final-index
83 break-if->
84 var curr-offset/ebx: (offset global) <- compute-offset data, curr-index
85 var curr/ebx: (addr global) <- index data, curr-offset
86 var curr-value-ah/edx: (addr handle cell) <- get curr, value
87 var curr-value/eax: (addr cell) <- lookup *curr-value-ah
88 var curr-type/eax: (addr int) <- get curr-value, type
89 {
90 compare *curr-type, 4/primitive-function
91 break-if-=
92 compare *curr-type, 5/screen
93 break-if-=
94 compare *curr-type, 6/keyboard
95 break-if-=
96 write out, " ("
97 var curr-name-ah/eax: (addr handle array byte) <- get curr, name
98 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
99 write out, curr-name
100 write out, " . ["
101 var curr-input-ah/eax: (addr handle gap-buffer) <- get curr, input
102 var curr-input/eax: (addr gap-buffer) <- lookup *curr-input-ah
103 {
104 compare curr-input, 0
105 break-if-!=
106 abort "null gap buffer"
107 }
108 append-gap-buffer curr-input, out
109 write out, "])\n"
110 }
111 curr-index <- increment
112 loop
113 }
114 write out, " ))\n"
115 }
116
117
118 fn render-globals screen: (addr screen), _self: (addr global-table), show-cursor?: boolean {
119 clear-rect screen, 0/xmin, 0/ymin, 0x55/xmax, 0x2f/ymax=screen-height-without-menu, 0xdc/bg=green-bg
120 var self/esi: (addr global-table) <- copy _self
121 compare self, 0
122 {
123 break-if-!=
124 abort "render globals"
125 return
126 }
127 var data-ah/eax: (addr handle array global) <- get self, data
128 var _data/eax: (addr array global) <- lookup *data-ah
129 var data/ebx: (addr array global) <- copy _data
130 var curr-index/edx: int <- copy 0
131 var y1: int
132 copy-to y1, 1/padding-top
133 var y2: int
134 copy-to y2, 1/padding-top
135 $render-globals:loop: {
136 compare curr-index, 0x20/render-size
137 break-if->=
138 {
139 compare y1, 0x2f/ymax
140 break-if-<
141 compare y2, 0x2f/ymax
142 break-if-<
143 break $render-globals:loop
144 }
145 $render-globals:iter: {
146 var cursor-in-current-line?: boolean
147 {
148 compare show-cursor?, 0/false
149 break-if-=
150 compare curr-index, 0
151 break-if-!=
152 copy-to cursor-in-current-line?, 1/true
153 }
154 var render-list-ah/eax: (addr handle array int) <- get self, render-list
155 var render-list/eax: (addr array int) <- lookup *render-list-ah
156 var global-id-a/eax: (addr int) <- index render-list, curr-index
157 var global-id/eax: int <- copy *global-id-a
158 compare global-id, 0
159 break-if-=
160 var global-offset/edx: (offset global) <- compute-offset data, global-id
161 var curr/edx: (addr global) <- index data, global-offset
162 {
163 var render-image?/eax: boolean <- render-image? curr, cursor-in-current-line?
164 compare render-image?, 0/false
165 break-if-=
166 var y/ecx: int <- render-image-definition screen, curr, 0/x y1
167 y <- increment
168 copy-to y1, y
169 break $render-globals:iter
170 }
171 var curr-input-ah/eax: (addr handle gap-buffer) <- get curr, input
172 var _curr-input/eax: (addr gap-buffer) <- lookup *curr-input-ah
173 var curr-input/ebx: (addr gap-buffer) <- copy _curr-input
174 compare curr-input, 0
175 break-if-=
176 var curr-trace-ah/eax: (addr handle trace) <- get curr, trace
177 var _curr-trace/eax: (addr trace) <- lookup *curr-trace-ah
178 var curr-trace/edx: (addr trace) <- copy _curr-trace
179 $render-globals:render-global: {
180 var x/eax: int <- copy 0
181 var y/ecx: int <- copy y1
182 compare y, y2
183 {
184 break-if->=
185 x, y <- render-gap-buffer-wrapping-right-then-down screen, curr-input, 1/padding-left, y1, 0x2a/xmax, 0x2f/ymax, cursor-in-current-line?, 7/fg=definition, 0xc5/bg=blue-bg
186 y <- increment
187 y <- render-trace screen, curr-trace, 1/padding-left, y, 0x2a/xmax, 0x2f/ymax, 0/no-cursor
188 y <- increment
189 copy-to y1, y
190 break $render-globals:render-global
191 }
192 x, y <- render-gap-buffer-wrapping-right-then-down screen, curr-input, 0x2b/xmin, y2, 0x54/xmax, 0x2f/ymax, cursor-in-current-line?, 7/fg=definition, 0xc5/bg=blue-bg
193 y <- increment
194 y <- render-trace screen, curr-trace, 0x2b/xmin, y, 0x54/xmax, 0x2f/ymax, 0/no-cursor
195 y <- increment
196 copy-to y2, y
197 }
198 }
199 curr-index <- increment
200 loop
201 }
202
203 render-primitives screen, 1/xmin=padding-left, 0x55/xmax, 0x2f/ymax
204 }
205
206 fn render-globals-menu screen: (addr screen), _self: (addr global-table) {
207 var _width/eax: int <- copy 0
208 var height/ecx: int <- copy 0
209 _width, height <- screen-size screen
210 var width/edx: int <- copy _width
211 var y/ecx: int <- copy height
212 y <- decrement
213 var height/ebx: int <- copy y
214 height <- increment
215 clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg
216 set-cursor-position screen, 0/x, y
217 draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight
218 draw-text-rightward-from-cursor screen, " run main ", width, 7/fg, 0xc5/bg=blue-bg
219 draw-text-rightward-from-cursor screen, " ^s ", width, 0/fg, 0x5c/bg=menu-highlight
220 draw-text-rightward-from-cursor screen, " run sandbox ", width, 7/fg, 0xc5/bg=blue-bg
221 draw-text-rightward-from-cursor screen, " ^g ", width, 0/fg, 0x5c/bg=menu-highlight
222 draw-text-rightward-from-cursor screen, " go to ", width, 7/fg, 0xc5/bg=blue-bg
223 draw-text-rightward-from-cursor screen, " ^a ", width, 0/fg, 0x5c/bg=menu-highlight
224 draw-text-rightward-from-cursor screen, " << ", width, 7/fg, 0xc5/bg=blue-bg
225 draw-text-rightward-from-cursor screen, " ^b ", width, 0/fg, 0x5c/bg=menu-highlight
226 draw-text-rightward-from-cursor screen, " <word ", width, 7/fg, 0xc5/bg=blue-bg
227 draw-text-rightward-from-cursor screen, " ^f ", width, 0/fg, 0x5c/bg=menu-highlight
228 draw-text-rightward-from-cursor screen, " word> ", width, 7/fg, 0xc5/bg=blue-bg
229 draw-text-rightward-from-cursor screen, " ^e ", width, 0/fg, 0x5c/bg=menu-highlight
230 draw-text-rightward-from-cursor screen, " >> ", width, 7/fg, 0xc5/bg=blue-bg
231 }
232
233 fn edit-globals _self: (addr global-table), key: code-point-utf8 {
234 var self/esi: (addr global-table) <- copy _self
235
236 {
237 compare key, 0x13/ctrl-s
238 break-if-!=
239
240 refresh-cursor-definition self
241 return
242 }
243 var cursor-index/ecx: int <- cursor-global self
244 compare cursor-index, 0
245 {
246 break-if-!=
247 return
248 }
249 var data-ah/eax: (addr handle array global) <- get self, data
250 var data/eax: (addr array global) <- lookup *data-ah
251 var cursor-offset/ecx: (offset global) <- compute-offset data, cursor-index
252 var curr-global/eax: (addr global) <- index data, cursor-offset
253 var curr-editor-ah/eax: (addr handle gap-buffer) <- get curr-global, input
254 var curr-editor/eax: (addr gap-buffer) <- lookup *curr-editor-ah
255 edit-gap-buffer curr-editor, key
256 }
257
258 fn create-empty-global _self: (addr global-table), name-stream: (addr stream byte), capacity: int {
259 var self/esi: (addr global-table) <- copy _self
260 var final-index-addr/ecx: (addr int) <- get self, final-index
261 increment *final-index-addr
262 var render-list-ah/eax: (addr handle array int) <- get self, render-list
263 var render-list/eax: (addr array int) <- lookup *render-list-ah
264 slide-down render-list, 0/start 0x1f/penultimate, 1/target
265 var curr-index/ecx: int <- copy *final-index-addr
266 var dest/eax: (addr int) <- index render-list, 0
267 copy-to *dest, curr-index
268 var data-ah/eax: (addr handle array global) <- get self, data
269 var data/eax: (addr array global) <- lookup *data-ah
270 var curr-offset/ecx: (offset global) <- compute-offset data, curr-index
271 var curr/esi: (addr global) <- index data, curr-offset
272 var curr-name-ah/eax: (addr handle array byte) <- get curr, name
273 stream-to-array name-stream, curr-name-ah
274 var curr-input-ah/eax: (addr handle gap-buffer) <- get curr, input
275 allocate curr-input-ah
276 var curr-input/eax: (addr gap-buffer) <- lookup *curr-input-ah
277 initialize-gap-buffer curr-input, capacity
278 var trace-ah/eax: (addr handle trace) <- get curr, trace
279 allocate trace-ah
280 var trace/eax: (addr trace) <- lookup *trace-ah
281 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
282 }
283
284 fn refresh-cursor-definition _self: (addr global-table) {
285 var self/esi: (addr global-table) <- copy _self
286 var render-list-ah/eax: (addr handle array int) <- get self, render-list
287 var render-list/eax: (addr array int) <- lookup *render-list-ah
288 var cursor-index/edx: (addr int) <- index render-list, 0
289 refresh-definition self, *cursor-index
290 }
291
292 fn refresh-definition _self: (addr global-table), _index: int {
293 var self/esi: (addr global-table) <- copy _self
294 var data-ah/eax: (addr handle array global) <- get self, data
295 var data/eax: (addr array global) <- lookup *data-ah
296 var index/ebx: int <- copy _index
297 var offset/ebx: (offset global) <- compute-offset data, index
298 var curr-global/ebx: (addr global) <- index data, offset
299 var curr-input-ah/edx: (addr handle gap-buffer) <- get curr-global, input
300 var curr-trace-ah/eax: (addr handle trace) <- get curr-global, trace
301 var curr-trace/eax: (addr trace) <- lookup *curr-trace-ah
302 clear-trace curr-trace
303 var curr-value-ah/edi: (addr handle cell) <- get curr-global, value
304 var definitions-created-storage: (stream int 0x10)
305 var definitions-created/ecx: (addr stream int) <- address definitions-created-storage
306 read-and-evaluate-and-save-gap-buffer-to-globals curr-input-ah, curr-value-ah, self, definitions-created, curr-trace, 0/no-screen, 0/no-keyboard
307 }
308
309 fn assign-or-create-global _self: (addr global-table), name: (addr array byte), value: (handle cell), index-updated: (addr int), trace: (addr trace) {
310 var self/esi: (addr global-table) <- copy _self
311 compare self, 0
312 {
313 break-if-!=
314 abort "assign global"
315 }
316 var curr-index/ecx: int <- find-symbol-name-in-globals self, name
317 {
318 compare curr-index, -1/not-found
319 break-if-!=
320 var final-index-addr/eax: (addr int) <- get self, final-index
321 increment *final-index-addr
322 curr-index <- copy *final-index-addr
323 var arr-ah/eax: (addr handle array int) <- get self, render-list
324 var arr/eax: (addr array int) <- lookup *arr-ah
325 slide-down arr, 0/start 0x1e/penultimate, 1/target
326 var dest/eax: (addr int) <- index arr, 0
327 copy-to *dest, curr-index
328 }
329 var data-ah/eax: (addr handle array global) <- get self, data
330 var data/eax: (addr array global) <- lookup *data-ah
331 var curr-offset/esi: (offset global) <- compute-offset data, curr-index
332 var curr/esi: (addr global) <- index data, curr-offset
333 var curr-name-ah/eax: (addr handle array byte) <- get curr, name
334 copy-array-object name, curr-name-ah
335 var curr-value-ah/eax: (addr handle cell) <- get curr, value
336 copy-handle value, curr-value-ah
337 var index-updated/edi: (addr int) <- copy index-updated
338 copy-to *index-updated, curr-index
339 var trace-ah/eax: (addr handle trace) <- get curr, trace
340 allocate trace-ah
341 var trace/eax: (addr trace) <- lookup *trace-ah
342 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
343 }
344
345 fn bump-global _globals: (addr global-table), global-id: int {
346 var globals/esi: (addr global-table) <- copy _globals
347 var render-list-ah/eax: (addr handle array int) <- get globals, render-list
348 var render-list/eax: (addr array int) <- lookup *render-list-ah
349 var idx/ecx: int <- find-slide-down-slot-in-array render-list, global-id
350 {
351 compare idx, 0
352 break-if-!=
353 return
354 }
355 slide-down render-list, 0/start idx, 1/target
356 var dest/eax: (addr int) <- index render-list, 0
357 var val/ecx: int <- copy global-id
358 copy-to *dest, val
359 }
360
361 fn cursor-global _globals: (addr global-table) -> _/ecx: int {
362 var globals/esi: (addr global-table) <- copy _globals
363 var render-list-ah/eax: (addr handle array int) <- get globals, render-list
364 var render-list/eax: (addr array int) <- lookup *render-list-ah
365 var dest/eax: (addr int) <- index render-list, 0
366 return *dest
367 }
368
369 fn lookup-symbol-in-globals _sym: (addr cell), out: (addr handle cell), _globals: (addr global-table), trace: (addr trace), inner-screen-var: (addr handle cell), inner-keyboard-var: (addr handle cell) {
370 var sym/eax: (addr cell) <- copy _sym
371 var sym-name-ah/eax: (addr handle stream byte) <- get sym, text-data
372 var _sym-name/eax: (addr stream byte) <- lookup *sym-name-ah
373 var sym-name/edx: (addr stream byte) <- copy _sym-name
374 var globals/esi: (addr global-table) <- copy _globals
375 {
376 compare globals, 0
377 break-if-=
378 var curr-index/ecx: int <- find-symbol-in-globals globals, sym-name
379 compare curr-index, -1/not-found
380 break-if-=
381 var global-data-ah/eax: (addr handle array global) <- get globals, data
382 var global-data/eax: (addr array global) <- lookup *global-data-ah
383 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index
384 var curr/ebx: (addr global) <- index global-data, curr-offset
385 var curr-value/eax: (addr handle cell) <- get curr, value
386 copy-object curr-value, out
387 return
388 }
389
390 {
391 var sym-is-screen?/eax: boolean <- stream-data-equal? sym-name, "screen"
392 compare sym-is-screen?, 0/false
393 break-if-=
394 compare inner-screen-var, 0
395 break-if-=
396 copy-object inner-screen-var, out
397 return
398 }
399
400 {
401 var sym-is-keyboard?/eax: boolean <- stream-data-equal? sym-name, "keyboard"
402 compare sym-is-keyboard?, 0/false
403 break-if-=
404 compare inner-keyboard-var, 0
405 break-if-=
406 copy-object inner-keyboard-var, out
407 return
408 }
409
410 var stream-storage: (stream byte 0x40)
411 var stream/ecx: (addr stream byte) <- address stream-storage
412 write stream, "unbound symbol: "
413 rewind-stream sym-name
414 write-stream stream, sym-name
415 error-stream trace, stream
416 }
417
418 fn maybe-lookup-symbol-in-globals _sym: (addr cell), out: (addr handle cell), _globals: (addr global-table), trace: (addr trace) {
419 var sym/eax: (addr cell) <- copy _sym
420 var sym-name-ah/eax: (addr handle stream byte) <- get sym, text-data
421 var _sym-name/eax: (addr stream byte) <- lookup *sym-name-ah
422 var sym-name/edx: (addr stream byte) <- copy _sym-name
423 var globals/esi: (addr global-table) <- copy _globals
424 {
425 compare globals, 0
426 break-if-=
427 var curr-index/ecx: int <- find-symbol-in-globals globals, sym-name
428 compare curr-index, -1/not-found
429 break-if-=
430 var global-data-ah/eax: (addr handle array global) <- get globals, data
431 var global-data/eax: (addr array global) <- lookup *global-data-ah
432 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index
433 var curr/ebx: (addr global) <- index global-data, curr-offset
434 var curr-value/eax: (addr handle cell) <- get curr, value
435 copy-object curr-value, out
436 return
437 }
438 }
439
440
441
442 fn find-symbol-in-globals _globals: (addr global-table), sym-name: (addr stream byte) -> _/ecx: int {
443 var globals/esi: (addr global-table) <- copy _globals
444 compare globals, 0
445 {
446 break-if-!=
447 return -1/not-found
448 }
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 final-index/ecx: (addr int) <- get globals, final-index
452 var curr-index/ecx: int <- copy *final-index
453 {
454 compare curr-index, 0
455 break-if-<
456 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index
457 var curr/ebx: (addr global) <- index global-data, curr-offset
458 var curr-name-ah/eax: (addr handle array byte) <- get curr, name
459 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
460 var found?/eax: boolean <- stream-data-equal? sym-name, curr-name
461 compare found?, 0/false
462 {
463 break-if-=
464 return curr-index
465 }
466 curr-index <- decrement
467 loop
468 }
469 return -1/not-found
470 }
471
472
473
474 fn find-symbol-name-in-globals _globals: (addr global-table), sym-name: (addr array byte) -> _/ecx: int {
475 var globals/esi: (addr global-table) <- copy _globals
476 compare globals, 0
477 {
478 break-if-!=
479 return -1/not-found
480 }
481 var global-data-ah/eax: (addr handle array global) <- get globals, data
482 var global-data/eax: (addr array global) <- lookup *global-data-ah
483 var final-index/ecx: (addr int) <- get globals, final-index
484 var curr-index/ecx: int <- copy *final-index
485 {
486 compare curr-index, 0
487 break-if-<
488 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index
489 var curr/ebx: (addr global) <- index global-data, curr-offset
490 var curr-name-ah/eax: (addr handle array byte) <- get curr, name
491 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
492 var found?/eax: boolean <- string-equal? sym-name, curr-name
493 compare found?, 0/false
494 {
495 break-if-=
496 return curr-index
497 }
498 curr-index <- decrement
499 loop
500 }
501 return -1/not-found
502 }
503
504 fn mutate-binding-in-globals name: (addr stream byte), val: (addr handle cell), _globals: (addr global-table), trace: (addr trace) {
505 var globals/esi: (addr global-table) <- copy _globals
506 {
507 compare globals, 0
508 break-if-=
509 var curr-index/ecx: int <- find-symbol-in-globals globals, name
510 compare curr-index, -1/not-found
511 break-if-=
512 var global-data-ah/eax: (addr handle array global) <- get globals, data
513 var global-data/eax: (addr array global) <- lookup *global-data-ah
514 var curr-offset/ebx: (offset global) <- compute-offset global-data, curr-index
515 var curr/ebx: (addr global) <- index global-data, curr-offset
516 var dest/eax: (addr handle cell) <- get curr, value
517 copy-object val, dest
518 return
519 }
520
521 var stream-storage: (stream byte 0x40)
522 var stream/ecx: (addr stream byte) <- address stream-storage
523 write stream, "unbound symbol: "
524 rewind-stream name
525 write-stream stream, name
526 error-stream trace, stream
527 }
528
529 fn stash-gap-buffer-to-globals _globals: (addr global-table), definitions: (addr stream int), gap: (addr handle gap-buffer) {
530 var globals/eax: (addr global-table) <- copy _globals
531 compare globals, 0
532 {
533 break-if-!=
534 return
535 }
536 var global-data-ah/eax: (addr handle array global) <- get globals, data
537 var global-data/eax: (addr array global) <- lookup *global-data-ah
538 rewind-stream definitions
539 {
540 {
541 var done?/eax: boolean <- stream-empty? definitions
542 compare done?, 0/false
543 }
544 break-if-!=
545 var index: int
546 var index-addr/ecx: (addr int) <- address index
547 read-from-stream definitions, index-addr
548 var index/ecx: int <- copy *index-addr
549 var offset/ebx: (offset global) <- compute-offset global-data, index
550 var dest-global/eax: (addr global) <- index global-data, offset
551 var dest-ah/eax: (addr handle gap-buffer) <- get dest-global, input
552 copy-object gap, dest-ah
553 loop
554 }
555 }
556
557
558 fn load-lexical-scope in-ah: (addr handle gap-buffer), _globals: (addr global-table) {
559 var globals/esi: (addr global-table) <- copy _globals
560 var definitions-created-storage: (stream int 0x10)
561 var definitions-created/ebx: (addr stream int) <- address definitions-created-storage
562 var trace-h: (handle trace)
563 var trace-ah/edx: (addr handle trace) <- address trace-h
564 allocate trace-ah
565 var trace/eax: (addr trace) <- lookup *trace-ah
566 initialize-trace trace, 1/only-errors, 0x10/capacity, 0/visible
567 var dummy-result-h: (handle cell)
568 var dummy-result-ah/ecx: (addr handle cell) <- address dummy-result-h
569 read-and-evaluate-and-save-gap-buffer-to-globals in-ah, dummy-result-ah, globals, definitions-created, trace, 0/no-inner-screen-var, 0/no-inner-keyboard-var
570
571
572 rewind-stream definitions-created
573 var globals-data-ah/eax: (addr handle array global) <- get globals, data
574 var _globals-data/eax: (addr array global) <- lookup *globals-data-ah
575 var globals-data/edi: (addr array global) <- copy _globals-data
576 {
577 var no-definitions?/eax: boolean <- stream-empty? definitions-created
578 compare no-definitions?, 0/false
579 break-if-!=
580 var curr-index: int
581 var curr-index-a/eax: (addr int) <- address curr-index
582 read-from-stream definitions-created, curr-index-a
583 var curr-offset/eax: (offset global) <- compute-offset globals-data, curr-index
584 var curr-global/ecx: (addr global) <- index globals-data, curr-offset
585 var curr-trace-ah/eax: (addr handle trace) <- get curr-global, trace
586 copy-object trace-ah, curr-trace-ah
587 loop
588 }
589 }
590
591 fn render-image? _self: (addr global), cursor-in-definition?: boolean -> _/eax: boolean {
592 {
593 compare cursor-in-definition?, 0/false
594 break-if-=
595
596 return 0/false
597 }
598 var self/esi: (addr global) <- copy _self
599 var value-ah/eax: (addr handle cell) <- get self, value
600 var value/eax: (addr cell) <- lookup *value-ah
601 compare value, 0
602 {
603 break-if-!=
604
605 return 0/false
606 }
607 {
608 var pair?/eax: boolean <- pair? value
609 compare pair?, 0/false
610 break-if-!=
611
612 return 0/false
613 }
614 var first-ah/eax: (addr handle cell) <- get value, left
615 var first/eax: (addr cell) <- lookup *first-ah
616 var litimg?/eax: boolean <- litimg? first
617 return pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long *//*
* parser.c
*
* Copyright (C) 2012, 2013 James Booth <boothj5@gmail.com>
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdlib.h>
#include <string.h>
#include <glib.h>
/*
* Take a full line of input and return an array of strings representing
* the arguments of a command.
* If the number of arguments found is less than min, or more than max
* NULL is returned.
*
* inp - The