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