https://github.com/akkartik/mu/blob/master/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 -> exit-status/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 exit-status <- copy 0
52 }
53
54 type int-stack {
55 data: (handle array int)
56 top: int
57 }
58
59 fn simplify in: (addr stream byte) -> result/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 result <- pop-int-stack stack
110 }
111
112 fn initialize-int-stack _self: (addr int-stack), n: int {
113 var self/esi: (addr int-stack) <- copy _self
114 var d/edi: (addr handle array int) <- get self, data
115 populate d, n
116 var top/eax: (addr int) <- get self, top
117 copy-to *top, 0
118 }
119
120 fn push-int-stack _self: (addr int-stack), _val: int {
121 var self/esi: (addr int-stack) <- copy _self
122 var top-addr/ecx: (addr int) <- get self, top
123 var data-ah/edx: (addr handle array int) <- get self, data
124 var data/eax: (addr array int) <- lookup *data-ah
125 var top/edx: int <- copy *top-addr
126 var dest-addr/edx: (addr int) <- index data, top
127 var val/eax: int <- copy _val
128 copy-to *dest-addr, val
129 add-to *top-addr, 1
130 }
131
132 fn pop-int-stack _self: (addr int-stack) -> val/eax: int {
133 $pop-int-stack:body: {
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 val <- copy 0
140 break $pop-int-stack:body
141 }
142 subtract-from *top-addr, 1
143 var data-ah/edx: (addr handle array int) <- get self, data
144 var data/eax: (addr array int) <- lookup *data-ah
145 var top/edx: int <- copy *top-addr
146 var result-addr/eax: (addr int) <- index data, top
147 val <- copy *result-addr
148 }
149 }