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