https://github.com/akkartik/mu/blob/master/apps/tile/value.mu
1 fn render-value-at screen: (addr screen), row: int, col: int, _val: (addr value), max-width: int {
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
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
21 print-string screen, truncated-string
22 compare len, orig-len
23 {
24 break-if-=
25 print-code-point screen, 0x2026
26 }
27 print-code-point screen, 0x275e
28 reset-formatting screen
29 return
30 }
31 compare *val-type, 2
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
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
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-int/eax: (addr int) <- get val, int-data
61 render-integer screen, *val-int, max-width
62 }
63
64
65 fn render-integer screen: (addr screen), val: int, max-width: int {
66 $render-integer:body: {
67
68 compare max-width, 0
69 {
70 break-if-!=
71 print-int32-decimal screen, val
72 break $render-integer:body
73 }
74 var bg/eax: int <- hash-color val
75 var fg/ecx: int <- copy 7
76 {
77 compare bg, 2
78 break-if-!=
79 fg <- copy 0
80 }
81 {
82 compare bg, 3
83 break-if-!=
84 fg <- copy 0
85 }
86 {
87 compare bg, 6
88 break-if-!=
89 fg <- copy 0
90 }
91 start-color screen, fg, bg
92 print-grapheme screen, 0x20
93 print-int32-decimal-right-justified screen, val, max-width
94 print-grapheme screen, 0x20
95 }
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 result/eax: int <- try-modulo val, 7
161 return result
162 }
163
164 fn print-screen-cell-of-fake-screen screen: (addr screen), _target: (addr screen), _row: int, _col: int {
165 start-color screen, 0, 0xf6
166 var target/esi: (addr screen) <- copy _target
167 var row/ecx: int <- copy _row
168 var col/edx: int <- copy _col
169
170 {
171 var cursor-row/eax: (addr int) <- get target, cursor-row
172 compare *cursor-row, row
173 break-if-!=
174 var cursor-col/eax: (addr int) <- get target, cursor-col
175 compare *cursor-col, col
176 break-if-!=
177 start-blinking screen
178 start-color screen, 0, 1
179 }
180 var g/eax: grapheme <- screen-grapheme-at target, row, col
181 {
182 compare g, 0
183 break-if-!=
184 g <- copy 0x20
185 }
186 print-grapheme screen, g
187 reset-formatting screen
188 }
189
190 fn print-upper-border screen: (addr screen), width: int {
191 print-code-point screen, 0x250c
192 var i/eax: int <- copy 0
193 {
194 compare i, width
195 break-if->=
196 print-code-point screen, 0x2500
197 i <- increment
198 loop
199 }
200 print-code-point screen, 0x2510
201 }
202
203 fn print-lower-border screen: (addr screen), width: int {
204 print-code-point screen, 0x2514
205 var i/eax: int <- copy 0
206 {
207 compare i, width
208 break-if->=
209 print-code-point screen, 0x2500
210 i <- increment
211 loop
212 }
213 print-code-point screen, 0x2518
214 }
215
216 fn value-width _v: (addr value), top-level: boolean -> _/eax: int {
217 var v/esi: (addr value) <- copy _v
218 var type/eax: (addr int) <- get v, type
219 {
220 compare *type, 0
221 break-if-!=
222 var v-int/edx: (addr int) <- get v, int-data
223 var result/eax: int <- decimal-size *v-int
224 return result
225 }
226 {
227 compare *type, 1
228 break-if-!=
229 var s-ah/eax: (addr handle array byte) <- get v, text-data
230 var s/eax: (addr array byte) <- lookup *s-ah
231 compare s, 0
232 break-if-=
233 var result/eax: int <- length s
234 compare result, 0xd
235 {
236 break-if-<=
237 result <- copy 0xd
238 }
239
240
241
242 compare top-level, 0
243 {
244 break-if-!=
245 result <- add 2
246 }
247 return result
248 }
249 {
250 compare *type, 2
251 break-if-!=
252 var a-ah/eax: (addr handle array value) <- get v, array-data
253 var a/eax: (addr array value) <- lookup *a-ah
254 compare a, 0
255 break-if-=
256 var result/eax: int <- array-width a
257 return result
258 }
259 {
260 compare *type, 3
261 break-if-!=
262 var f-ah/eax: (addr handle buffered-file) <- get v, file-data
263 var f/eax: (addr buffered-file) <- lookup *f-ah
264 compare f, 0
265 break-if-=
266
267 return 4
268 }
269 {
270 compare *type, 4
271 break-if-!=
272 var screen-ah/eax: (addr handle screen) <- get v, screen-data
273 var screen/eax: (addr screen) <- lookup *screen-ah
274 compare screen, 0
275 break-if-=
276 var ncols/ecx: (addr int) <- get screen, num-cols
277 var result/eax: int <- copy *ncols
278 result <- add 2
279 return *ncols
280 }
281 return 0
282 }
283
284
285 fn array-width _a: (addr array value) -> _/eax: int {
286 var a/esi: (addr array value) <- copy _a
287 var max/ecx: int <- length a
288 var i/eax: int <- copy 0
289 var result/edi: int <- copy 0
290 {
291 compare i, max
292 break-if->=
293 {
294 compare i, 0
295 break-if-=
296 result <- increment
297 }
298 var off/ecx: (offset value) <- compute-offset a, i
299 var x/ecx: (addr value) <- index a, off
300 {
301 var w/eax: int <- value-width x, 0
302 result <- add w
303 }
304 i <- increment
305 loop
306 }
307
308
309 return result
310 }
311
312 fn value-height _v: (addr value) -> _/eax: int {
313 var v/esi: (addr value) <- copy _v
314 var type/eax: (addr int) <- get v, type
315 {
316 compare *type, 3
317 break-if-!=
318
319 return 1
320 }
321 {
322 compare *type, 4
323 break-if-!=
324 var screen-ah/eax: (addr handle screen) <- get v, screen-data
325 var screen/eax: (addr screen) <- lookup *screen-ah
326 compare screen, 0
327 break-if-=
328 var nrows/ecx: (addr int) <- get screen, num-rows
329 var result/eax: int <- copy *nrows
330 result <- add 2
331 return result
332 }
333 return 1
334 }
335
336 fn deep-copy-value _src: (addr value), _dest: (addr value) {
337
338 var src/esi: (addr value) <- copy _src
339 var dest/edi: (addr value) <- copy _dest
340 var type/ebx: (addr int) <- get src, type
341 var y/ecx: (addr int) <- get dest, type
342 copy-object type, y
343 compare *type, 0
344 {
345 break-if-!=
346
347 var x/eax: (addr int) <- get src, int-data
348 y <- get dest, int-data
349 copy-object x, y
350 return
351 }
352 compare *type, 1
353 {
354 break-if-!=
355
356 var src-ah/eax: (addr handle array byte) <- get src, text-data
357 var src/eax: (addr array byte) <- lookup *src-ah
358 var dest-ah/edx: (addr handle array byte) <- get dest, text-data
359 copy-array-object src, dest-ah
360 return
361 }
362 compare *type, 2
363 {
364 break-if-!=
365
366 var src-ah/eax: (addr handle array value) <- get src, array-data
367 var _src/eax: (addr array value) <- lookup *src-ah
368 var src/esi: (addr array value) <- copy _src
369 var n/ecx: int <- length src
370 var dest-ah/edx: (addr handle array value) <- get dest, array-data
371 populate dest-ah, n
372 var _dest/eax: (addr array value) <- lookup *dest-ah
373 var dest/edi: (addr array value) <- copy _dest
374 var i/eax: int <- copy 0
375 {
376 compare i, n
377 break-if->=
378 {
379 var offset/edx: (offset value) <- compute-offset src, i
380 var src-element/eax: (addr value) <- index src, offset
381 var dest-element/ecx: (addr value) <- index dest, offset
382 deep-copy-value src-element, dest-element
383 }
384 i <- increment
385 loop
386 }
387 copy-array-object src, dest-ah
388 return
389 }
390 compare *type, 3
391 {
392 break-if-!=
393
394 var src-filename-ah/eax: (addr handle array byte) <- get src, filename
395 var _src-filename/eax: (addr array byte) <- lookup *src-filename-ah
396 var src-filename/ecx: (addr array byte) <- copy _src-filename
397 var dest-filename-ah/ebx: (addr handle array byte) <- get dest, filename
398 copy-array-object src-filename, dest-filename-ah
399 var src-file-ah/eax: (addr handle buffered-file) <- get src, file-data
400 var src-file/eax: (addr buffered-file) <- lookup *src-file-ah
401 var dest-file-ah/edx: (addr handle buffered-file) <- get dest, file-data
402 copy-file src-file, dest-file-ah, src-filename
403 return
404 }
405 compare *type, 4
406 {
407 break-if-!=
408
409 var src-screen-ah/eax: (addr handle screen) <- get src, screen-data
410 var _src-screen/eax: (addr screen) <- lookup *src-screen-ah
411 var src-screen/ecx: (addr screen) <- copy _src-screen
412 var dest-screen-ah/eax: (addr handle screen) <- get dest, screen-data
413 allocate dest-screen-ah
414 var dest-screen/eax: (addr screen) <- lookup *dest-screen-ah
415 copy-object src-screen, dest-screen
416 var dest-screen-data-ah/ebx: (addr handle array screen-cell) <- get dest-screen, data
417 var src-screen-data-ah/eax: (addr handle array screen-cell) <- get src-screen, data
418 var src-screen-data/eax: (addr array screen-cell) <- lookup *src-screen-data-ah
419 copy-array-object src-screen-data, dest-screen-data-ah
420 return
421 }
422 }