diff options
-rw-r--r-- | 301array-equal.subx | 46 | ||||
-rw-r--r-- | 400.mu | 2 | ||||
-rw-r--r-- | 405screen.mu | 19 | ||||
-rwxr-xr-x | apps/mu | bin | 422150 -> 422182 bytes | |||
-rw-r--r-- | apps/tile/data.mu | 1 | ||||
-rw-r--r-- | apps/tile/environment.mu | 28 | ||||
-rw-r--r-- | apps/tile/rpn.mu | 77 | ||||
-rw-r--r-- | apps/tile/value-stack.mu | 64 |
8 files changed, 194 insertions, 43 deletions
diff --git a/301array-equal.subx b/301array-equal.subx index c799f814..d020f5aa 100644 --- a/301array-equal.subx +++ b/301array-equal.subx @@ -171,7 +171,7 @@ test-compare-inequal-arrays-equal-sizes: 5d/pop-to-ebp c3/return -parse-array-of-ints: # ad: (addr allocation-descriptor), s: (addr string), out: (addr handle array int) +_parse-array-of-ints: # ad: (addr allocation-descriptor), s: (addr array byte), out: (addr handle array int) # pseudocode # end = &s->data[s->size] # curr = s->data @@ -216,25 +216,25 @@ parse-array-of-ints: # ad: (addr allocation-descriptor), s: (addr string), out: 01/add-to %edx 1/r32/ecx # var size/ebx: int = 0 31/xor-with %ebx 3/r32/ebx -$parse-array-of-ints:loop1: +$_parse-array-of-ints:loop1: # if (curr >= end) break 39/compare %ecx 2/r32/edx - 73/jump-if-addr>= $parse-array-of-ints:break1/disp8 + 73/jump-if-addr>= $_parse-array-of-ints:break1/disp8 # curr = skip-chars-matching-in-slice(curr, end, ' ') (skip-chars-matching-in-slice %ecx %edx 0x20) # => eax 89/<- %ecx 0/r32/eax # if (curr >= end) break 39/compare %ecx 2/r32/edx - 73/jump-if-addr>= $parse-array-of-ints:break1/disp8 + 73/jump-if-addr>= $_parse-array-of-ints:break1/disp8 # curr = skip-chars-not-matching-in-slice(curr, end, ' ') (skip-chars-not-matching-in-slice %ecx %edx 0x20) # => eax 89/<- %ecx 0/r32/eax # size += 4 81 0/subop/add %ebx 4/imm32 - eb/jump $parse-array-of-ints:loop1/disp8 -$parse-array-of-ints:break1: + eb/jump $_parse-array-of-ints:loop1/disp8 +$_parse-array-of-ints:break1: (allocate-array *(ebp+8) %ebx *(ebp+0x10)) -$parse-array-of-ints:pass2: +$_parse-array-of-ints:pass2: # var slice/edi: slice = {s->data, 0} 68/push 0/imm32/end 8d/copy-address *(esi+4) 7/r32/edi @@ -244,16 +244,16 @@ $parse-array-of-ints:pass2: 8b/-> *(ebp+0x10) 0/r32/eax (lookup *eax *(eax+4)) # => eax 8d/copy-address *(eax+4) 1/r32/ecx -$parse-array-of-ints:loop2: +$_parse-array-of-ints:loop2: # if (slice->start >= end) break 39/compare *edi 2/r32/edx - 73/jump-if-addr>= $parse-array-of-ints:end/disp8 + 73/jump-if-addr>= $_parse-array-of-ints:end/disp8 # slice->start = skip-chars-matching-in-slice(slice->start, end, ' ') (skip-chars-matching-in-slice *edi %edx 0x20) # => eax 89/<- *edi 0/r32/eax # if (slice->start >= end) break 39/compare *edi 2/r32/edx - 73/jump-if-addr>= $parse-array-of-ints:end/disp8 + 73/jump-if-addr>= $_parse-array-of-ints:end/disp8 # slice->end = skip-chars-not-matching-in-slice(slice->start, end, ' ') (skip-chars-not-matching-in-slice *edi %edx 0x20) # => eax 89/<- *(edi+4) 0/r32/eax @@ -265,8 +265,8 @@ $parse-array-of-ints:loop2: # slice->start = slice->end 8b/-> *(edi+4) 0/r32/eax 89/<- *edi 0/r32/eax - eb/jump $parse-array-of-ints:loop2/disp8 -$parse-array-of-ints:end: + eb/jump $_parse-array-of-ints:loop2/disp8 +$_parse-array-of-ints:end: # . reclaim locals 81 0/subop/add %esp 8/imm32 # . restore registers @@ -296,7 +296,7 @@ test-parse-array-of-ints: 68/push 0xc/imm32/size 89/<- %ecx 4/r32/esp # - (parse-array-of-ints Heap "1 2 3" %esi) + (_parse-array-of-ints Heap "1 2 3" %esi) (lookup *esi *(esi+4)) # => eax (array-equal? %ecx %eax) # => eax (check-ints-equal %eax 1 "F - test-parse-array-of-ints") @@ -315,7 +315,7 @@ test-parse-array-of-ints-empty: 68/push 0/imm32 89/<- %esi 4/r32/esp # - (parse-array-of-ints Heap "" %esi) + (_parse-array-of-ints Heap "" %esi) (lookup *esi *(esi+4)) # => eax (check-ints-equal *eax 0 "F - test-parse-array-of-ints-empty") # . epilogue @@ -333,7 +333,7 @@ test-parse-array-of-ints-just-whitespace: 68/push 0/imm32 89/<- %esi 4/r32/esp # - (parse-array-of-ints Heap Space %esi) + (_parse-array-of-ints Heap Space %esi) (lookup *esi *(esi+4)) # => eax (check-ints-equal *eax 0 "F - test-parse-array-of-ints-just-whitespace") # . epilogue @@ -356,7 +356,7 @@ test-parse-array-of-ints-extra-whitespace: 68/push 0xc/imm32/size 89/<- %ecx 4/r32/esp # - (parse-array-of-ints Heap " 1 2 3 " %esi) + (_parse-array-of-ints Heap " 1 2 3 " %esi) (lookup *esi *(esi+4)) # => eax (array-equal? %ecx %eax) # => eax (check-ints-equal %eax 1 "F - test-parse-array-of-ints-extra-whitespace") @@ -365,6 +365,18 @@ test-parse-array-of-ints-extra-whitespace: 5d/pop-to-ebp c3/return +parse-array-of-ints: # s: (addr array byte), out: (addr handle array int) + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # + (_parse-array-of-ints Heap *(ebp+8) *(ebp+0xc)) +$parse-array-of-ints:end: + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + # helper for later tests # compare an array with a string representation of an array literal check-array-equal: # a: (addr array int), expected: (addr string), msg: (addr string) @@ -379,7 +391,7 @@ check-array-equal: # a: (addr array int), expected: (addr string), msg: (addr s 68/push 0/imm32 89/<- %esi 4/r32/esp # var b/eax: (addr array int) = parse-array-of-ints(Heap, expected) - (parse-array-of-ints Heap *(ebp+0xc) %esi) + (parse-array-of-ints *(ebp+0xc) %esi) (lookup *esi *(esi+4)) # => eax # (array-equal? *(ebp+8) %eax) diff --git a/400.mu b/400.mu index 35fc88f0..87e43356 100644 --- a/400.mu +++ b/400.mu @@ -139,7 +139,7 @@ sig write-int out: (addr stream byte), n: int #sig pop s: (addr stack) -> n/eax: int #sig top s: (addr stack) -> n/eax: int sig array-equal? a: (addr array int), b: (addr array int) -> result/eax: boolean -sig parse-array-of-ints ad: (addr allocation-descriptor), s: (addr string), out: (addr handle array int) +sig parse-array-of-ints s: (addr array byte), out: (addr handle array int) sig check-array-equal a: (addr array int), expected: (addr string), msg: (addr string) #sig push-n-zero-bytes n: int sig kernel-string-to-string ad: (addr allocation-descriptor), in: (addr kernel-string), out: (addr handle array byte) diff --git a/405screen.mu b/405screen.mu index ba854e4a..201caba8 100644 --- a/405screen.mu +++ b/405screen.mu @@ -203,6 +203,25 @@ $print-string:body: { } } +fn print-array-of-ints-in-decimal screen: (addr screen), _a: (addr array int) { + var a/esi: (addr array int) <- 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 x/ecx: (addr int) <- index a, i + print-int32-decimal screen, *x + i <- increment + loop + } +} + fn print-grapheme screen: (addr screen), c: grapheme { $print-grapheme:body: { compare screen, 0 diff --git a/apps/mu b/apps/mu index 236b5d2a..d3607682 100755 --- a/apps/mu +++ b/apps/mu Binary files differdiff --git a/apps/tile/data.mu b/apps/tile/data.mu index f69ed645..7575461c 100644 --- a/apps/tile/data.mu +++ b/apps/tile/data.mu @@ -37,6 +37,7 @@ type value { type: int int-data: int # if type = 0 text-data: (handle array byte) # if type = 1 + array-data: (handle array int) # if type = 2 } type table { diff --git a/apps/tile/environment.mu b/apps/tile/environment.mu index bdf9574c..e37b32ba 100644 --- a/apps/tile/environment.mu +++ b/apps/tile/environment.mu @@ -424,6 +424,7 @@ $process-sandbox:body: { break $process-sandbox:body } # if start of word is quote and grapheme before cursor is not, just insert it as usual + # TODO: support string escaping { var first-grapheme/eax: grapheme <- first-grapheme cursor-word compare first-grapheme, 0x22 # double quote @@ -433,6 +434,17 @@ $process-sandbox:body: { break-if-= break $process-sandbox:space } + # if start of word is '[' and grapheme before cursor is not ']', just insert it as usual + # TODO: support nested arrays + { + var first-grapheme/eax: grapheme <- first-grapheme cursor-word + compare first-grapheme, 0x5b # '[' + break-if-!= + var final-grapheme/eax: grapheme <- grapheme-before-cursor cursor-word + compare final-grapheme, 0x5d # ']' + break-if-= + break $process-sandbox:space + } # otherwise insert word after and move cursor to it for the next key # (but we'll continue to track the current cursor-word for the rest of this function) append-word cursor-word-ah @@ -1352,6 +1364,14 @@ fn render-column screen: (addr screen), functions: (addr handle function), bindi print-string screen, val break $render-column:render-value } + { + compare *val-type, 2 # array + break-if-!= + var val-ah/eax: (addr handle array int) <- get val-addr, array-data + var val/eax: (addr array int) <- lookup *val-ah + render-array 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 @@ -1410,6 +1430,14 @@ fn render-integer screen: (addr screen), val: int, max-width: int { print-grapheme screen, 0x20 # space } +fn render-array screen: (addr screen), val: (addr array int) { + start-color screen, 0, 7 + # don't surround in spaces + print-grapheme screen, 0x5b # '[' + print-array-of-ints-in-decimal screen, val + print-grapheme screen, 0x5d # ']' +} + fn hash-color val: int -> result/eax: int { result <- try-modulo val, 7 # assumes that 7 is always the background color } diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu index 847a3a8c..ef53bb7e 100644 --- a/apps/tile/rpn.mu +++ b/apps/tile/rpn.mu @@ -65,30 +65,42 @@ fn evaluate functions: (addr handle function), bindings: (addr table), scratch: top <- decrement var dest-offset/edx: (offset value) <- compute-offset data, top var target-val/edx: (addr value) <- index data, dest-offset - # check target-val is a string + # check target-val is a string or array var target-type-addr/eax: (addr int) <- get target-val, type -#? print-string 0, "checking type: " -#? { -#? var foo/eax: int <- copy target-type-addr -#? print-int32-hex 0, foo -#? } -#? print-string 0, "\n" compare *target-type-addr, 1 # string - break-if-!= -#? print-string 0, "is string\n" - # compute length - var src-ah/eax: (addr handle array byte) <- get target-val, text-data - var src/eax: (addr array byte) <- lookup *src-ah - var result/ebx: int <- length src - # save result into target-val - var type-addr/eax: (addr int) <- get target-val, type - copy-to *type-addr, 0 # int - var target-string-ah/eax: (addr handle array byte) <- get target-val, text-data - var empty: (handle array byte) - copy-handle empty, target-string-ah - var target/eax: (addr int) <- get target-val, int-data - copy-to *target, result - break $evaluate:process-word + { + break-if-!= + # compute length + var src-ah/eax: (addr handle array byte) <- get target-val, text-data + var src/eax: (addr array byte) <- lookup *src-ah + var result/ebx: int <- length src + # save result into target-val + var type-addr/eax: (addr int) <- get target-val, type + copy-to *type-addr, 0 # int + var target-string-ah/eax: (addr handle array byte) <- get target-val, text-data + var empty: (handle array byte) + copy-handle empty, target-string-ah + var target/eax: (addr int) <- get target-val, int-data + copy-to *target, result + break $evaluate:process-word + } + compare *target-type-addr, 2 # array of ints + { + break-if-!= + # compute length + var src-ah/eax: (addr handle array int) <- get target-val, array-data + var src/eax: (addr array int) <- lookup *src-ah + var result/ebx: int <- length src + # save result into target-val + var type-addr/eax: (addr int) <- get target-val, type + copy-to *type-addr, 0 # int + var target-array-ah/eax: (addr handle array int) <- get target-val, array-data + var empty: (handle array int) + copy-handle empty, target-array-ah + var target/eax: (addr int) <- get target-val, int-data + copy-to *target, result + break $evaluate:process-word + } } # if curr-stream defines a binding, save top of stack to bindings { @@ -152,7 +164,7 @@ 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 + # if the word starts with a quote and ends with a quote, turn it into a string { var start/eax: byte <- stream-first curr-stream compare start, 0x22 # double-quote @@ -166,6 +178,25 @@ fn evaluate functions: (addr handle function), bindings: (addr table), scratch: push-string-to-value-stack out, *s break $evaluate:process-word } + # if the word starts with a '[' and ends with a ']', turn it into an array + { + var start/eax: byte <- stream-first curr-stream + compare start, 0x5b # '[' + break-if-!= + var end/eax: byte <- stream-final curr-stream + compare end, 0x5d # ']' + break-if-!= + # wastefully create a new string to strip quotes + var h: (handle array int) + var tmp-ah/eax: (addr handle array byte) <- address h + unquote-stream-to-string curr-stream, tmp-ah # leak + var tmp/eax: (addr array byte) <- lookup *tmp-ah + var h2: (handle array int) + var array-ah/ecx: (addr handle array int) <- address h2 + parse-array-of-ints tmp, array-ah # leak + push-array-to-value-stack out, *array-ah + 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 093e8846..dbe25b74 100644 --- a/apps/tile/value-stack.mu +++ b/apps/tile/value-stack.mu @@ -55,6 +55,27 @@ fn push-string-to-value-stack _self: (addr value-stack), val: (handle array byte increment *top-addr } +fn push-array-to-value-stack _self: (addr value-stack), val: (handle array int) { + 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 int) <- get dest-addr, array-data + copy-handle val, dest-addr2 + var dest-addr3/eax: (addr int) <- get dest-addr, type +#? print-string 0, "setting type to 1: " +#? { +#? var foo/eax: int <- copy dest-addr3 +#? print-int32-hex 0, foo +#? } +#? print-string 0, "\n" + copy-to *dest-addr3, 2 # type array + 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 @@ -123,7 +144,7 @@ fn value-stack-max-width _self: (addr value-stack) -> result/eax: int { var g/edx: (addr value) <- index data, o var type/eax: (addr int) <- get g, type { - compare *type, 0 + compare *type, 0 # int break-if-!= var g2/edx: (addr int) <- get g, int-data var w/eax: int <- decimal-size *g2 @@ -132,7 +153,7 @@ fn value-stack-max-width _self: (addr value-stack) -> result/eax: int { copy-to out, w } { - compare *type, 1 + compare *type, 1 # string break-if-!= var s-ah/eax: (addr handle array byte) <- get g, text-data var s/eax: (addr array byte) <- lookup *s-ah @@ -143,8 +164,47 @@ fn value-stack-max-width _self: (addr value-stack) -> result/eax: int { break-if-<= copy-to out, w } + { + compare *type, 2 # array + break-if-!= + var a-ah/eax: (addr handle array int) <- get g, array-data + var a/eax: (addr array int) <- lookup *a-ah + compare a, 0 + break-if-= + var w/eax: int <- array-decimal-size a + compare w, out + break-if-<= + copy-to out, w + } + i <- increment + loop + } + result <- copy out +} + +# keep sync'd with print-array-of-ints +fn array-decimal-size _a: (addr array int) -> result/eax: int { + var a/esi: (addr array int) <- copy _a + var max/ecx: int <- length a + var i/eax: int <- copy 0 + var out/edi: int <- copy 0 + { + compare i, max + break-if->= + { + compare i, 0 + break-if-= + out <- increment # for space + } + var x/ecx: (addr int) <- index a, i + { + var w/eax: int <- decimal-size *x + out <- add w + } i <- increment loop } result <- copy out + # we won't add 2 for surrounding brackets since we don't surround arrays in + # spaces like other value types } |