https://github.com/akkartik/mu/blob/master/apps/tile/rpn.mu
1 fn evaluate functions: (addr handle function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr value-stack) {
2 var line/eax: (addr line) <- copy scratch
3 var word-ah/eax: (addr handle word) <- get line, data
4 var curr/eax: (addr word) <- lookup *word-ah
5 var curr-stream-storage: (stream byte 0x10)
6 var curr-stream/edi: (addr stream byte) <- address curr-stream-storage
7 clear-value-stack out
8 $evaluate:loop: {
9
10 compare curr, 0
11 break-if-=
12
13 emit-word curr, curr-stream
14
15
16
17 $evaluate:process-word: {
18
19
20 {
21 var is-add?/eax: boolean <- stream-data-equal? curr-stream, "+"
22 compare is-add?, 0
23 break-if-=
24 var _b/eax: int <- pop-int-from-value-stack out
25 var b/edx: int <- copy _b
26 var a/eax: int <- pop-int-from-value-stack out
27 a <- add b
28 push-int-to-value-stack out, a
29 break $evaluate:process-word
30 }
31 {
32 var is-sub?/eax: boolean <- stream-data-equal? curr-stream, "-"
33 compare is-sub?, 0
34 break-if-=
35 var _b/eax: int <- pop-int-from-value-stack out
36 var b/edx: int <- copy _b
37 var a/eax: int <- pop-int-from-value-stack out
38 a <- subtract b
39 push-int-to-value-stack out, a
40 break $evaluate:process-word
41 }
42 {
43 var is-mul?/eax: boolean <- stream-data-equal? curr-stream, "*"
44 compare is-mul?, 0
45 break-if-=
46 var _b/eax: int <- pop-int-from-value-stack out
47 var b/edx: int <- copy _b
48 var a/eax: int <- pop-int-from-value-stack out
49 a <- multiply b
50 push-int-to-value-stack out, a
51 break $evaluate:process-word
52 }
53
54 {
55 var is-len?/eax: boolean <- stream-data-equal? curr-stream, "len"
56 compare is-len?, 0
57 break-if-=
58
59
60 var out2/esi: (addr value-stack) <- copy out
61 var top-addr/ecx: (addr int) <- get out2, top
62 compare *top-addr, 0
63 break-if-<=
64
65 var data-ah/eax: (addr handle array value) <- get out2, data
66 var data/eax: (addr array value) <- lookup *data-ah
67 var top/edx: int <- copy *top-addr
68 top <- decrement
69 var dest-offset/edx: (offset value) <- compute-offset data, top
70 var target-val/edx: (addr value) <- index data, dest-offset
71
72 var target-type-addr/eax: (addr int) <- get target-val, type
73 compare *target-type-addr, 1
74 {
75 break-if-!=
76
77 var src-ah/eax: (addr handle array byte) <- get target-val, text-data
78 var src/eax: (addr array byte) <- lookup *src-ah
79 var result/ebx: int <- length src
80
81 var type-addr/eax: (addr int) <- get target-val, type
82 copy-to *type-addr, 0
83 var target-string-ah/eax: (addr handle array byte) <- get target-val, text-data
84 clear-object target-string-ah
85 var target/eax: (addr int) <- get target-val, int-data
86 copy-to *target, result
87 break $evaluate:process-word
88 }
89 compare *target-type-addr, 2
90 {
91 break-if-!=
92
93 var src-ah/eax: (addr handle array value) <- get target-val, array-data
94 var src/eax: (addr array value) <- lookup *src-ah
95 var result/ebx: int <- length src
96
97 var type-addr/eax: (addr int) <- get target-val, type
98 copy-to *type-addr, 0
99 var target-array-ah/eax: (addr handle array value) <- get target-val, array-data
100 clear-object target-array-ah
101 var target/eax: (addr int) <- get target-val, int-data
102 copy-to *target, result
103 break $evaluate:process-word
104 }
105 }
106
107 {
108 var is-open?/eax: boolean <- stream-data-equal? curr-stream, "open"
109 compare is-open?, 0
110 break-if-=
111
112 var out2/esi: (addr value-stack) <- copy out
113 var top-addr/ecx: (addr int) <- get out2, top
114 compare *top-addr, 0
115 break-if-<=
116 var data-ah/eax: (addr handle array value) <- get out2, data
117 var data/eax: (addr array value) <- lookup *data-ah
118 var top/edx: int <- copy *top-addr
119 top <- decrement
120 var dest-offset/edx: (offset value) <- compute-offset data, top
121 var target-val/edx: (addr value) <- index data, dest-offset
122
123 var target-type-addr/eax: (addr int) <- get target-val, type
124 compare *target-type-addr, 1
125 break-if-!=
126
127 var src-ah/eax: (addr handle array byte) <- get target-val, text-data
128 var src/eax: (addr array byte) <- lookup *src-ah
129 var result-ah/ecx: (addr handle buffered-file) <- get target-val, file-data
130 open src, 0, result-ah
131
132 var type-addr/eax: (addr int) <- get target-val, type
133 copy-to *type-addr, 3
134 var target-string-ah/eax: (addr handle array byte) <- get target-val, text-data
135 var filename-ah/ecx: (addr handle array byte) <- get target-val, filename
136 copy-object target-string-ah, filename-ah
137 clear-object target-string-ah
138 break $evaluate:process-word
139 }
140 {
141 var is-read?/eax: boolean <- stream-data-equal? curr-stream, "read"
142 compare is-read?, 0
143 break-if-=
144
145 var out2/esi: (addr value-stack) <- copy out
146 var top-addr/ecx: (addr int) <- get out2, top
147 compare *top-addr, 0
148 break-if-<=
149 var data-ah/eax: (addr handle array value) <- get out2, data
150 var data/eax: (addr array value) <- lookup *data-ah
151 var top/edx: int <- copy *top-addr
152 top <- decrement
153 var dest-offset/edx: (offset value) <- compute-offset data, top
154 var target-val/edx: (addr value) <- index data, dest-offset
155
156 var target-type-addr/eax: (addr int) <- get target-val, type
157 compare *target-type-addr, 3
158 break-if-!=
159
160
161 var file-ah/eax: (addr handle buffered-file) <- get target-val, file-data
162 var file/eax: (addr buffered-file) <- lookup *file-ah
163 var s: (stream byte 0x100)
164 var s-addr/ecx: (addr stream byte) <- address s
165 read-line-buffered file, s-addr
166 var target/eax: (addr handle array byte) <- get target-val, text-data
167 stream-to-array s-addr, target
168
169 var type-addr/eax: (addr int) <- get target-val, type
170 copy-to *type-addr, 1
171 var target-file-ah/eax: (addr handle buffered-file) <- get target-val, file-data
172 clear-object target-file-ah
173 break $evaluate:process-word
174 }
175 {
176 var is-slurp?/eax: boolean <- stream-data-equal? curr-stream, "slurp"
177 compare is-slurp?, 0
178 break-if-=
179
180 var out2/esi: (addr value-stack) <- copy out
181 var top-addr/ecx: (addr int) <- get out2, top
182 compare *top-addr, 0
183 break-if-<=
184 var data-ah/eax: (addr handle array value) <- get out2, data
185 var data/eax: (addr array value) <- lookup *data-ah
186 var top/edx: int <- copy *top-addr
187 top <- decrement
188 var dest-offset/edx: (offset value) <- compute-offset data, top
189 var target-val/edx: (addr value) <- index data, dest-offset
190
191 var target-type-addr/eax: (addr int) <- get target-val, type
192 compare *target-type-addr, 3
193 break-if-!=
194
195
196 var file-ah/eax: (addr handle buffered-file) <- get target-val, file-data
197 var file/eax: (addr buffered-file) <- lookup *file-ah
198 var s: (stream byte 0x100)
199 var s-addr/ecx: (addr stream byte) <- address s
200 slurp file, s-addr
201 var target/eax: (addr handle array byte) <- get target-val, text-data
202 stream-to-array s-addr, target
203
204 var type-addr/eax: (addr int) <- get target-val, type
205 copy-to *type-addr, 1
206 var target-file-ah/eax: (addr handle buffered-file) <- get target-val, file-data
207 clear-object target-file-ah
208 break $evaluate:process-word
209 }
210 {
211 var is-lines?/eax: boolean <- stream-data-equal? curr-stream, "lines"
212 compare is-lines?, 0
213 break-if-=
214
215 var out2/esi: (addr value-stack) <- copy out
216 var top-addr/ecx: (addr int) <- get out2, top
217 compare *top-addr, 0
218 break-if-<=
219 var data-ah/eax: (addr handle array value) <- get out2, data
220 var data/eax: (addr array value) <- lookup *data-ah
221 var top/edx: int <- copy *top-addr
222 top <- decrement
223 var dest-offset/edx: (offset value) <- compute-offset data, top
224 var target-val/edx: (addr value) <- index data, dest-offset
225
226 var target-type-addr/eax: (addr int) <- get target-val, type
227 compare *target-type-addr, 3
228 break-if-!=
229
230
231 var file-ah/eax: (addr handle buffered-file) <- get target-val, file-data
232 var file/eax: (addr buffered-file) <- lookup *file-ah
233 var s: (stream byte 0x100)
234 var s-addr/ecx: (addr stream byte) <- address s
235 slurp file, s-addr
236 var tmp-ah/eax: (addr handle array byte) <- get target-val, text-data
237 stream-to-array s-addr, tmp-ah
238 var tmp/eax: (addr array byte) <- lookup *tmp-ah
239
240
241 var h: (handle array (handle array byte))
242 {
243 var ah/edx: (addr handle array (handle array byte)) <- address h
244 split-string tmp, 0xa, ah
245 }
246 var target/eax: (addr handle array value) <- get target-val, array-data
247 save-lines h, target
248
249 var type-addr/eax: (addr int) <- get target-val, type
250 copy-to *type-addr, 2
251 var target-file-ah/eax: (addr handle buffered-file) <- get target-val, file-data
252 var empty-file: (handle buffered-file)
253 copy-handle empty-file, target-file-ah
254 var target-text-ah/eax: (addr handle array byte) <- get target-val, text-data
255 var empty-text: (handle array byte)
256 copy-handle empty-text, target-text-ah
257 break $evaluate:process-word
258 }
259
260 {
261 var is-fake-screen?/eax: boolean <- stream-data-equal? curr-stream, "fake-screen"
262 compare is-fake-screen?, 0
263 break-if-=
264 var out2/esi: (addr value-stack) <- copy out
265 var top-addr/ecx: (addr int) <- get out2, top
266 compare *top-addr, 0
267 break-if-<=
268
269 var _nrows/eax: int <- pop-int-from-value-stack out2
270 var nrows/edx: int <- copy _nrows
271 var _ncols/eax: int <- pop-int-from-value-stack out2
272 var ncols/ebx: int <- copy _ncols
273
274 var screen-h: (handle screen)
275 var screen-ah/eax: (addr handle screen) <- address screen-h
276 allocate screen-ah
277 var screen/eax: (addr screen) <- lookup screen-h
278 initialize-screen screen, nrows, ncols
279
280 var data-ah/eax: (addr handle array value) <- get out2, data
281 var data/eax: (addr array value) <- lookup *data-ah
282 var top/edx: int <- copy *top-addr
283 increment *top-addr
284 var dest-offset/edx: (offset value) <- compute-offset data, top
285 var target-val/edx: (addr value) <- index data, dest-offset
286 var type/eax: (addr int) <- get target-val, type
287 copy-to *type, 4
288 var dest/eax: (addr handle screen) <- get target-val, screen-data
289 copy-handle screen-h, dest
290 break $evaluate:process-word
291 }
292 {
293 var is-print?/eax: boolean <- stream-data-equal? curr-stream, "print"
294 compare is-print?, 0
295 break-if-=
296 var out2/esi: (addr value-stack) <- copy out
297 var top-addr/ecx: (addr int) <- get out2, top
298 compare *top-addr, 0
299 break-if-<=
300
301 var top-addr/ecx: (addr int) <- get out2, top
302 compare *top-addr, 0
303 break-if-<=
304 decrement *top-addr
305 var data-ah/eax: (addr handle array value) <- get out2, data
306 var _data/eax: (addr array value) <- lookup *data-ah
307 var data/edi: (addr array value) <- copy _data
308 var top/eax: int <- copy *top-addr
309 var dest-offset/edx: (offset value) <- compute-offset data, top
310 var s/esi: (addr value) <- index data, dest-offset
311
312 compare *top-addr, 0
313 break-if-<=
314 var top/eax: int <- copy *top-addr
315 top <- decrement
316 var dest-offset/edx: (offset value) <- compute-offset data, top
317 var target-val/edx: (addr value) <- index data, dest-offset
318 var type/eax: (addr int) <- get target-val, type
319 compare *type, 4
320 break-if-!=
321
322 var dest-ah/eax: (addr handle screen) <- get target-val, screen-data
323 var dest/eax: (addr screen) <- lookup *dest-ah
324 var r/ecx: (addr int) <- get dest, cursor-row
325 var c/edx: (addr int) <- get dest, cursor-col
326 render-value-at dest, *r, *c, s, 0
327 break $evaluate:process-word
328 }
329 {
330 var is-move?/eax: boolean <- stream-data-equal? curr-stream, "move"
331 compare is-move?, 0
332 break-if-=
333 var out2/esi: (addr value-stack) <- copy out
334
335 var _r/eax: int <- pop-int-from-value-stack out2
336 var r/ecx: int <- copy _r
337 var _c/eax: int <- pop-int-from-value-stack out2
338 var c/edx: int <- copy _c
339
340 var top-addr/ebx: (addr int) <- get out2, top
341 compare *top-addr, 0
342 break-if-<=
343 var data-ah/eax: (addr handle array value) <- get out2, data
344 var _data/eax: (addr array value) <- lookup *data-ah
345 var data/edi: (addr array value) <- copy _data
346 var top/eax: int <- copy *top-addr
347 top <- decrement
348 var target-offset/eax: (offset value) <- compute-offset data, top
349 var target-val/ebx: (addr value) <- index data, target-offset
350 var type/eax: (addr int) <- get target-val, type
351 compare *type, 4
352 break-if-!=
353 var target-ah/eax: (addr handle screen) <- get target-val, screen-data
354 var target/eax: (addr screen) <- lookup *target-ah
355 move-cursor target, r, c
356 break $evaluate:process-word
357 }
358 {
359 var is-up?/eax: boolean <- stream-data-equal? curr-stream, "up"
360 compare is-up?, 0
361 break-if-=
362 var out2/esi: (addr value-stack) <- copy out
363 var top-addr/ebx: (addr int) <- get out2, top
364 compare *top-addr, 0
365 break-if-<=
366
367 var _d/eax: int <- pop-int-from-value-stack out2
368 var d/ecx: int <- copy _d
369
370 compare *top-addr, 0
371 break-if-<=
372 var data-ah/eax: (addr handle array value) <- get out2, data
373 var _data/eax: (addr array value) <- lookup *data-ah
374 var data/edi: (addr array value) <- copy _data
375 var top/eax: int <- copy *top-addr
376 top <- decrement
377 var target-offset/eax: (offset value) <- compute-offset data, top
378 var target-val/ebx: (addr value) <- index data, target-offset
379 var type/eax: (addr int) <- get target-val, type
380 compare *type, 4
381 break-if-!=
382 var target-ah/eax: (addr handle screen) <- get target-val, screen-data
383 var _target/eax: (addr screen) <- lookup *target-ah
384 var target/edi: (addr screen) <- copy _target
385 var r/edx: (addr int) <- get target, cursor-row
386 var c/eax: (addr int) <- get target, cursor-col
387 var col/eax: int <- copy *c
388 {
389 compare d, 0
390 break-if-<=
391 compare *r, 1
392 break-if-<=
393 print-string target "│"
394 decrement *r
395 move-cursor target, *r, col
396 d <- decrement
397 loop
398 }
399 break $evaluate:process-word
400 }
401 {
402 var is-down?/eax: boolean <- stream-data-equal? curr-stream, "down"
403 compare is-down?, 0
404 break-if-=
405 var out2/esi: (addr value-stack) <- copy out
406 var top-addr/ebx: (addr int) <- get out2, top
407 compare *top-addr, 0
408 break-if-<=
409
410 var _d/eax: int <- pop-int-from-value-stack out2
411 var d/ecx: int <- copy _d
412
413 compare *top-addr, 0
414 break-if-<=
415 var data-ah/eax: (addr handle array value) <- get out2, data
416 var _data/eax: (addr array value) <- lookup *data-ah
417 var data/edi: (addr array value) <- copy _data
418 var top/eax: int <- copy *top-addr
419 top <- decrement
420 var target-offset/eax: (offset value) <- compute-offset data, top
421 var target-val/ebx: (addr value) <- index data, target-offset
422 var type/eax: (addr int) <- get target-val, type
423 compare *type, 4
424 break-if-!=
425 var target-ah/eax: (addr handle screen) <- get target-val, screen-data
426 var _target/eax: (addr screen) <- lookup *target-ah
427 var target/edi: (addr screen) <- copy _target
428 var bound-a/ebx: (addr int) <- get target, num-rows
429 var bound/ebx: int <- copy *bound-a
430 var r/edx: (addr int) <- get target, cursor-row
431 var c/eax: (addr int) <- get target, cursor-col
432 var col/eax: int <- copy *c
433 {
434 compare d, 0
435 break-if-<=
436 compare *r, bound
437 break-if->=
438 print-string target "│"
439 increment *r
440 move-cursor target, *r, col
441 d <- decrement
442 loop
443 }
444 break $evaluate:process-word
445 }
446 {
447 var is-left?/eax: boolean <- stream-data-equal? curr-stream, "left"
448 compare is-left?, 0
449 break-if-=
450 var out2/esi: (addr value-stack) <- copy out
451 var top-addr/ebx: (addr int) <- get out2, top
452 compare *top-addr, 0
453 break-if-<=
454
455 var _d/eax: int <- pop-int-from-value-stack out2
456 var d/ecx: int <- copy _d
457
458 compare *top-addr, 0
459 break-if-<=
460 var data-ah/eax: (addr handle array value) <- get out2, data
461 var _data/eax: (addr array value) <- lookup *data-ah
462 var data/edi: (addr array value) <- copy _data
463 var top/eax: int <- copy *top-addr
464 top <- decrement
465 var target-offset/eax: (offset value) <- compute-offset data, top
466 var target-val/ebx: (addr value) <- index data, target-offset
467 var type/eax: (addr int) <- get target-val, type
468 compare *type, 4
469 break-if-!=
470 var target-ah/eax: (addr handle screen) <- get target-val, screen-data
471 var _target/eax: (addr screen) <- lookup *target-ah
472 var target/edi: (addr screen) <- copy _target
473 var c/edx: (addr int) <- get target, cursor-col
474 var r/eax: (addr int) <- get target, cursor-row
475 var row/eax: int <- copy *r
476 {
477 compare d, 0
478 break-if-<=
479 compare *c, 1
480 break-if-<=
481 print-string target "─"
482 decrement *c
483 decrement *c
484 move-cursor target, row, *c
485 d <- decrement
486 loop
487 }
488 break $evaluate:process-word
489 }
490 {
491 var is-right?/eax: boolean <- stream-data-equal? curr-stream, "right"
492 compare is-right?, 0
493 break-if-=
494 var out2/esi: (addr value-stack) <- copy out
495 var top-addr/ebx: (addr int) <- get out2, top
496 compare *top-addr, 0
497 break-if-<=
498
499 var _d/eax: int <- pop-int-from-value-stack out2
500 var d/ecx: int <- copy _d
501
502 compare *top-addr, 0
503 break-if-<=
504 var data-ah/eax: (addr handle array value) <- get out2, data
505 var _data/eax: (addr array value) <- lookup *data-ah
506 var data/edi: (addr array value) <- copy _data
507 var top/eax: int <- copy *top-addr
508 top <- decrement
509 var target-offset/eax: (offset value) <- compute-offset data, top
510 var target-val/ebx: (addr value) <- index data, target-offset
511 var type/eax: (addr int) <- get target-val, type
512 compare *type, 4
513 break-if-!=
514 var target-ah/eax: (addr handle screen) <- get target-val, screen-data
515 var _target/eax: (addr screen) <- lookup *target-ah
516 var target/edi: (addr screen) <- copy _target
517 var bound-a/ebx: (addr int) <- get target, num-rows
518 var bound/ebx: int <- copy *bound-a
519 var c/edx: (addr int) <- get target, cursor-col
520 var r/eax: (addr int) <- get target, cursor-row
521 var row/eax: int <- copy *r
522 {
523 compare d, 0
524 break-if-<=
525 compare *c, bound
526 break-if->=
527 print-string target "─"
528
529 move-cursor target, row, *c
530 d <- decrement
531 loop
532 }
533 break $evaluate:process-word
534 }
535
536 {
537 var is-dup?/eax: boolean <- stream-data-equal? curr-stream, "dup"
538 compare is-dup?, 0
539 break-if-=
540
541 var out2/esi: (addr value-stack) <- copy out
542 var top-addr/ecx: (addr int) <- get out2, top
543 compare *top-addr, 0
544 break-if-<=
545 var data-ah/eax: (addr handle array value) <- get out2, data
546 var data/eax: (addr array value) <- lookup *data-ah
547 var top/ecx: int <- copy *top-addr
548 top <- decrement
549 var offset/edx: (offset value) <- compute-offset data, top
550 var src-val/edx: (addr value) <- index data, offset
551
552 top <- increment
553 var offset/ebx: (offset value) <- compute-offset data, top
554 var target-val/ebx: (addr value) <- index data, offset
555 copy-object src-val, target-val
556
557 var top-addr/ecx: (addr int) <- get out2, top
558 increment *top-addr
559 break $evaluate:process-word
560 }
561 {
562 var is-swap?/eax: boolean <- stream-data-equal? curr-stream, "swap"
563 compare is-swap?, 0
564 break-if-=
565
566 var out2/esi: (addr value-stack) <- copy out
567 var top-addr/ecx: (addr int) <- get out2, top
568 compare *top-addr, 0
569 break-if-<=
570 var data-ah/eax: (addr handle array value) <- get out2, data
571 var data/eax: (addr array value) <- lookup *data-ah
572 var top/ecx: int <- copy *top-addr
573 top <- decrement
574 var offset/edx: (offset value) <- compute-offset data, top
575 var top-val/edx: (addr value) <- index data, offset
576
577 top <- decrement
578 var offset/ebx: (offset value) <- compute-offset data, top
579 var pen-top-val/ebx: (addr value) <- index data, offset
580
581 var tmp: value
582 var tmp-a/eax: (addr value) <- address tmp
583 copy-object top-val, tmp-a
584 copy-object pen-top-val, top-val
585 copy-object tmp-a, pen-top-val
586 break $evaluate:process-word
587 }
588
589 {
590 var done?/eax: boolean <- stream-empty? curr-stream
591 compare done?, 0
592 break-if-!=
593 var new-byte/eax: byte <- read-byte curr-stream
594 compare new-byte, 0x3d
595 break-if-!=
596
597 var out2/esi: (addr value-stack) <- copy out
598 var top-addr/ecx: (addr int) <- get out2, top
599 compare *top-addr, 0
600 break-if-<=
601 var data-ah/eax: (addr handle array value) <- get out2, data
602 var data/eax: (addr array value) <- lookup *data-ah
603 var top/edx: int <- copy *top-addr
604 top <- decrement
605 var dest-offset/edx: (offset value) <- compute-offset data, top
606 var target-val/edx: (addr value) <- index data, dest-offset
607
608 var key-h: (handle array byte)
609 var key/ecx: (addr handle array byte) <- address key-h
610 stream-to-array curr-stream, key
611 bind-in-table bindings, key, target-val
612 break $evaluate:process-word
613 }
614 rewind-stream curr-stream
615
616 {
617 var callee-h: (handle function)
618 var callee-ah/eax: (addr handle function) <- address callee-h
619 find-function functions, curr-stream, callee-ah
620 var callee/eax: (addr function) <- lookup *callee-ah
621 compare callee, 0
622 break-if-=
623 perform-call callee, out, functions
624 break $evaluate:process-word
625 }
626
627 {
628 compare bindings, 0
629 break-if-=
630 var tmp: (handle array byte)
631 var curr-string-ah/edx: (addr handle array byte) <- address tmp
632 stream-to-array curr-stream, curr-string-ah
633 var curr-string/eax: (addr array byte) <- lookup *curr-string-ah
634 var val-storage: (handle value)
635 var val-ah/edi: (addr handle value) <- address val-storage
636 lookup-binding bindings, curr-string, val-ah
637 var val/eax: (addr value) <- lookup *val-ah
638 compare val, 0
639 break-if-=
640 push-value-stack out, val
641 break $evaluate:process-word
642 }
643
644 {
645 var start/eax: byte <- stream-first curr-stream
646 compare start, 0x22
647 break-if-!=
648 var end/eax: byte <- stream-final curr-stream
649 compare end, 0x22
650 break-if-!=
651 var h: (handle array byte)
652 var s/eax: (addr handle array byte) <- address h
653 unquote-stream-to-array curr-stream, s
654 push-string-to-value-stack out, *s
655 break $evaluate:process-word
656 }
657
658 {
659 var start/eax: byte <- stream-first curr-stream
660 compare start, 0x5b
661 break-if-!=
662 var end/eax: byte <- stream-final curr-stream
663 compare end, 0x5d
664 break-if-!=
665
666 var h: (handle array value)
667 var input-ah/eax: (addr handle array byte) <- address h
668 unquote-stream-to-array curr-stream, input-ah
669
670
671 var input/eax: (addr array byte) <- lookup *input-ah
672 var h2: (handle array int)
673 var int-array-ah/esi: (addr handle array int) <- address h2
674 parse-array-of-decimal-ints input, int-array-ah
675 var _int-array/eax: (addr array int) <- lookup *int-array-ah
676 var int-array/esi: (addr array int) <- copy _int-array
677 var len/ebx: int <- length int-array
678
679 var h3: (handle array value)
680 var value-array-ah/eax: (addr handle array value) <- address h3
681 populate value-array-ah, len
682 push-array-to-value-stack out, *value-array-ah
683
684 var _value-array/eax: (addr array value) <- lookup *value-array-ah
685 var value-array/edi: (addr array value) <- copy _value-array
686 var i/eax: int <- copy 0
687 {
688 compare i, len
689 break-if->=
690 var src-addr/ecx: (addr int) <- index int-array, i
691 var src/ecx: int <- copy *src-addr
692 var dest-offset/edx: (offset value) <- compute-offset value-array, i
693 var dest-val/edx: (addr value) <- index value-array, dest-offset
694 var dest/edx: (addr int) <- get dest-val, int-data
695 copy-to *dest, src
696 i <- increment
697 loop
698 }
699 break $evaluate:process-word
700 }
701
702 {
703 var n/eax: int <- parse-decimal-int-from-stream curr-stream
704 push-int-to-value-stack out, n
705 }
706 }
707
708 compare curr, end
709 break-if-=
710
711 var next-word-ah/edx: (addr handle word) <- get curr, next
712 curr <- lookup *next-word-ah
713
714 loop
715 }
716
717 var line/eax: (addr line) <- copy scratch
718 var next-line-ah/eax: (addr handle line) <- get line, next
719 var next-line/eax: (addr line) <- lookup *next-line-ah
720 compare next-line, 0
721 break-if-=
722 evaluate functions, bindings, next-line, end, out
723 }
724
725 fn test-evaluate {
726 var line-storage: line
727 var line/esi: (addr line) <- address line-storage
728 var first-word-ah/eax: (addr handle word) <- get line-storage, data
729 allocate-word-with first-word-ah, "3"
730 append-word-with *first-word-ah, "=a"
731 var next-line-ah/eax: (addr handle line) <- get line-storage, next
732 allocate next-line-ah
733 var next-line/eax: (addr line) <- lookup *next-line-ah
734 var first-word-ah/eax: (addr handle word) <- get next-line, data
735 allocate-word-with first-word-ah, "a"
736 var functions-storage: (handle function)
737 var functions/ecx: (addr handle function) <- address functions-storage
738 var table-storage: table
739 var table/ebx: (addr table) <- address table-storage
740 initialize-table table, 0x10
741 var stack-storage: value-stack
742 var stack/edi: (addr value-stack) <- address stack-storage
743 initialize-value-stack stack, 0x10
744 evaluate functions, table, line, 0, stack
745 var x/eax: int <- pop-int-from-value-stack stack
746 check-ints-equal x, 3, "F - test-evaluate"
747 }
748
749 fn find-function first: (addr handle function), name: (addr stream byte), out: (addr handle function) {
750 var curr/esi: (addr handle function) <- copy first
751 $find-function:loop: {
752 var _f/eax: (addr function) <- lookup *curr
753 var f/ecx: (addr function) <- copy _f
754 compare f, 0
755 break-if-=
756 var curr-name-ah/eax: (addr handle array byte) <- get f, name
757 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
758 var done?/eax: boolean <- stream-data-equal? name, curr-name
759 compare done?, 0
760 {
761 break-if-=
762 copy-handle *curr, out
763 break $find-function:loop
764 }
765 curr <- get f, next
766 loop
767 }
768 }
769
770 fn perform-call _callee: (addr function), caller-stack: (addr value-stack), functions: (addr handle function) {
771 var callee/ecx: (addr function) <- copy _callee
772
773 var table-storage: table
774 var table/esi: (addr table) <- address table-storage
775 initialize-table table, 0x10
776 bind-args callee, caller-stack, table
777
778 var body-ah/eax: (addr handle line) <- get callee, body
779 var body/eax: (addr line) <- lookup *body-ah
780
781 var stack-storage: value-stack
782 var stack/edi: (addr value-stack) <- address stack-storage
783 initialize-value-stack stack, 0x10
784
785 evaluate functions, table, body, 0, stack
786
787
788 var top-addr/ecx: (addr int) <- get stack, top
789 compare *top-addr, 0
790 break-if-<=
791 var data-ah/eax: (addr handle array value) <- get stack, data
792 var data/eax: (addr array value) <- lookup *data-ah
793 var top/edx: int <- copy *top-addr
794 top <- decrement
795 var dest-offset/edx: (offset value) <- compute-offset data, top
796 var target-val/edx: (addr value) <- index data, dest-offset
797
798 push-value-stack caller-stack, target-val
799 }
800
801
802
803 fn bind-args _callee: (addr function), _caller-stack: (addr value-stack), table: (addr table) {
804 var callee/ecx: (addr function) <- copy _callee
805 var curr-arg-ah/eax: (addr handle word) <- get callee, args
806 var curr-arg/eax: (addr word) <- lookup *curr-arg-ah
807
808 var curr-key-storage: (handle array byte)
809 var curr-key/edx: (addr handle array byte) <- address curr-key-storage
810 {
811 compare curr-arg, 0
812 break-if-=
813
814 word-to-string curr-arg, curr-key
815 {
816
817 var caller-stack/esi: (addr value-stack) <- copy _caller-stack
818 var top-addr/ecx: (addr int) <- get caller-stack, top
819 compare *top-addr, 0
820 break-if-<=
821 decrement *top-addr
822 var data-ah/eax: (addr handle array value) <- get caller-stack, data
823 var data/eax: (addr array value) <- lookup *data-ah
824 var top/ebx: int <- copy *top-addr
825 var dest-offset/ebx: (offset value) <- compute-offset data, top
826 var target-val/ebx: (addr value) <- index data, dest-offset
827
828 bind-in-table table, curr-key, target-val
829 }
830
831 var next-arg-ah/edx: (addr handle word) <- get curr-arg, next
832 curr-arg <- lookup *next-arg-ah
833 loop
834 }
835 }
836
837
838
839 fn max-stack-depth first-word: (addr word), final-word: (addr word) -> _/edi: int {
840 var curr-word/eax: (addr word) <- copy first-word
841 var curr-depth/ecx: int <- copy 0
842 var result/edi: int <- copy 0
843 $max-stack-depth:loop: {
844 $max-stack-depth:process-word: {
845
846 {
847 var is-add?/eax: boolean <- word-equal? curr-word, "+"
848 compare is-add?, 0
849 break-if-=
850 curr-depth <- decrement
851 break $max-stack-depth:process-word
852 }
853 {
854 var is-sub?/eax: boolean <- word-equal? curr-word, "-"
855 compare is-sub?, 0
856 break-if-=
857 curr-depth <- decrement
858 break $max-stack-depth:process-word
859 }
860 {
861 var is-mul?/eax: boolean <- word-equal? curr-word, "*"
862 compare is-mul?, 0
863 break-if-=
864 curr-depth <- decrement
865 break $max-stack-depth:process-word
866 }
867
868 curr-depth <- increment
869
870 {
871 compare curr-depth, result
872 break-if-<=
873 result <- copy curr-depth
874 }
875 }
876
877 compare curr-word, final-word
878 break-if-=
879
880 var next-word-ah/edx: (addr handle word) <- get curr-word, next
881 curr-word <- lookup *next-word-ah
882
883 loop
884 }
885 return result
886 }