https://github.com/akkartik/mu/blob/main/apps/tile/data.mu
1 type sandbox {
2 setup: (handle line)
3 data: (handle line)
4
5 cursor-call-path: (handle call-path-element)
6 expanded-words: (handle call-path)
7 partial-name-for-cursor-word: (handle word)
8 partial-name-for-function: (handle word)
9
10 next: (handle sandbox)
11 prev: (handle sandbox)
12 }
13
14 type function {
15 name: (handle array byte)
16 args: (handle word)
17 body: (handle line)
18
19 next: (handle function)
20 }
21
22 type line {
23 name: (handle array byte)
24 data: (handle word)
25 result: (handle result)
26 next: (handle line)
27 prev: (handle line)
28 }
29
30 type word {
31 scalar-data: (handle gap-buffer)
32 next: (handle word)
33 prev: (handle word)
34 }
35
36
37 type value {
38 type: int
39 number-data: float
40 text-data: (handle array byte)
41 array-data: (handle array value)
42 file-data: (handle buffered-file)
43 filename: (handle array byte)
44 screen-data: (handle screen)
45 }
46
47 type table {
48 data: (handle array bind)
49 next: (handle table)
50 }
51
52 type bind {
53 key: (handle array byte)
54 value: (handle value)
55 }
56
57
58
59 type call-path {
60 data: (handle call-path-element)
61 next: (handle call-path)
62 }
63
64
65 type call-path-element {
66 word: (handle word)
67 next: (handle call-path-element)
68 }
69
70 type result {
71 data: value-stack
72 error: (handle array byte)
73 }
74
75 fn initialize-sandbox _sandbox: (addr sandbox) {
76 var sandbox/esi: (addr sandbox) <- copy _sandbox
77 var line-ah/eax: (addr handle line) <- get sandbox, data
78 allocate line-ah
79 var line/eax: (addr line) <- lookup *line-ah
80 initialize-line line
81 var word-ah/ecx: (addr handle word) <- get line, data
82 var cursor-call-path-ah/eax: (addr handle call-path-element) <- get sandbox, cursor-call-path
83 allocate cursor-call-path-ah
84 var cursor-call-path/eax: (addr call-path-element) <- lookup *cursor-call-path-ah
85 var dest/eax: (addr handle word) <- get cursor-call-path, word
86 copy-object word-ah, dest
87 }
88
89
90 fn initialize-line _line: (addr line) {
91 var line/esi: (addr line) <- copy _line
92 var word-ah/eax: (addr handle word) <- get line, data
93 allocate word-ah
94 var word/eax: (addr word) <- lookup *word-ah
95 initialize-word word
96 }
97
98 fn create-primitive-functions _self: (addr handle function) {
99
100 var self/esi: (addr handle function) <- copy _self
101 allocate self
102 var _f/eax: (addr function) <- lookup *self
103 var f/esi: (addr function) <- copy _f
104 var name-ah/eax: (addr handle array byte) <- get f, name
105 populate-text-with name-ah, "2*"
106 var args-ah/eax: (addr handle word) <- get f, args
107 allocate args-ah
108 var args/eax: (addr word) <- lookup *args-ah
109 initialize-word-with args, "x"
110 var body-ah/eax: (addr handle line) <- get f, body
111 allocate body-ah
112 var body/eax: (addr line) <- lookup *body-ah
113 initialize-line body
114 var curr-word-ah/ecx: (addr handle word) <- get body, data
115 parse-words "x 2 *", curr-word-ah
116
117 var next/esi: (addr handle function) <- get f, next
118 allocate next
119 var _f/eax: (addr function) <- lookup *next
120 var f/esi: (addr function) <- copy _f
121 var name-ah/eax: (addr handle array byte) <- get f, name
122 populate-text-with name-ah, "1+"
123 var args-ah/eax: (addr handle word) <- get f, args
124 allocate args-ah
125 var args/eax: (addr word) <- lookup *args-ah
126 initialize-word-with args, "x"
127 var body-ah/eax: (addr handle line) <- get f, body
128 allocate body-ah
129 var body/eax: (addr line) <- lookup *body-ah
130 initialize-line body
131 curr-word-ah <- get body, data
132 parse-words "x 1 +", curr-word-ah
133
134 var next/esi: (addr handle function) <- get f, next
135 allocate next
136 var _f/eax: (addr function) <- lookup *next
137 var f/esi: (addr function) <- copy _f
138 var name-ah/eax: (addr handle array byte) <- get f, name
139 populate-text-with name-ah, "2+"
140 var args-ah/eax: (addr handle word) <- get f, args
141 allocate args-ah
142 var args/eax: (addr word) <- lookup *args-ah
143 initialize-word-with args, "x"
144 var body-ah/eax: (addr handle line) <- get f, body
145 allocate body-ah
146 var body/eax: (addr line) <- lookup *body-ah
147 initialize-line body
148 curr-word-ah <- get body, data
149 parse-words "x 1+ 1+", curr-word-ah
150
151 var next/esi: (addr handle function) <- get f, next
152 allocate next
153 var _f/eax: (addr function) <- lookup *next
154 var f/esi: (addr function) <- copy _f
155 var name-ah/eax: (addr handle array byte) <- get f, name
156 populate-text-with name-ah, "square"
157 var args-ah/eax: (addr handle word) <- get f, args
158 allocate args-ah
159 var args/eax: (addr word) <- lookup *args-ah
160 initialize-word-with args, "x"
161 var body-ah/eax: (addr handle line) <- get f, body
162 allocate body-ah
163 var body/eax: (addr line) <- lookup *body-ah
164 initialize-line body
165 curr-word-ah <- get body, data
166 parse-words "x x *", curr-word-ah
167
168 var next/esi: (addr handle function) <- get f, next
169 allocate next
170 var _f/eax: (addr function) <- lookup *next
171 var f/esi: (addr function) <- copy _f
172 var name-ah/eax: (addr handle array byte) <- get f, name
173 populate-text-with name-ah, "1-"
174 var args-ah/eax: (addr handle word) <- get f, args
175 allocate args-ah
176 var args/eax: (addr word) <- lookup *args-ah
177 initialize-word-with args, "x"
178 var body-ah/eax: (addr handle line) <- get f, body
179 allocate body-ah
180 var body/eax: (addr line) <- lookup *body-ah
181 initialize-line body
182 curr-word-ah <- get body, data
183 parse-words "x 1 -", curr-word-ah
184
185 var next/esi: (addr handle function) <- get f, next
186 allocate next
187 var _f/eax: (addr function) <- lookup *next
188 var f/esi: (addr function) <- copy _f
189 var name-ah/eax: (addr handle array byte) <- get f, name
190 populate-text-with name-ah, "sub"
191
192 var args-ah/eax: (addr handle word) <- get f, args
193 allocate args-ah
194 var args/eax: (addr word) <- lookup *args-ah
195 initialize-word-with args, "y"
196 var next-arg-ah/eax: (addr handle word) <- get args, next
197 allocate next-arg-ah
198 var next-arg/eax: (addr word) <- lookup *next-arg-ah
199 initialize-word-with next-arg, "x"
200 var body-ah/eax: (addr handle line) <- get f, body
201 allocate body-ah
202 var body/eax: (addr line) <- lookup *body-ah
203 initialize-line body
204 curr-word-ah <- get body, data
205 parse-words "x y -", curr-word-ah
206 }
207
208 fn function-body functions: (addr handle function), _word: (addr handle word), out: (addr handle line) {
209 var function-name-storage: (handle array byte)
210 var function-name-ah/ecx: (addr handle array byte) <- address function-name-storage
211 var word-ah/esi: (addr handle word) <- copy _word
212 var word/eax: (addr word) <- lookup *word-ah
213 var gap-ah/eax: (addr handle gap-buffer) <- get word, scalar-data
214 var gap/eax: (addr gap-buffer) <- lookup *gap-ah
215 gap-buffer-to-string gap, function-name-ah
216 var _function-name/eax: (addr array byte) <- lookup *function-name-ah
217 var function-name/esi: (addr array byte) <- copy _function-name
218 var curr-ah/ecx: (addr handle function) <- copy functions
219 $function-body:loop: {
220 var _curr/eax: (addr function) <- lookup *curr-ah
221 var curr/edx: (addr function) <- copy _curr
222 compare curr, 0
223 break-if-=
224 var curr-name-ah/eax: (addr handle array byte) <- get curr, name
225 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
226 var found?/eax: boolean <- string-equal? curr-name, function-name
227 compare found?, 0
228 {
229 break-if-=
230 var src/eax: (addr handle line) <- get curr, body
231 copy-object src, out
232 break $function-body:loop
233 }
234 curr-ah <- get curr, next
235 loop
236 }
237 }
238
239 fn body-length functions: (addr handle function), function-name: (addr handle word) -> _/eax: int {
240 var body-storage: (handle line)
241 var body-ah/edi: (addr handle line) <- address body-storage
242 function-body functions, function-name, body-ah
243 var body/eax: (addr line) <- lookup *body-ah
244 var result/eax: int <- num-words-in-line body
245 return result
246 }
247
248 fn num-words-in-line _in: (addr line) -> _/eax: int {
249 var in/esi: (addr line) <- copy _in
250 var curr-ah/ecx: (addr handle word) <- get in, data
251 var result/edi: int <- copy 0
252 {
253 var curr/eax: (addr word) <- lookup *curr-ah
254 compare curr, 0
255 break-if-=
256 curr-ah <- get curr, next
257 result <- increment
258 loop
259 }
260 return result
261 }
262
263 fn populate-text-with _out: (addr handle array byte), _in: (addr array byte) {
264 var in/esi: (addr array byte) <- copy _in
265 var n/ecx: int <- length in
266 var out/edx: (addr handle array byte) <- copy _out
267 populate out, n
268 var _out-addr/eax: (addr array byte) <- lookup *out
269 var out-addr/edx: (addr array byte) <- copy _out-addr
270 var i/eax: int <- copy 0
271 {
272 compare i, n
273 break-if->=
274 var src/esi: (addr byte) <- index in, i
275 var val/ecx: byte <- copy-byte *src
276 var dest/edi: (addr byte) <- index out-addr, i
277 copy-byte-to *dest, val
278 i <- increment
279 loop
280 }
281 }
282
283 fn initialize-path-from-sandbox _in: (addr sandbox), _out: (addr handle call-path-element) {
284 var sandbox/esi: (addr sandbox) <- copy _in
285 var line-ah/eax: (addr handle line) <- get sandbox, data
286 var line/eax: (addr line) <- lookup *line-ah
287 var src/esi: (addr handle word) <- get line, data
288 var out-ah/edi: (addr handle call-path-element) <- copy _out
289 var out/eax: (addr call-path-element) <- lookup *out-ah
290 var dest/edi: (addr handle word) <- get out, word
291 copy-object src, dest
292 }
293
294 fn initialize-path-from-line _line: (addr line), _out: (addr handle call-path-element) {
295 var line/eax: (addr line) <- copy _line
296 var src/esi: (addr handle word) <- get line, data
297 var out-ah/edi: (addr handle call-path-element) <- copy _out
298 var out/eax: (addr call-path-element) <- lookup *out-ah
299 var dest/edi: (addr handle word) <- get out, word
300 copy-object src, dest
301 }
302
303 fn find-in-call-paths call-paths: (addr handle call-path), needle: (addr handle call-path-element) -> _/eax: boolean {
304 var curr-ah/esi: (addr handle call-path) <- copy call-paths
305 $find-in-call-path:loop: {
306 var curr/eax: (addr call-path) <- lookup *curr-ah
307 compare curr, 0
308 break-if-=
309 {
310 var curr-data/eax: (addr handle call-path-element) <- get curr, data
311 var match?/eax: boolean <- call-path-element-match? curr-data, needle
312 compare match?, 0
313 {
314 break-if-=
315 return 1
316 }
317 }
318 curr-ah <- get curr, next
319 loop
320 }
321 return 0
322 }
323
324 fn call-path-element-match? _x: (addr handle call-path-element), _y: (addr handle call-path-element) -> _/eax: boolean {
325 var x-ah/eax: (addr handle call-path-element) <- copy _x
326 var x-a/eax: (addr call-path-element) <- lookup *x-ah
327 var x/esi: (addr call-path-element) <- copy x-a
328 var y-ah/eax: (addr handle call-path-element) <- copy _y
329 var y-a/eax: (addr call-path-element) <- lookup *y-ah
330 var y/edi: (addr call-path-element) <- copy y-a
331 compare x, y
332 {
333 break-if-!=
334 return 1
335 }
336 compare x, 0
337 {
338 break-if-!=
339 return 0
340 }
341 compare y, 0
342 {
343 break-if-!=
344 return 0
345 }
346
347 var x-data-ah/ecx: (addr handle word) <- get x, word
348 var x-data-a/eax: (addr word) <- lookup *x-data-ah
349 var x-data/ecx: int <- copy x-data-a
350 var y-data-ah/eax: (addr handle word) <- get y, word
351 var y-data-a/eax: (addr word) <- lookup *y-data-ah
352 var y-data/eax: int <- copy y-data-a
353
354
355
356
357
358 compare x-data, y-data
359 {
360 break-if-=
361 return 0
362 }
363 var x-next/ecx: (addr handle call-path-element) <- get x, next
364 var y-next/eax: (addr handle call-path-element) <- get y, next
365 var result/eax: boolean <- call-path-element-match? x-next, y-next
366 return result
367 }
368
369
370 fn insert-in-call-path list: (addr handle call-path), new: (addr handle call-path-element) {
371 var new-path-storage: (handle call-path)
372 var new-path-ah/edi: (addr handle call-path) <- address new-path-storage
373 allocate new-path-ah
374 var new-path/eax: (addr call-path) <- lookup *new-path-ah
375 var next/ecx: (addr handle call-path) <- get new-path, next
376 copy-object list, next
377 var dest/ecx: (addr handle call-path-element) <- get new-path, data
378 deep-copy-call-path-element new, dest
379 copy-object new-path-ah, list
380 }
381
382
383 fn deep-copy-call-path-element _src: (addr handle call-path-element), _dest: (addr handle call-path-element) {
384 var src/esi: (addr handle call-path-element) <- copy _src
385
386 var _src-addr/eax: (addr call-path-element) <- lookup *src
387 compare _src-addr, 0
388 break-if-=
389
390 var src-addr/esi: (addr call-path-element) <- copy _src-addr
391 var dest/eax: (addr handle call-path-element) <- copy _dest
392 allocate dest
393
394 var dest-addr/eax: (addr call-path-element) <- lookup *dest
395 {
396 var dest-data-addr/ecx: (addr handle word) <- get dest-addr, word
397 var src-data-addr/eax: (addr handle word) <- get src-addr, word
398 copy-object src-data-addr, dest-data-addr
399 }
400
401 var src-next/esi: (addr handle call-path-element) <- get src-addr, next
402 var dest-next/eax: (addr handle call-path-element) <- get dest-addr, next
403 deep-copy-call-path-element src-next, dest-next
404 }
405
406 fn delete-in-call-path list: (addr handle call-path), needle: (addr handle call-path-element) {
407 var curr-ah/esi: (addr handle call-path) <- copy list
408 $delete-in-call-path:loop: {
409 var _curr/eax: (addr call-path) <- lookup *curr-ah
410 var curr/ecx: (addr call-path) <- copy _curr
411 compare curr, 0
412 break-if-=
413 {
414 var curr-data/eax: (addr handle call-path-element) <- get curr, data
415 var match?/eax: boolean <- call-path-element-match? curr-data, needle
416 compare match?, 0
417 {
418 break-if-=
419 var next-ah/ecx: (addr handle call-path) <- get curr, next
420 copy-object next-ah, curr-ah
421 loop $delete-in-call-path:loop
422 }
423 }
424 curr-ah <- get curr, next
425 loop
426 }
427 }
428
429 fn increment-final-element list: (addr handle call-path-element) {
430 var final-ah/eax: (addr handle call-path-element) <- copy list
431 var final/eax: (addr call-path-element) <- lookup *final-ah
432 var val-ah/ecx: (addr handle word) <- get final, word
433 var val/eax: (addr word) <- lookup *val-ah
434 var new-ah/edx: (addr handle word) <- get val, next
435 var target/eax: (addr word) <- lookup *new-ah
436 compare target, 0
437 break-if-=
438 copy-object new-ah, val-ah
439 }
440
441 fn decrement-final-element list: (addr handle call-path-element) {
442 var final-ah/eax: (addr handle call-path-element) <- copy list
443 var final/eax: (addr call-path-element) <- lookup *final-ah
444 var val-ah/ecx: (addr handle word) <- get final, word
445 var val/eax: (addr word) <- lookup *val-ah
446
447
448
449
450
451 var new-ah/edx: (addr handle word) <- get val, prev
452 var target/eax: (addr word) <- lookup *new-ah
453 compare target, 0
454 break-if-=
455
456
457
458
459
460
461
462 copy-object new-ah, val-ah
463 }
464
465 fn move-final-element-to-start-of-line list: (addr handle call-path-element) {
466 var final-ah/eax: (addr handle call-path-element) <- copy list
467 var final/eax: (addr call-path-element) <- lookup *final-ah
468 var val-ah/ecx: (addr handle word) <- get final, word
469 var val/eax: (addr word) <- lookup *val-ah
470 var new-ah/edx: (addr handle word) <- get val, prev
471 var target/eax: (addr word) <- lookup *new-ah
472 compare target, 0
473 break-if-=
474 copy-object new-ah, val-ah
475 move-final-element-to-start-of-line list
476 }
477
478 fn move-final-element-to-end-of-line list: (addr handle call-path-element) {
479 var final-ah/eax: (addr handle call-path-element) <- copy list
480 var final/eax: (addr call-path-element) <- lookup *final-ah
481 var val-ah/ecx: (addr handle word) <- get final, word
482 var val/eax: (addr word) <- lookup *val-ah
483 var new-ah/edx: (addr handle word) <- get val, next
484 var target/eax: (addr word) <- lookup *new-ah
485 compare target, 0
486 break-if-=
487 copy-object new-ah, val-ah
488 move-final-element-to-end-of-line list
489 }
490
491 fn push-to-call-path-element list: (addr handle call-path-element), new: (addr handle word) {
492 var new-element-storage: (handle call-path-element)
493 var new-element-ah/edi: (addr handle call-path-element) <- address new-element-storage
494 allocate new-element-ah
495 var new-element/eax: (addr call-path-element) <- lookup *new-element-ah
496
497 var dest/ecx: (addr handle word) <- get new-element, word
498 copy-object new, dest
499
500 var dest2/ecx: (addr handle call-path-element) <- get new-element, next
501 copy-object list, dest2
502
503 copy-object new-element-ah, list
504 }
505
506 fn drop-from-call-path-element _list: (addr handle call-path-element) {
507 var list-ah/esi: (addr handle call-path-element) <- copy _list
508 var list/eax: (addr call-path-element) <- lookup *list-ah
509 var next/eax: (addr handle call-path-element) <- get list, next
510 copy-object next, _list
511 }
512
513 fn drop-nested-calls _list: (addr handle call-path-element) {
514 var list-ah/esi: (addr handle call-path-element) <- copy _list
515 var list/eax: (addr call-path-element) <- lookup *list-ah
516 var next-ah/edi: (addr handle call-path-element) <- get list, next
517 var next/eax: (addr call-path-element) <- lookup *next-ah
518 compare next, 0
519 break-if-=
520 copy-object next-ah, _list
521 drop-nested-calls _list
522 }
523
524 fn dump-call-path-element screen: (addr screen), _x-ah: (addr handle call-path-element) {
525 var x-ah/ecx: (addr handle call-path-element) <- copy _x-ah
526 var _x/eax: (addr call-path-element) <- lookup *x-ah
527 var x/esi: (addr call-path-element) <- copy _x
528 var word-ah/eax: (addr handle word) <- get x, word
529 var word/eax: (addr word) <- lookup *word-ah
530 print-word screen, word
531 var next-ah/ecx: (addr handle call-path-element) <- get x, next
532 var next/eax: (addr call-path-element) <- lookup *next-ah
533 compare next, 0
534 {
535 break-if-=
536 print-string screen, " "
537 dump-call-path-element screen, next-ah
538 return
539 }
540 print-string screen, "\n"
541 }
542
543 fn dump-call-paths screen: (addr screen), _x-ah: (addr handle call-path) {
544 var x-ah/ecx: (addr handle call-path) <- copy _x-ah
545 var x/eax: (addr call-path) <- lookup *x-ah
546 compare x, 0
547 break-if-=
548 var src/ecx: (addr handle call-path-element) <- get x, data
549 dump-call-path-element screen, src
550 var next-ah/ecx: (addr handle call-path) <- get x, next
551 var next/eax: (addr call-path) <- lookup *next-ah
552 compare next, 0
553 {
554 break-if-=
555 dump-call-paths screen, next-ah
556 }
557 }
558
559 fn function-width _self: (addr function) -> _/eax: int {
560 var self/esi: (addr function) <- copy _self
561 var args/ecx: (addr handle word) <- get self, args
562 var arg-width/eax: int <- word-list-length args
563 var result/edi: int <- copy arg-width
564 result <- add 4
565 var body-ah/eax: (addr handle line) <- get self, body
566 var body-width/eax: int <- body-width body-ah
567 body-width <- add 1
568 body-width <- add 2
569 compare result, body-width
570 {
571 break-if->=
572 result <- copy body-width
573 }
574 return result
575 }
576
577 fn body-width lines: (addr handle line) -> _/eax: int {
578 var curr-ah/esi: (addr handle line) <- copy lines
579 var result/edi: int <- copy 0
580 {
581 var curr/eax: (addr line) <- lookup *curr-ah
582 compare curr, 0
583 break-if-=
584 {
585 var words/ecx: (addr handle word) <- get curr, data
586 var curr-len/eax: int <- word-list-length words
587 compare curr-len, result
588 break-if-<=
589 result <- copy curr-len
590 }
591 curr-ah <- get curr, next
592 loop
593 }
594 return result
595 }
596
597 fn function-height _self: (addr function) -> _/eax: int {
598 var self/esi: (addr function) <- copy _self
599 var body-ah/eax: (addr handle line) <- get self, body
600 var result/eax: int <- line-list-length body-ah
601 result <- increment
602 return result
603 }
604
605 fn line-list-length lines: (addr handle line) -> _/eax: int {
606 var curr-ah/esi: (addr handle line) <- copy lines
607 var result/edi: int <- copy 0
608 {
609 var curr/eax: (addr line) <- lookup *curr-ah
610 compare curr, 0
611 break-if-=
612 curr-ah <- get curr, next
613 result <- increment
614 loop
615 }
616 return result
617 }