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