https://github.com/akkartik/mu/blob/main/apps/rpn.mu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) {
19 var in-storage: (stream byte 0x80)
20 var in/esi: (addr stream byte) <- address in-storage
21 var y/ecx: int <- copy 0
22
23 {
24 var x/eax: int <- draw-text-rightward screen, "> ", 0/x, 0x80/xmax, y, 3/fg/cyan, 0/bg
25 read-line-from-keyboard keyboard, in, screen, 0xf/fg 0/bg
26
27 var out/eax: int <- simplify in
28
29 y <- increment
30 out, y <- draw-int32-decimal-wrapping-right-then-down screen, out, 0/xmin, y, 0x80/xmax, 0x30/ymax, 0/x, y, 7/fg, 0/bg
31
32 y <- increment
33
34 loop
35 }
36 }
37
38 type int-stack {
39 data: (handle array int)
40 top: int
41 }
42
43 fn simplify in: (addr stream byte) -> _/eax: int {
44 var word-storage: slice
45 var word/ecx: (addr slice) <- address word-storage
46 var stack-storage: int-stack
47 var stack/esi: (addr int-stack) <- address stack-storage
48 initialize-int-stack stack, 0x10
49 $simplify:word-loop: {
50 next-word in, word
51 var done?/eax: boolean <- slice-empty? word
52 compare done?, 0
53 break-if-!=
54
55 {
56 var is-add?/eax: boolean <- slice-equal? word, "+"
57 compare is-add?, 0
58 break-if-=
59 var _b/eax: int <- pop-int-stack stack
60 var b/edx: int <- copy _b
61 var a/eax: int <- pop-int-stack stack
62 a <- add b
63 push-int-stack stack, a
64 loop $simplify:word-loop
65 }
66 {
67 var is-sub?/eax: boolean <- slice-equal? word, "-"
68 compare is-sub?, 0
69 break-if-=
70 var _b/eax: int <- pop-int-stack stack
71 var b/edx: int <- copy _b
72 var a/eax: int <- pop-int-stack stack
73 a <- subtract b
74 push-int-stack stack, a
75 loop $simplify:word-loop
76 }
77 {
78 var is-mul?/eax: boolean <- slice-equal? word, "*"
79 compare is-mul?, 0
80 break-if-=
81 var _b/eax: int <- pop-int-stack stack
82 var b/edx: int <- copy _b
83 var a/eax: int <- pop-int-stack stack
84 a <- multiply b
85 push-int-stack stack, a
86 loop $simplify:word-loop
87 }
88
89 var n/eax: int <- parse-decimal-int-from-slice word
90 push-int-stack stack, n
91 loop
92 }
93 var result/eax: int <- pop-int-stack stack
94 return result
95 }
96
97 fn initialize-int-stack _self: (addr int-stack), n: int {
98 var self/esi: (addr int-stack) <- copy _self
99 var d/edi: (addr handle array int) <- get self, data
100 populate d, n
101 var top/eax: (addr int) <- get self, top
102 copy-to *top, 0
103 }
104
105 fn push-int-stack _self: (addr int-stack), _val: int {
106 var self/esi: (addr int-stack) <- copy _self
107 var top-addr/ecx: (addr int) <- get self, top
108 var data-ah/edx: (addr handle array int) <- get self, data
109 var data/eax: (addr array int) <- lookup *data-ah
110 var top/edx: int <- copy *top-addr
111 var dest-addr/edx: (addr int) <- index data, top
112 var val/eax: int <- copy _val
113 copy-to *dest-addr, val
114 add-to *top-addr, 1
115 }
116
117 fn pop-int-stack _self: (addr int-stack) -> _/eax: int {
118 var self/esi: (addr int-stack) <- copy _self
119 var top-addr/ecx: (addr int) <- get self, top
120 {
121 compare *top-addr, 0
122 break-if->
123 return 0
124 }
125 subtract-from *top-addr, 1
126 var data-ah/edx: (addr handle array int) <- get self, data
127 var data/eax: (addr array int) <- lookup *data-ah
128 var top/edx: int <- copy *top-addr
129 var result-addr/eax: (addr int) <- index data, top
130 var val/eax: int <- copy *result-addr
131 return val
132 }