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