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