From 8a6ad45d8d26c60b62a2a7ac8d594b3c4d1dbc45 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sun, 25 Oct 2020 17:41:06 -0700 Subject: 7100 - tile: render string literals --- 309stream.subx | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 400.mu | 2 ++ apps/mu | Bin 421929 -> 422010 bytes apps/tile/data.mu | 1 + apps/tile/environment.mu | 32 +++++++++++++++++++++------ apps/tile/rpn.mu | 14 ++++++++++++ apps/tile/value-stack.mu | 34 +++++++++++++++++++++++++--- 7 files changed, 129 insertions(+), 10 deletions(-) diff --git a/309stream.subx b/309stream.subx index 84642def..adc92cfd 100644 --- a/309stream.subx +++ b/309stream.subx @@ -156,3 +156,59 @@ $read-from-stream:abort: bb/copy-to-ebx 1/imm32 (syscall_exit) # never gets here + +stream-first: # s: (addr stream byte) -> result/eax: byte + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 51/push-ecx + 56/push-esi + # result = false + b8/copy-to-eax 0/imm32 + # esi = s + 8b/-> *(ebp+8) 6/r32/esi + # var idx/ecx: int = s->read + 8b/-> *(esi+4) 1/r32/ecx + # if idx >= s->write return 0 + 3b/compare-with 1/r32/ecx *esi + 7d/jump-if->= $stream-first:end/disp8 + # result = s->data[idx] + 8a/byte-> *(esi+ecx+0xc) 0/r32/AL +$stream-first:end: + # . restore registers + 5e/pop-to-esi + 59/pop-to-ecx + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +stream-final: # s: (addr stream byte) -> result/eax: byte + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 51/push-ecx + 56/push-esi + # result = false + b8/copy-to-eax 0/imm32 + # esi = s + 8b/-> *(ebp+8) 6/r32/esi + # var max/ecx: int = s->write + 8b/-> *esi 1/r32/ecx + # if s->read >= max return 0 + 39/compare-with *(esi+4) 1/r32/ecx + 7d/jump-if->= $stream-final:end/disp8 + # var idx/ecx: int = max - 1 + 49/decrement-ecx + # result = s->data[idx] + 8a/byte-> *(esi+ecx+0xc) 0/r32/AL +$stream-final:end: + # . restore registers + 5e/pop-to-esi + 59/pop-to-ecx + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return diff --git a/400.mu b/400.mu index 93e6f03a..fb686e17 100644 --- a/400.mu +++ b/400.mu @@ -177,5 +177,7 @@ sig new-buffered-file out: (addr handle buffered-file) sig stream-empty? s: (addr stream _) -> result/eax: boolean sig stream-full? s: (addr stream _) -> result/eax: boolean sig stream-to-string in: (addr stream _), out: (addr handle array _) +sig stream-first s: (addr stream byte) -> result/eax: byte +sig stream-final s: (addr stream byte) -> result/eax: byte #sig copy-bytes src: (addr byte), dest: (addr byte), n: int diff --git a/apps/mu b/apps/mu index 6c1e8057..d713a6eb 100755 Binary files a/apps/mu and b/apps/mu differ diff --git a/apps/tile/data.mu b/apps/tile/data.mu index 18b7e7ce..f69ed645 100644 --- a/apps/tile/data.mu +++ b/apps/tile/data.mu @@ -36,6 +36,7 @@ type word { type value { type: int int-data: int # if type = 0 + text-data: (handle array byte) # if type = 1 } type table { diff --git a/apps/tile/environment.mu b/apps/tile/environment.mu index 2cc552c0..2b768c0a 100644 --- a/apps/tile/environment.mu +++ b/apps/tile/environment.mu @@ -1323,19 +1323,37 @@ fn render-column screen: (addr screen), functions: (addr handle function), bindi curr-row <- add 2 # stack-margin-top var _max-width/eax: int <- value-stack-max-width stack-addr max-width <- copy _max-width - var i/eax: int <- value-stack-length stack-addr { - compare i, 0 + var top-addr/ecx: (addr int) <- get stack-addr, top + compare *top-addr, 0 break-if-<= + decrement *top-addr move-cursor screen, curr-row, indented-col { - var val/eax: int <- pop-int-from-value-stack stack-addr -#? print-int32-decimal 0, val -#? print-string 0, "\n" - render-integer screen, val, max-width + var data-ah/eax: (addr handle array value) <- get stack-addr, data + var data/eax: (addr array value) <- lookup *data-ah + var top/edx: int <- copy *top-addr + var dest-offset/edx: (offset value) <- compute-offset data, top + var val-addr/eax: (addr value) <- index data, dest-offset + $render-column:render-value: { + var val-type/ecx: (addr int) <- get val-addr, type + # per-type rendering logic goes here + { + compare *val-type, 1 # string + break-if-!= + var val-ah/eax: (addr handle array byte) <- get val-addr, text-data + var val/eax: (addr array byte) <- lookup *val-ah + start-color screen, 0, 7 + print-grapheme screen, 0x20 # space + print-string screen, val + break $render-column:render-value + } + # render ints by default for now + var val-addr2/eax: (addr int) <- get val-addr, int-data + render-integer screen, *val-addr2, max-width + } } curr-row <- increment - i <- decrement loop } } diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu index 44108580..80ab47ae 100644 --- a/apps/tile/rpn.mu +++ b/apps/tile/rpn.mu @@ -99,6 +99,20 @@ fn evaluate functions: (addr handle function), bindings: (addr table), scratch: push-value-stack out, val break $evaluate:process-word } + # if the word starts with a quote and ends with a quote, return it directly + { + var start/eax: byte <- stream-first curr-stream + compare start, 0x22 # double-quote + break-if-!= + var end/eax: byte <- stream-final curr-stream + compare end, 0x22 # double-quote + break-if-!= + var h: (handle array byte) + var s/eax: (addr handle array byte) <- address h + stream-to-string curr-stream, s # leak + push-string-to-value-stack out, *s + break $evaluate:process-word + } # otherwise assume it's a literal int and push it { var n/eax: int <- parse-decimal-int-from-stream curr-stream diff --git a/apps/tile/value-stack.mu b/apps/tile/value-stack.mu index ba1a824d..aae87c3d 100644 --- a/apps/tile/value-stack.mu +++ b/apps/tile/value-stack.mu @@ -34,6 +34,21 @@ fn push-int-to-value-stack _self: (addr value-stack), _val: int { increment *top-addr } +fn push-string-to-value-stack _self: (addr value-stack), val: (handle array byte) { + var self/esi: (addr value-stack) <- copy _self + var top-addr/ecx: (addr int) <- get self, top + var data-ah/edx: (addr handle array value) <- get self, data + var data/eax: (addr array value) <- lookup *data-ah + var top/edx: int <- copy *top-addr + var dest-offset/edx: (offset value) <- compute-offset data, top + var dest-addr/edx: (addr value) <- index data, dest-offset + var dest-addr2/eax: (addr handle array byte) <- get dest-addr, text-data + copy-handle val, dest-addr2 + var dest-addr3/eax: (addr int) <- get dest-addr, type + copy-to *dest-addr3, 1 # type string + increment *top-addr +} + fn push-value-stack _self: (addr value-stack), val: (addr value) { var self/esi: (addr value-stack) <- copy _self var top-addr/ecx: (addr int) <- get self, top @@ -100,10 +115,23 @@ fn value-stack-max-width _self: (addr value-stack) -> result/eax: int { break-if->= var o/edx: (offset value) <- compute-offset data, i var g/edx: (addr value) <- index data, o - var g2/edx: (addr int) <- get g, int-data - var w/eax: int <- decimal-size *g2 - compare w, out + var type/eax: (addr int) <- get g, type + { + compare *type, 0 + break-if-!= + var g2/edx: (addr int) <- get g, int-data + var w/eax: int <- decimal-size *g2 + compare w, out + break-if-<= + copy-to out, w + } { + compare *type, 1 + break-if-!= + var s-ah/eax: (addr handle array byte) <- get g, text-data + var s/eax: (addr array byte) <- lookup *s-ah + var w/eax: int <- length s + compare w, out break-if-<= copy-to out, w } -- cgit 1.4.1-2-gfad0