https://github.com/akkartik/mu/blob/main/linux/tile/value.mu
1 fn render-value-at screen: (addr screen), row: int, col: int, _val: (addr value), top-level?: boolean {
2 move-cursor screen, row, col
3 var val/esi: (addr value) <- copy _val
4 var val-type/ecx: (addr int) <- get val, type
5
6 compare *val-type, 1/string
7 {
8 break-if-!=
9 var val-ah/eax: (addr handle array byte) <- get val, text-data
10 var val-string/eax: (addr array byte) <- lookup *val-ah
11 compare val-string, 0
12 break-if-=
13 var orig-len/ecx: int <- length val-string
14 var truncated: (handle array byte)
15 var truncated-ah/esi: (addr handle array byte) <- address truncated
16 substring val-string, 0, 0xc, truncated-ah
17 var truncated-string/eax: (addr array byte) <- lookup *truncated-ah
18 var len/edx: int <- length truncated-string
19 start-color screen, 0xf2, 7
20 print-code-point screen, 0x275d/open-quote
21 print-string screen, truncated-string
22 compare len, orig-len
23 {
24 break-if-=
25 print-code-point screen, 0x2026/ellipses
26 }
27 print-code-point screen, 0x275e/close-quote
28 reset-formatting screen
29 return
30 }
31 compare *val-type, 2/array
32 {
33 break-if-!=
34 var val-ah/eax: (addr handle array value) <- get val, array-data
35 var val-array/eax: (addr array value) <- lookup *val-ah
36 render-array-at screen, row, col, val-array
37 return
38 }
39 compare *val-type, 3/file
40 {
41 break-if-!=
42 var val-ah/eax: (addr handle buffered-file) <- get val, file-data
43 var val-file/eax: (addr buffered-file) <- lookup *val-ah
44 start-color screen, 0, 7
45
46 print-string screen, " FILE "
47 return
48 }
49 compare *val-type, 4/screen
50 {
51 break-if-!=
52
53 var val-ah/eax: (addr handle screen) <- get val, screen-data
54 var val-screen/eax: (addr screen) <- lookup *val-ah
55 render-screen screen, row, col, val-screen
56
57 return
58 }
59
60 var val-num/eax: (addr float) <- get val, number-data
61 render-number screen, *val-num, top-level?
62 }
63
64
65
66 fn render-number screen: (addr screen), val: float, top-level?: boolean {
67
68 compare top-level?, 0
69 {
70 break-if-!=
71 print-float-decimal-approximate screen, val, 3
72 return
73 }
74 var val-int/eax: int <- convert val
75 var bg/eax: int <- hash-color val-int
76 var fg/ecx: int <- copy 7
77 {
78 compare bg, 2
79 break-if-!=
80 fg <- copy 0
81 }
82 {
83 compare bg, 3
84 break-if-!=
85 fg <- copy 0
86 }
87 {
88 compare bg, 6
89 break-if-!=
90 fg <- copy 0
91 }
92 start-color screen, fg, bg
93 print-grapheme screen, 0x20/space
94 print-float-decimal-approximate screen, val, 3
95 print-grapheme screen, 0x20/space
96 }
97
98 fn render-array-at screen: (addr screen), row: int, col: int, _a: (addr array value) {
99 start-color screen, 0xf2, 7
100
101 print-grapheme screen, 0x5b/[
102 increment col
103 var a/esi: (addr array value) <- copy _a
104 var max/ecx: int <- length a
105 var i/eax: int <- copy 0
106 {
107 compare i, max
108 break-if->=
109 {
110 compare i, 0
111 break-if-=
112 print-string screen, " "
113 }
114 var off/ecx: (offset value) <- compute-offset a, i
115 var x/ecx: (addr value) <- index a, off
116 render-value-at screen, row, col, x, 0
117 {
118 var w/eax: int <- value-width x, 0
119 add-to col, w
120 increment col
121 }
122 i <- increment
123 loop
124 }
125 print-grapheme screen, 0x5d/]
126 }
127
128 fn render-screen screen: (addr screen), row: int, col: int, _target-screen: (addr screen) {
129 reset-formatting screen
130 move-cursor screen, row, col
131 var target-screen/esi: (addr screen) <- copy _target-screen
132 var ncols-a/ecx: (addr int) <- get target-screen, num-cols
133 print-upper-border screen, *ncols-a
134 var r/edx: int <- copy 1
135 var nrows-a/ebx: (addr int) <- get target-screen, num-rows
136 {
137 compare r, *nrows-a
138 break-if->
139 increment row
140 move-cursor screen, row, col
141 print-string screen, " "
142 var c/edi: int <- copy 1
143 {
144 compare c, *ncols-a
145 break-if->
146 print-screen-cell-of-fake-screen screen, target-screen, r, c
147 c <- increment
148 loop
149 }
150 print-string screen, " "
151 r <- increment
152 loop
153 }
154 increment row
155 move-cursor screen, row, col
156 print-lower-border screen, *ncols-a
157 }
158
159 fn hash-color val: int -> _/eax: int {
160 var quotient/eax: int <- copy 0
161 var remainder/edx: int <- copy 0
162 quotient, remainder <- integer-divide val, 7
163 return remainder
164 }
165
166 fn print-screen-cell-of-fake-screen screen: (addr screen), _target: (addr screen), _row: int, _col: int {
167 start-color screen, 0, 0xf6
168 var target/esi: (addr screen) <- copy _target
169 var row/ecx: int <- copy _row
170 var col/edx: int <- copy _col
171
172 {
173 var cursor-row/eax: (addr int) <- get target, cursor-row
174 compare *cursor-row, row
175 break-if-!=
176 var cursor-col/eax: (addr int) <- get target, cursor-col
177 compare *cursor-col, col
178 break-if-!=
179 start-blinking screen
180 start-color screen, 0, 1
181 }
182 var g/eax: grapheme <- screen-grapheme-at target, row, col
183 {
184 compare g, 0
185 break-if-!=
186 g <- copy 0x20/space
187 }
188 print-grapheme screen, g
189 reset-formatting screen
190 }
191
192 fn print-upper-border screen: (addr screen), width: int {
193 print-code-point screen, 0x250c/top-left-corner
194 var i/eax: int <- copy 0
195 {
196 compare i, width
197 break-if->=
198 print-code-point screen, 0x2500/horizontal-line
199 i <- increment
200 loop
201 }
202 print-code-point screen, 0x2510/top-right-corner
203 }
204
205 fn print-lower-border screen: (addr screen), width: int {
206 print-code-point screen, 0x2514/bottom-left-corner
207 var i/eax: int <- copy 0
208 {
209 compare i, width
210 break-if->=
211 print-code-point screen, 0x2500/horizontal-line
212 i <- increment
213 loop
214 }
215 print-code-point screen, 0x2518/bottom-right-corner
216 }
217
218 fn value-width _v: (addr value), top-level: boolean -> _/eax: int {
219 var v/esi: (addr value) <- copy _v
220 var type/eax: (addr int) <- get v, type
221 {
222 compare *type, 0/int
223 break-if-!=
224 var v-num/edx: (addr float) <- get v, number-data
225 var result/eax: int <- float-size *v-num, 3
226 return result
227 }
228 {
229 compare *type, 1/string
230 break-if-!=
231 var s-ah/eax: (addr handle array byte) <- get v, text-data
232 var s/eax: (addr array byte) <- lookup *s-ah
233 compare s, 0
234 break-if-=
235 var result/eax: int <- length s
236 compare result, 0xd/max-string-size
237 {
238 break-if-<=
239 result <- copy 0xd
240 }
241
242
243
244 compare top-level, 0/false
245 {
246 break-if-!=
247 result <- add 2
248 }
249 return result
250 }
251 {
252 compare *type, 2/array
253 break-if-!=
254 var a-ah/eax: (addr handle array value) <- get v, array-data
255 var a/eax: (addr array value) <- lookup *a-ah
256 compare a, 0
257 break-if-=
258 var result/eax: int <- array-width a
259 return result
260 }
261 {
262 compare *type, 3/file
263 break-if-!=
264 var f-ah/eax: (addr handle buffered-file) <- get v, file-data
265 var f/eax: (addr buffered-file) <- lookup *f-ah
266 compare f, 0
267 break-if-=
268
269 return 4
270 }
271 {
272 compare *type, 4/screen
273 break-if-!=
274 var screen-ah/eax: (addr handle screen) <- get v, screen-data
275 var screen/eax: (addr screen) <- lookup *screen-ah
276 compare screen, 0
277 break-if-=
278 var ncols/ecx: (addr int) <- get screen, num-cols
279 var result/eax: int <- copy *ncols
280 result <- add 2
281 return *ncols
282 }
283 return 0
284 }
285
286
287 fn array-width _a: (addr array value) -> _/eax: int {
288 var a/esi: (addr array value) <- copy _a
289 var max/ecx: int <- length a
290 var i/eax: int <- copy 0
291 var result/edi: int <- copy 0
292 {
293 compare i, max
294 break-if->=
295 {
296 compare i, 0
297 break-if-=
298 result <- increment
299 }
300 var off/ecx: (offset value) <- compute-offset a, i
301 var x/ecx: (addr value) <- index a, off
302 {
303 var w/eax: int <- value-width x, 0
304 result <- add w
305 }
306 i <- increment
307 loop
308 }
309
310
311 return result
312 }
313
314 fn value-height _v: (addr value) -> _/eax: int {
315 var v/esi: (addr value) <- copy _v
316 var type/eax: (addr int) <- get v, type
317 {
318 compare *type, 3/file
319 break-if-!=
320
321 return 1
322 }
323 {
324 compare *type, 4/screen
325 break-if-!=
326 var screen-ah/eax: (addr handle screen) <- get v, screen-data
327 var screen/eax: (addr screen) <- lookup *screen-ah
328 compare screen, 0
329 break-if-=
330 var nrows/ecx: (addr int) <- get screen, num-rows
331 var result/eax: int <- copy *nrows
332 result <- add 2
333 return result
334 }
335 return 1
336 }
337
338 fn deep-copy-value _src: (addr value), _dest: (addr value) {
339
340 var src/esi: (addr value) <- copy _src
341 var dest/edi: (addr value) <- copy _dest
342 var type/ebx: (addr int) <- get src, type
343 var y/ecx: (addr int) <- get dest, type
344 copy-object type, y
345 compare *type, 0
346 {
347 break-if-!=
348
349 var src-n/eax: (addr float) <- get src, number-data
350 var dest-n/ecx: (addr float) <- get dest, number-data
351 copy-object src-n, dest-n
352 return
353 }
354 compare *type, 1/string
355 {
356 break-if-!=
357
358 var src-ah/eax: (addr handle array byte) <- get src, text-data
359 var src/eax: (addr array byte) <- lookup *src-ah
360 var dest-ah/edx: (addr handle array byte) <- get dest, text-data
361 copy-array-object src, dest-ah
362 return
363 }
364 compare *type, 2/array
365 {
366 break-if-!=
367
368 var src-ah/eax: (addr handle array value) <- get src, array-data
369 var _src/eax: (addr array value) <- lookup *src-ah
370 var src/esi: (addr array value) <- copy _src
371 var n/ecx: int <- length src
372 var dest-ah/edx: (addr handle array value) <- get dest, array-data
373 populate dest-ah, n
374 var _dest/eax: (addr array value) <- lookup *dest-ah
375 var dest/edi: (addr array value) <- copy _dest
376 var i/eax: int <- copy 0
377 {
378 compare i, n
379 break-if->=
380 {
381 var offset/edx: (offset value) <- compute-offset src, i
382 var src-element/eax: (addr value) <- index src, offset
383 var dest-element/ecx: (addr value) <- index dest, offset
384 deep-copy-value src-element, dest-element
385 }
386 i <- increment
387 loop
388 }
389 copy-array-object src, dest-ah
390 return
391 }
392 compare *type, 3/file
393 {
394 break-if-!=
395
396 var src-filename-ah/eax: (addr handle array byte) <- get src, filename
397 var _src-filename/eax: (addr array byte) <- lookup *src-filename-ah
398 var src-filename/ecx: (addr array byte) <- copy _src-filename
399 var dest-filename-ah/ebx: (addr handle array byte) <- get dest, filename
400 copy-array-object src-filename, dest-filename-ah
401 var src-file-ah/eax: (addr handle buffered-file) <- get src, file-data
402 var src-file/eax: (addr buffered-file) <- lookup *src-file-ah
403 var dest-file-ah/edx: (addr handle buffered-file) <- get dest, file-data
404 copy-file src-file, dest-file-ah, src-filename
405 return
406 }
407 compare *type, 4/screen
408 {
409 break-if-!=
410
411 var src-screen-ah/eax: (addr handle screen) <- get src, screen-data
412 var _src-screen/eax: (addr screen) <- lookup *src-screen-ah
413 var src-screen/ecx: (addr screen) <- copy _src-screen
414 var dest-screen-ah/eax: (addr handle screen) <- get dest, screen-data
415 allocate dest-screen-ah
416 var dest-screen/eax: (addr screen) <- lookup *dest-screen-ah
417 copy-object src-screen, dest-screen
418 var dest-screen-data-ah/ebx: (addr handle array screen-cell) <- get dest-screen, data
419 var src-screen-data-ah/eax: (addr handle array screen-cell) <- get src-screen, data
420 var src-screen-data/eax: (addr array screen-cell) <- lookup *src-screen-data-ah
421 copy-array-object src-screen-data, dest-screen-data-ah
422 return
423 }
424 }