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