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