https://github.com/akkartik/mu/blob/main/baremetal/shell/value.mu
1
2 type value {
3 type: int
4 number-data: float
5 text-data: (handle array byte)
6 array-data: (handle array value)
7 boolean-data: boolean
8 }
9
10
11
12 fn render-value screen: (addr screen), _val: (addr value), x: int, y: int, top-level?: boolean -> _/eax: int {
13 var val/esi: (addr value) <- copy _val
14 var val-type/ecx: (addr int) <- get val, type
15 compare *val-type, 1/string
16 {
17 break-if-!=
18 var val-ah/eax: (addr handle array byte) <- get val, text-data
19 var _val-string/eax: (addr array byte) <- lookup *val-ah
20 var val-string/ecx: (addr array byte) <- copy _val-string
21 var new-x/eax: int <- render-string screen, val-string, x, y
22 return new-x
23 }
24 compare *val-type, 2/array
25 {
26 break-if-!=
27 var val-ah/eax: (addr handle array value) <- get val, array-data
28 var _val-array/eax: (addr array value) <- lookup *val-ah
29 var val-array/edx: (addr array value) <- copy _val-array
30 var new-x/eax: int <- render-array screen, val-array, x, y
31 return new-x
32 }
33 compare *val-type, 3/boolean
34 {
35 break-if-!=
36 var val/eax: (addr boolean) <- get val, boolean-data
37 var new-x/eax: int <- render-boolean screen, *val, x, y
38 return new-x
39 }
40
41 var val-num/eax: (addr float) <- get val, number-data
42 var new-x/eax: int <- render-number screen, *val-num, x, y, top-level?
43 return new-x
44 }
45
46 fn initialize-value-with-integer _self: (addr value), n: int {
47 var self/esi: (addr value) <- copy _self
48 var type/eax: (addr int) <- get self, type
49 copy-to *type, 0/number
50 var val/xmm0: float <- convert n
51 var dest/eax: (addr float) <- get self, number-data
52 copy-to *dest, val
53 }
54
55 fn initialize-value-with-float _self: (addr value), n: float {
56 var self/esi: (addr value) <- copy _self
57 var type/eax: (addr int) <- get self, type
58 copy-to *type, 0/number
59 var val/xmm0: float <- copy n
60 var dest/eax: (addr float) <- get self, number-data
61 copy-to *dest, val
62 }
63
64
65
66 fn render-number screen: (addr screen), val: float, x: int, y: int, top-level?: boolean -> _/eax: int {
67
68 compare top-level?, 0
69 {
70 break-if-!=
71 var new-x/eax: int <- render-float-decimal screen, val, 3/precision, x, y, 3/fg, 0/bg
72 return new-x
73 }
74 var val-int/eax: int <- convert val
75 var _bg/eax: int <- hash-color val-int
76 var bg/ecx: int <- copy _bg
77 var fg/edx: int <- copy 7
78 {
79 compare bg, 2
80 break-if-!=
81 fg <- copy 0
82 }
83 {
84 compare bg, 3
85 break-if-!=
86 fg <- copy 0
87 }
88 {
89 compare bg, 6
90 break-if-!=
91 fg <- copy 0
92 }
93 draw-code-point screen, 0x20/space, x, y, fg, bg
94 increment x
95 var new-x/eax: int <- render-float-decimal screen, val, 3/precision, x, y, fg, bg
96 draw-code-point screen, 0x20/space, new-x, y, fg, bg
97 new-x <- increment
98 return new-x
99 }
100
101 fn hash-color val: int -> _/eax: int {
102 var quotient/eax: int <- copy 0
103 var remainder/edx: int <- copy 0
104 quotient, remainder <- integer-divide val, 7
105 return remainder
106 }
107
108 fn test-render-number {
109
110 var screen-on-stack: screen
111 var screen/edi: (addr screen) <- address screen-on-stack
112 initialize-screen screen, 0x20, 4
113
114 var new-x/eax: int <- render-number screen, 0/n, 0/x, 0/y, 1/at-top-level
115 check-screen-row screen, 0/y, " 0 ", "F - test-render-number"
116 check-ints-equal new-x, 3, "F - test-render-number: result"
117
118 }
119
120 fn initialize-value-with-string _self: (addr value), s: (addr array byte) {
121 var self/esi: (addr value) <- copy _self
122 var type/eax: (addr int) <- get self, type
123 copy-to *type, 1/string
124 var dest/eax: (addr handle array byte) <- get self, text-data
125 copy-array-object s, dest
126 }
127
128 fn render-string screen: (addr screen), _val: (addr array byte), x: int, y: int -> _/eax: int {
129 var val/esi: (addr array byte) <- copy _val
130 compare val, 0
131 {
132 break-if-!=
133 return x
134 }
135 var orig-len/ecx: int <- length val
136
137
138 var truncated: (handle array byte)
139 var truncated-ah/eax: (addr handle array byte) <- address truncated
140 substring val, 0, 0xc, truncated-ah
141 var _truncated-string/eax: (addr array byte) <- lookup *truncated-ah
142 var truncated-string/edx: (addr array byte) <- copy _truncated-string
143 var len/ebx: int <- length truncated-string
144 draw-code-point screen, 0x22/double-quote, x, y, 7/fg, 0/bg
145 increment x
146 var new-x/eax: int <- draw-text-rightward-over-full-screen screen, truncated-string, x, y, 7/fg, 0/bg
147 compare len, orig-len
148 {
149 break-if-=
150 new-x <- draw-text-rightward-over-full-screen screen, "...", new-x, y, 7/fg, 0/bg
151 }
152 draw-code-point screen, 0x22/double-quote, new-x, y, 7/fg, 0/bg
153 new-x <- increment
154 return new-x
155 }
156
157 fn test-render-string {
158
159 var screen-on-stack: screen
160 var screen/edi: (addr screen) <- address screen-on-stack
161 initialize-screen screen, 0x20, 4
162
163 var new-x/eax: int <- render-string screen, "abc", 0/x, 0/y
164 check-screen-row screen, 0/y, "\"abc\"", "F - test-render-string"
165 check-ints-equal new-x, 5, "F - test-render-string: result"
166 }
167
168 fn initialize-value-with-array-of-integers _self: (addr value), s: (addr array byte) {
169
170 var tmp-storage: (handle array int)
171 var tmp-ah/eax: (addr handle array int) <- address tmp-storage
172 parse-array-of-decimal-ints s, tmp-ah
173 var _tmp/eax: (addr array int ) <- lookup *tmp-ah
174 var tmp/esi: (addr array int ) <- copy _tmp
175
176 var self/edi: (addr value) <- copy _self
177 var type/eax: (addr int) <- get self, type
178 copy-to *type, 2/string
179 var dest-array-ah/eax: (addr handle array value) <- get self, array-data
180 var len/ebx: int <- length tmp
181 populate dest-array-ah, len
182 var _dest-array/eax: (addr array value) <- lookup *dest-array-ah
183 var dest-array/edi: (addr array value) <- copy _dest-array
184 var i/eax: int <- copy 0
185 {
186 compare i, len
187 break-if->=
188 var src-addr/ecx: (addr int) <- index tmp, i
189 var src/ecx: int <- copy *src-addr
190 var src-f/xmm0: float <- convert src
191 var dest-offset/edx: (offset value) <- compute-offset dest-array, i
192 var dest-val/edx: (addr value) <- index dest-array, dest-offset
193 var dest/edx: (addr float) <- get dest-val, number-data
194 copy-to *dest, src-f
195 i <- increment
196 loop
197 }
198 }
199
200 fn render-array screen: (addr screen), _arr: (addr array value), x: int, y: int -> _/eax: int {
201
202 draw-code-point screen, 0x5b/open-bracket, x, y, 7/fg, 0/bg
203 increment x
204 var arr/esi: (addr array value) <- copy _arr
205 var max/ecx: int <- length arr
206 var i/edx: int <- copy 0
207 var new-x/eax: int <- copy x
208 {
209 compare i, max
210 break-if->=
211 {
212 compare i, 0
213 break-if-=
214 draw-code-point screen, 0x20/space, new-x, y, 7/fg, 0/bg
215 new-x <- increment
216 }
217 var off/ecx: (offset value) <- compute-offset arr, i
218 var x/ecx: (addr value) <- index arr, off
219 new-x <- render-value screen, x, new-x, y, 0/nested
220 i <- increment
221 loop
222 }
223 draw-code-point screen, 0x5d/close-bracket, new-x, y, 7/fg, 0/bg
224 new-x <- increment
225 return new-x
226 }
227
228 fn test-render-array {
229
230 var screen-on-stack: screen
231 var screen/edi: (addr screen) <- address screen-on-stack
232 initialize-screen screen, 0x20, 4
233
234 var val-storage: value
235 var val/eax: (addr value) <- address val-storage
236 initialize-value-with-array-of-integers val, "0 1 2"
237 var val-array-ah/eax: (addr handle array value) <- get val, array-data
238 var val-array/eax: (addr array value) <- lookup *val-array-ah
239 var new-x/eax: int <- render-array screen, val-array, 0/x, 0/y
240 check-screen-row screen, 0/y, "[0 1 2]", "F - test-render-array"
241 check-ints-equal new-x, 7, "F - test-render-array: result"
242 }
243
244 fn initialize-value-with-boolean _self: (addr value), _b: boolean {
245 var self/esi: (addr value) <- copy _self
246 var type/eax: (addr int) <- get self, type
247 copy-to *type, 3/boolean
248 var dest/edi: (addr boolean) <- get self, boolean-data
249 var b/esi: boolean <- copy _b
250 copy-to *dest, b
251 }
252
253 fn render-boolean screen: (addr screen), val: boolean, x: int, y: int -> _/eax: int {
254 var new-x/eax: int <- copy 0
255 compare val, 0/false
256 {
257 break-if-=
258 new-x <- draw-text-rightward-over-full-screen screen, "true", new-x, y, 7/fg, 0/bg
259 return new-x
260 }
261 new-x <- draw-text-rightward-over-full-screen screen, "false", new-x, y, 7/fg, 0/bg
262 return new-x
263 }