https://github.com/akkartik/mu/blob/main/baremetal/shell/value-stack.mu
1
2
3
4 type value-stack {
5 data: (handle array value)
6 top: int
7 }
8
9 fn initialize-value-stack _self: (addr value-stack), n: int {
10 var self/esi: (addr value-stack) <- copy _self
11 var d/edi: (addr handle array value) <- get self, data
12 populate d, n
13 var top/eax: (addr int) <- get self, top
14 copy-to *top, 0
15 }
16
17 fn clear-value-stack _self: (addr value-stack) {
18 var self/esi: (addr value-stack) <- copy _self
19 var top/eax: (addr int) <- get self, top
20 copy-to *top, 0
21 }
22
23 fn push-number-to-value-stack _self: (addr value-stack), _val: float {
24 var self/esi: (addr value-stack) <- copy _self
25 var top-addr/ecx: (addr int) <- get self, top
26 var data-ah/edx: (addr handle array value) <- get self, data
27 var data/eax: (addr array value) <- lookup *data-ah
28 var top/edx: int <- copy *top-addr
29 var dest-offset/edx: (offset value) <- compute-offset data, top
30 var dest-addr/edx: (addr value) <- index data, dest-offset
31 var dest-addr2/eax: (addr float) <- get dest-addr, number-data
32 var val/xmm0: float <- copy _val
33 copy-to *dest-addr2, val
34 increment *top-addr
35 var type-addr/eax: (addr int) <- get dest-addr, type
36 copy-to *type-addr, 0/number
37 }
38
39 fn push-int-to-value-stack _self: (addr value-stack), _val: int {
40 var self/esi: (addr value-stack) <- copy _self
41 var top-addr/ecx: (addr int) <- get self, top
42 var data-ah/edx: (addr handle array value) <- get self, data
43 var data/eax: (addr array value) <- lookup *data-ah
44 var top/edx: int <- copy *top-addr
45 var dest-offset/edx: (offset value) <- compute-offset data, top
46 var dest-addr/edx: (addr value) <- index data, dest-offset
47 var dest-addr2/eax: (addr float) <- get dest-addr, number-data
48 var val/xmm0: float <- convert _val
49 copy-to *dest-addr2, val
50 increment *top-addr
51 var type-addr/eax: (addr int) <- get dest-addr, type
52 copy-to *type-addr, 0/number
53 }
54
55 fn push-string-to-value-stack _self: (addr value-stack), val: (handle array byte) {
56 var self/esi: (addr value-stack) <- copy _self
57 var top-addr/ecx: (addr int) <- get self, top
58 var data-ah/edx: (addr handle array value) <- get self, data
59 var data/eax: (addr array value) <- lookup *data-ah
60 var top/edx: int <- copy *top-addr
61 var dest-offset/edx: (offset value) <- compute-offset data, top
62 var dest-addr/edx: (addr value) <- index data, dest-offset
63 var dest-addr2/eax: (addr handle array byte) <- get dest-addr, text-data
64 copy-handle val, dest-addr2
65 var dest-addr3/eax: (addr int) <- get dest-addr, type
66 copy-to *dest-addr3, 1/string
67 increment *top-addr
68 }
69
70 fn push-array-to-value-stack _self: (addr value-stack), val: (handle array value) {
71 var self/esi: (addr value-stack) <- copy _self
72 var top-addr/ecx: (addr int) <- get self, top
73 var data-ah/edx: (addr handle array value) <- get self, data
74 var data/eax: (addr array value) <- lookup *data-ah
75 var top/edx: int <- copy *top-addr
76 var dest-offset/edx: (offset value) <- compute-offset data, top
77 var dest-addr/edx: (addr value) <- index data, dest-offset
78 var dest-addr2/eax: (addr handle array value) <- get dest-addr, array-data
79 copy-handle val, dest-addr2
80
81 var dest-addr3/eax: (addr int) <- get dest-addr, type
82 copy-to *dest-addr3, 2/array
83 increment *top-addr
84 }
85
86 fn push-boolean-to-value-stack _self: (addr value-stack), _val: boolean {
87 var self/esi: (addr value-stack) <- copy _self
88 var top-addr/ecx: (addr int) <- get self, top
89 var data-ah/edx: (addr handle array value) <- get self, data
90 var data/eax: (addr array value) <- lookup *data-ah
91 var top/edx: int <- copy *top-addr
92 var dest-offset/edx: (offset value) <- compute-offset data, top
93 var dest-addr/edx: (addr value) <- index data, dest-offset
94 var dest-addr2/eax: (addr boolean) <- get dest-addr, boolean-data
95 var val/esi: boolean <- copy _val
96 copy-to *dest-addr2, val
97 increment *top-addr
98 var type-addr/eax: (addr int) <- get dest-addr, type
99 copy-to *type-addr, 3/boolean
100 }
101
102 fn push-value-stack _self: (addr value-stack), val: (addr value) {
103 var self/esi: (addr value-stack) <- copy _self
104 var top-addr/ecx: (addr int) <- get self, top
105 var data-ah/edx: (addr handle array value) <- get self, data
106 var data/eax: (addr array value) <- lookup *data-ah
107 var top/edx: int <- copy *top-addr
108 var dest-offset/edx: (offset value) <- compute-offset data, top
109 var dest-addr/edx: (addr value) <- index data, dest-offset
110 copy-object val, dest-addr
111 increment *top-addr
112 }
113
114 fn pop-number-from-value-stack _self: (addr value-stack) -> _/xmm0: float {
115 var self/esi: (addr value-stack) <- copy _self
116 var top-addr/ecx: (addr int) <- get self, top
117 {
118 compare *top-addr, 0
119 break-if->
120 abort "pop number: empty stack"
121 }
122 decrement *top-addr
123 var data-ah/edx: (addr handle array value) <- get self, data
124 var data/eax: (addr array value) <- lookup *data-ah
125 var top/edx: int <- copy *top-addr
126 var dest-offset/edx: (offset value) <- compute-offset data, top
127 var result-addr/eax: (addr value) <- index data, dest-offset
128 var result-addr2/eax: (addr float) <- get result-addr, number-data
129 return *result-addr2
130 }
131
132 fn pop-boolean-from-value-stack _self: (addr value-stack) -> _/eax: boolean {
133 var self/esi: (addr value-stack) <- copy _self
134 var top-addr/ecx: (addr int) <- get self, top
135 {
136 compare *top-addr, 0
137 break-if->
138 abort "pop boolean: empty stack"
139 }
140 decrement *top-addr
141 var data-ah/edx: (addr handle array value) <- get self, data
142 var data/eax: (addr array value) <- lookup *data-ah
143 var top/edx: int <- copy *top-addr
144 var dest-offset/edx: (offset value) <- compute-offset data, top
145 var result-addr/eax: (addr value) <- index data, dest-offset
146 var result-addr2/eax: (addr boolean) <- get result-addr, boolean-data
147 return *result-addr2
148 }
149
150 fn value-stack-empty? _self: (addr value-stack) -> _/eax: boolean {
151 var self/esi: (addr value-stack) <- copy _self
152 var top/eax: (addr int) <- get self, top
153 compare *top, 0
154 {
155 break-if-!=
156 return 1/true
157 }
158 return 0/false
159 }
160
161 fn value-stack-length _self: (addr value-stack) -> _/eax: int {
162 var self/esi: (addr value-stack) <- copy _self
163 var top-addr/eax: (addr int) <- get self, top
164 return *top-addr
165 }
166
167 fn test-boolean {
168 var stack-storage: value-stack
169 var stack/esi: (addr value-stack) <- address stack-storage
170 push-boolean-to-value-stack stack, 0/false
171 var result/eax: boolean <- pop-boolean-from-value-stack stack
172 check-not result, "F - test-boolean/false"
173 push-boolean-to-value-stack stack, 1/true
174 var result/eax: boolean <- pop-boolean-from-value-stack stack
175 check result, "F - test-boolean/true"
176 }
177
178 fn dump-stack _self: (addr value-stack) {
179 var self/esi: (addr value-stack) <- copy _self
180 var data-ah/eax: (addr handle array value) <- get self, data
181 var _data/eax: (addr array value) <- lookup *data-ah
182 var data/edi: (addr array value) <- copy _data
183 var top-addr/ecx: (addr int) <- get self, top
184 var top/ecx: int <- copy *top-addr
185 top <- decrement
186 var y/edx: int <- copy 0xa
187 var dummy/eax: int <- draw-text-rightward-over-full-screen 0/screen, "==", 0/x, 9/y, 0xc/red, 0/bg
188 {
189 compare top, 0
190 break-if-<
191 var dest-offset/eax: (offset value) <- compute-offset data, top
192 var curr/eax: (addr value) <- index data, dest-offset
193 var dummy/eax: int <- render-value 0/screen, curr, 0/x, y, 0/no-color
194 top <- decrement
195 y <- increment
196 loop
197 }
198 }
199
200 fn render-value-stack screen: (addr screen), _self: (addr value-stack), x: int, y: int -> _/eax: int, _/ecx: int {
201 var self/ecx: (addr value-stack) <- copy _self
202 var data-ah/eax: (addr handle array value) <- get self, data
203 var _data/eax: (addr array value) <- lookup *data-ah
204 var data/edi: (addr array value) <- copy _data
205 var top-addr/eax: (addr int) <- get self, top
206 var curr-idx/ecx: int <- copy *top-addr
207 curr-idx <- decrement
208 var new-x/edx: int <- copy 0
209 {
210 compare curr-idx, 0
211 break-if-<
212 var dest-offset/eax: (offset value) <- compute-offset data, curr-idx
213 var curr/eax: (addr value) <- index data, dest-offset
214 var curr-x/eax: int <- render-value screen, curr, x, y, 1/top-level
215 {
216 compare curr-x, new-x
217 break-if-<=
218 new-x <- copy curr-x
219 }
220 curr-idx <- decrement
221 increment y
222 loop
223 }
224 return new-x, y
225 }
226
227 fn test-render-value-stack {
228 var stack-storage: value-stack
229 var stack/esi: (addr value-stack) <- address stack-storage
230 push-int-to-value-stack stack, 3
231
232 var screen-on-stack: screen
233 var screen/edi: (addr screen) <- address screen-on-stack
234 initialize-screen screen, 0x20, 4
235
236 var final-x/eax: int <- copy 0
237 var final-y/ecx: int <- copy 0
238 final-x, final-y <- render-value-stack screen, stack, 0/x, 0/y
239 check-ints-equal final-y, 1, "F - test-render-value-stack y"
240 check-ints-equal final-x, 3, "F - test-render-value-stack x"
241 }