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