diff options
Diffstat (limited to 'apps/tile/value.mu')
-rw-r--r-- | apps/tile/value.mu | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/apps/tile/value.mu b/apps/tile/value.mu new file mode 100644 index 00000000..db98e503 --- /dev/null +++ b/apps/tile/value.mu @@ -0,0 +1,208 @@ + +## Rendering values + +fn render-value screen: (addr screen), _val: (addr value), max-width: int { +$render-value:body: { + var val/esi: (addr value) <- copy _val + var val-type/ecx: (addr int) <- get val, type + # per-type rendering logic goes here + compare *val-type, 1 # string + { + break-if-!= + var val-ah/eax: (addr handle array byte) <- get val, text-data + var val-string/eax: (addr array byte) <- lookup *val-ah + compare val-string, 0 + break-if-= + var orig-len/ecx: int <- length val-string + var truncated: (handle array byte) + var truncated-ah/esi: (addr handle array byte) <- address truncated + substring val-string, 0, 0xc, truncated-ah + var truncated-string/eax: (addr array byte) <- lookup *truncated-ah +#? { +#? var foo/eax: int <- copy truncated-string +#? print-int32-hex 0, foo +#? print-string 0, "\n" +#? } + var len/edx: int <- length truncated-string + start-color screen, 0xf2, 7 + print-code-point screen, 0x275d # open-quote + print-string screen, truncated-string + compare len, orig-len + { + break-if-= + print-code-point screen, 0x2026 # ellipses + } + print-code-point screen, 0x275e # close-quote + reset-formatting screen + break $render-value:body + } + compare *val-type, 2 # array + { + break-if-!= + var val-ah/eax: (addr handle array value) <- get val, array-data + var val-array/eax: (addr array value) <- lookup *val-ah + render-array screen, val-array + break $render-value:body + } + compare *val-type, 3 # file + { + break-if-!= + var val-ah/eax: (addr handle buffered-file) <- get val, file-data + var val-file/eax: (addr buffered-file) <- lookup *val-ah + start-color screen, 0, 7 + # TODO + print-string screen, " FILE " + break $render-value:body + } + # render ints by default for now + var val-int/eax: (addr int) <- get val, int-data + render-integer screen, *val-int, max-width +} +} + +# synaesthesia +fn render-integer screen: (addr screen), val: int, max-width: int { +$render-integer:body: { + # if max-width is 0, we're inside an array. No coloring. + compare max-width, 0 + { + break-if-!= + print-int32-decimal screen, val + break $render-integer:body + } + var bg/eax: int <- hash-color val + var fg/ecx: int <- copy 7 + { + compare bg, 2 + break-if-!= + fg <- copy 0 + } + { + compare bg, 3 + break-if-!= + fg <- copy 0 + } + { + compare bg, 6 + break-if-!= + fg <- copy 0 + } + start-color screen, fg, bg + print-grapheme screen, 0x20 # space + print-int32-decimal-right-justified screen, val, max-width + print-grapheme screen, 0x20 # space +} +} + +fn render-array screen: (addr screen), _a: (addr array value) { + start-color screen, 0xf2, 7 + # don't surround in spaces + print-grapheme screen, 0x5b # '[' + var a/esi: (addr array value) <- copy _a + var max/ecx: int <- length a + var i/eax: int <- copy 0 + { + compare i, max + break-if->= + { + compare i, 0 + break-if-= + print-string screen, " " + } + var off/ecx: (offset value) <- compute-offset a, i + var x/ecx: (addr value) <- index a, off + render-value screen, x, 0 + i <- increment + loop + } + print-grapheme screen, 0x5d # ']' +} + +fn hash-color val: int -> _/eax: int { + var result/eax: int <- try-modulo val, 7 # assumes that 7 is always the background color + return result +} + +fn value-width _v: (addr value), top-level: boolean -> _/eax: int { + var v/esi: (addr value) <- copy _v + var type/eax: (addr int) <- get v, type + { + compare *type, 0 # int + break-if-!= + var v-int/edx: (addr int) <- get v, int-data + var result/eax: int <- decimal-size *v-int + return result + } + { + compare *type, 1 # string + break-if-!= + var s-ah/eax: (addr handle array byte) <- get v, text-data + var s/eax: (addr array byte) <- lookup *s-ah + compare s, 0 + break-if-= + var result/eax: int <- length s + compare result, 0xd # max string size + { + break-if-<= + result <- copy 0xd + } + # if it's a nested string, include space for quotes + # we don't do this for the top-level, where the quotes will overflow + # into surrounding padding. + compare top-level, 0 # false + { + break-if-!= + result <- add 2 + } + return result + } + { + compare *type, 2 # array + break-if-!= + var a-ah/eax: (addr handle array value) <- get v, array-data + var a/eax: (addr array value) <- lookup *a-ah + compare a, 0 + break-if-= + var result/eax: int <- array-width a + return result + } + { + compare *type, 3 # file handle + break-if-!= + var f-ah/eax: (addr handle buffered-file) <- get v, file-data + var f/eax: (addr buffered-file) <- lookup *f-ah + compare f, 0 + break-if-= + # TODO: visualizing file handles + return 4 + } + return 0 +} + +# keep sync'd with render-array +fn array-width _a: (addr array value) -> _/eax: int { + var a/esi: (addr array value) <- copy _a + var max/ecx: int <- length a + var i/eax: int <- copy 0 + var result/edi: int <- copy 0 + { + compare i, max + break-if->= + { + compare i, 0 + break-if-= + result <- increment # for space + } + var off/ecx: (offset value) <- compute-offset a, i + var x/ecx: (addr value) <- index a, off + { + var w/eax: int <- value-width x, 0 + result <- add w + } + i <- increment + loop + } + # we won't add 2 for surrounding brackets since we don't surround arrays in + # spaces like other value types + return result +} |