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
19
20
21
22
23
24
25
26
27
28
29 fn main -> _/ebx: int {
30 var in-storage: (stream byte 0x100)
31 var in/esi: (addr stream byte) <- address in-storage
32 print-string 0, "press ctrl-c or ctrl-d to exit\n"
33
34 {
35
36 print-string 0, "> "
37
38 clear-stream in
39 read-line-from-real-keyboard in
40 var done?/eax: boolean <- stream-empty? in
41 compare done?, 0
42 break-if-!=
43
44 var out/eax: int <- simplify in
45
46 print-int32-decimal 0, out
47 print-string 0, "\n"
48
49 loop
50 }
51 return 0
52 }
53
54 type int-stack {
55 data: (handle array int)
56 top: int
57 }
58
59 fn simplify in: (addr stream byte) -> _/eax: int {
60 var word-storage: slice
61 var word/ecx: (addr slice) <- address word-storage
62 var stack-storage: int-stack
63 var stack/esi: (addr int-stack) <- address stack-storage
64 initialize-int-stack stack, 0x10
65 $simplify:word-loop: {
66 next-word in, word
67 var done?/eax: boolean <- slice-empty? word
68 compare done?, 0
69 break-if-!=
70
71 {
72 var is-add?/eax: boolean <- slice-equal? word, "+"
73 compare is-add?, 0
74 break-if-=
75 var _b/eax: int <- pop-int-stack stack
76 var b/edx: int <- copy _b
77 var a/eax: int <- pop-int-stack stack
78 a <- add b
79 push-int-stack stack, a
80 loop $simplify:word-loop
81 }
82 {
83 var is-sub?/eax: boolean <- slice-equal? word, "-"
84 compare is-sub?, 0
85 break-if-=
86 var _b/eax: int <- pop-int-stack stack
87 var b/edx: int <- copy _b
88 var a/eax: int <- pop-int-stack stack
89 a <- subtract b
90 push-int-stack stack, a
91 loop $simplify:word-loop
92 }
93 {
94 var is-mul?/eax: boolean <- slice-equal? word, "*"
95 compare is-mul?, 0
96 break-if-=
97 var _b/eax: int <- pop-int-stack stack
98 var b/edx: int <- copy _b
99 var a/eax: int <- pop-int-stack stack
100 a <- multiply b
101 push-int-stack stack, a
102 loop $simplify:word-loop
103 }
104
105 var n/eax: int <- parse-decimal-int-from-slice word
106 push-int-stack stack, n
107 loop
108 }
109 var result/eax: int <- pop-int-stack stack
110 return result
111 }
112
113 fn initialize-int-stack _self: (addr int-stack), n: int {
114 var self/esi: (addr int-stack) <- copy _self
115 var d/edi: (addr handle array int) <- get self, data
116 populate d, n
117 var top/eax: (addr int) <- get self, top
118 copy-to *top, 0
119 }
120
121 fn push-int-stack _self: (addr int-stack), _val: int {
122 var self/esi: (addr int-stack) <- copy _self
123 var top-addr/ecx: (addr int) <- get self, top
124 var data-ah/edx: (addr handle array int) <- get self, data
125 var data/eax: (addr array int) <- lookup *data-ah
126 var top/edx: int <- copy *top-addr
127 var dest-addr/edx: (addr int) <- index data, top
128 var val/eax: int <- copy _val
129 copy-to *dest-addr, val
130 add-to *top-addr, 1
131 }
132
133 fn pop-int-stack _self: (addr int-stack) -> _/eax: int {
134 var self/esi: (addr int-stack) <- copy _self
135 var top-addr/ecx: (addr int) <- get self, top
136 {
137 compare *top-addr, 0
138 break-if->
139 return 0
140 }
141 subtract-from *top-addr, 1
142 var data-ah/edx: (addr handle array int) <- get self, data
143 var data/eax: (addr array int) <- lookup *data-ah
144 var top/edx: int <- copy *top-addr
145 var result-addr/eax: (addr int) <- index data, top
146 var val/eax: int <- copy *result-addr
147 return val
148 }