diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-09-26 21:58:47 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-09-26 21:59:50 -0700 |
commit | ebb93c6d58ab087c581948acfc054e91a02047f9 (patch) | |
tree | c856a4a1e4ca7565983b2f5caf2a709bd1a3e31b | |
parent | 65e6633b79e97fdbaab37a47b8246d2726ae5907 (diff) | |
download | mu-ebb93c6d58ab087c581948acfc054e91a02047f9.tar.gz |
6870
Emit a stack of not ints but more complex objects containing the int payload. Function calls again segfaulting.
-rw-r--r-- | apps/tile/data.mu | 2 | ||||
-rw-r--r-- | apps/tile/environment.mu | 14 | ||||
-rw-r--r-- | apps/tile/main.mu | 12 | ||||
-rw-r--r-- | apps/tile/rpn.mu | 58 | ||||
-rw-r--r-- | apps/tile/table.mu | 18 | ||||
-rw-r--r-- | apps/tile/value-stack.mu | 64 |
6 files changed, 103 insertions, 65 deletions
diff --git a/apps/tile/data.mu b/apps/tile/data.mu index 31c9aa16..9b852a82 100644 --- a/apps/tile/data.mu +++ b/apps/tile/data.mu @@ -48,7 +48,7 @@ type table { type bind { key: (handle array byte) - value: value + value: (handle value) # I'd inline this but we sometimes want to return a specific value from a table } type result { diff --git a/apps/tile/environment.mu b/apps/tile/environment.mu index 906905d0..f85e7dd6 100644 --- a/apps/tile/environment.mu +++ b/apps/tile/environment.mu @@ -157,7 +157,7 @@ $process:body: { } } -fn evaluate-environment _env: (addr environment), stack: (addr int-stack) { +fn evaluate-environment _env: (addr environment), stack: (addr value-stack) { var env/esi: (addr environment) <- copy _env # program var program-ah/eax: (addr handle program) <- get env, program @@ -242,22 +242,22 @@ fn render-column screen: (addr screen), defs: (addr handle function), bindings: var indented-col/ebx: int <- copy left-col indented-col <- add 1 # margin-right - 2 for padding spaces # compute stack - var stack: int-stack - var stack-addr/edi: (addr int-stack) <- address stack - initialize-int-stack stack-addr, 0x10 # max-words + var stack: value-stack + var stack-addr/edi: (addr value-stack) <- address stack + initialize-value-stack stack-addr, 0x10 # max-words evaluate defs, bindings, scratch, final-word, stack-addr # render stack var curr-row/edx: int <- copy top-row curr-row <- add 3 # stack-margin-top - var _max-width/eax: int <- int-stack-max-width stack-addr + var _max-width/eax: int <- value-stack-max-width stack-addr var max-width/esi: int <- copy _max-width - var i/eax: int <- int-stack-length stack-addr + var i/eax: int <- value-stack-length stack-addr { compare i, 0 break-if-<= move-cursor screen, curr-row, indented-col { - var val/eax: int <- pop-int-stack stack-addr + var val/eax: int <- pop-int-from-value-stack stack-addr render-integer screen, val, max-width var size/eax: int <- decimal-size val compare size, max-width diff --git a/apps/tile/main.mu b/apps/tile/main.mu index afefc4b5..8d44ba80 100644 --- a/apps/tile/main.mu +++ b/apps/tile/main.mu @@ -67,24 +67,24 @@ fn repl { var env-storage: environment var env/esi: (addr environment) <- address env-storage initialize-environment env - var stack-storage: int-stack - var stack/edi: (addr int-stack) <- address stack-storage - initialize-int-stack stack, 0x10 + var stack-storage: value-stack + var stack/edi: (addr value-stack) <- address stack-storage + initialize-value-stack stack, 0x10 print-string-to-real-screen "> " $repl:loop: { var key/eax: grapheme <- read-key-from-real-keyboard print-grapheme-to-real-screen key compare key, 4 # ctrl-d break-if-= - compare key, 0xa # 'q' + compare key, 0xa # newline { break-if-!= evaluate-environment env, stack - var empty?/eax: boolean <- int-stack-empty? stack + var empty?/eax: boolean <- value-stack-empty? stack { compare empty?, 0 # false break-if-!= - var result/eax: int <- pop-int-stack stack + var result/eax: int <- pop-int-from-value-stack stack print-int32-decimal-to-real-screen result print-string-to-real-screen "\n" } diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu index 1d94d69f..ab3a623c 100644 --- a/apps/tile/rpn.mu +++ b/apps/tile/rpn.mu @@ -1,10 +1,10 @@ -fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr int-stack) { +fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr value-stack) { var line/eax: (addr line) <- copy scratch var word-ah/eax: (addr handle word) <- get line, data var curr/eax: (addr word) <- lookup *word-ah var curr-stream-storage: (stream byte 0x10) var curr-stream/edi: (addr stream byte) <- address curr-stream-storage - clear-int-stack out + clear-value-stack out $evaluate:loop: { # precondition (should never hit) compare curr, 0 @@ -19,33 +19,33 @@ fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr var is-add?/eax: boolean <- stream-data-equal? curr-stream, "+" compare is-add?, 0 break-if-= - var _b/eax: int <- pop-int-stack out + var _b/eax: int <- pop-int-from-value-stack out var b/edx: int <- copy _b - var a/eax: int <- pop-int-stack out + var a/eax: int <- pop-int-from-value-stack out a <- add b - push-int-stack out, a + push-int-to-value-stack out, a break $evaluate:process-word } { var is-sub?/eax: boolean <- stream-data-equal? curr-stream, "-" compare is-sub?, 0 break-if-= - var _b/eax: int <- pop-int-stack out + var _b/eax: int <- pop-int-from-value-stack out var b/edx: int <- copy _b - var a/eax: int <- pop-int-stack out + var a/eax: int <- pop-int-from-value-stack out a <- subtract b - push-int-stack out, a + push-int-to-value-stack out, a break $evaluate:process-word } { var is-mul?/eax: boolean <- stream-data-equal? curr-stream, "*" compare is-mul?, 0 break-if-= - var _b/eax: int <- pop-int-stack out + var _b/eax: int <- pop-int-from-value-stack out var b/edx: int <- copy _b - var a/eax: int <- pop-int-stack out + var a/eax: int <- pop-int-from-value-stack out a <- multiply b - push-int-stack out, a + push-int-to-value-stack out, a break $evaluate:process-word } # if curr-stream is a known function name, call it appropriately @@ -65,26 +65,26 @@ fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr break-if-= var tmp: (handle array byte) var curr-string-ah/edx: (addr handle array byte) <- address tmp - stream-to-string curr-stream, curr-string-ah - var _curr-string/eax: (addr array byte) <- lookup *curr-string-ah - var curr-string/edx: (addr array byte) <- copy _curr-string - var result/eax: int <- copy 0 - var found?/ecx: boolean <- copy 0 # false - result, found? <- lookup-binding bindings, curr-string - compare found?, 0 # false + stream-to-string curr-stream, curr-string-ah # unfortunate leak + var curr-string/eax: (addr array byte) <- lookup *curr-string-ah + var val-storage: (handle value) + var val-ah/edi: (addr handle value) <- address val-storage + lookup-binding bindings, curr-string, val-ah + var val/eax: (addr value) <- lookup *val-ah + compare val, 0 break-if-= #? print-string-to-real-screen "value of " #? print-string-to-real-screen curr-string #? print-string-to-real-screen " is " #? print-int32-hex-to-real-screen result #? print-string-to-real-screen "\n" - push-int-stack out, result + push-value-stack out, val 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 - push-int-stack out, n + push-int-to-value-stack out, n } } # termination check @@ -119,7 +119,7 @@ fn find-function first: (addr handle function), name: (addr stream byte), out: ( } } -fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs: (addr handle function) { +fn perform-call _callee: (addr function), caller-stack: (addr value-stack), defs: (addr handle function) { var callee/ecx: (addr function) <- copy _callee # create bindings for args var table-storage: table @@ -141,7 +141,7 @@ fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs: #? print-string-to-real-screen "binding " #? print-string-to-real-screen tmp #? print-string-to-real-screen " to " - var curr-val/eax: int <- pop-int-stack caller-stack + var curr-val/eax: int <- pop-int-from-value-stack caller-stack #? print-int32-decimal-to-real-screen curr-val #? print-string-to-real-screen "\n" bind-int-in-table table, curr-key, curr-val @@ -155,15 +155,15 @@ fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs: var body-ah/eax: (addr handle line) <- get callee, body var body/eax: (addr line) <- lookup *body-ah # perform call - var stack-storage: int-stack - var stack/edi: (addr int-stack) <- address stack-storage - initialize-int-stack stack, 0x10 -#? print-string-to-real-screen "about to enter recursive eval\n" + var stack-storage: value-stack + var stack/edi: (addr value-stack) <- address stack-storage + initialize-value-stack stack, 0x10 + print-string-to-real-screen "about to enter recursive eval\n" evaluate defs, table, body, 0, stack -#? print-string-to-real-screen "exited recursive eval\n" + print-string-to-real-screen "exited recursive eval\n" # stitch result from stack into caller - var result/eax: int <- pop-int-stack stack - push-int-stack caller-stack, result + var result/eax: int <- pop-int-from-value-stack stack + push-int-to-value-stack caller-stack, result } # Copy of 'simplify' that just tracks the maximum stack depth needed diff --git a/apps/tile/table.mu b/apps/tile/table.mu index 53fb5ce7..fc3a5399 100644 --- a/apps/tile/table.mu +++ b/apps/tile/table.mu @@ -40,22 +40,20 @@ fn make-binding _self: (addr bind), key: (addr handle array byte), _val: int { var self/esi: (addr bind) <- copy _self var dest/eax: (addr handle array byte) <- get self, key copy-object key, dest - var dest2/eax: (addr value) <- get self, value - var dest3/eax: (addr int) <- get dest2, scalar-data + var dest2/eax: (addr handle value) <- get self, value + var dest3/eax: (addr value) <- lookup *dest2 + var dest4/eax: (addr int) <- get dest3, scalar-data var val/ecx: int <- copy _val - copy-to *dest3, val + copy-to *dest4, val } -# TODO: supporting non-integers -# That'll require radical surgery. -fn lookup-binding _self: (addr table), key: (addr array byte) -> result/eax: int, found?/ecx: boolean { +fn lookup-binding _self: (addr table), key: (addr array byte), out: (addr handle value) { var self/esi: (addr table) <- copy _self var data-ah/esi: (addr handle array bind) <- get self, data var _data/eax: (addr array bind) <- lookup *data-ah var data/esi: (addr array bind) <- copy _data var len/edx: int <- length data var i/ebx: int <- copy 0 - found? <- copy 0 # false $lookup-binding:loop: { compare i, len break-if->= @@ -70,10 +68,8 @@ fn lookup-binding _self: (addr table), key: (addr array byte) -> result/eax: int compare is-match?, 0 # false break-if-= # found - found? <- copy 1 # true - var dest2/eax: (addr value) <- get target-bind, value - var dest3/eax: (addr int) <- get dest2, scalar-data - result <- copy *dest3 + var target/eax: (addr handle value) <- get target-bind, value + copy-object target, out break $lookup-binding:loop } i <- increment diff --git a/apps/tile/value-stack.mu b/apps/tile/value-stack.mu index f43cd25d..126ed036 100644 --- a/apps/tile/value-stack.mu +++ b/apps/tile/value-stack.mu @@ -1,3 +1,5 @@ +# support for non-int values is untested + type value-stack { data: (handle array value) top: int @@ -17,7 +19,22 @@ fn clear-value-stack _self: (addr value-stack) { copy-to *top, 0 } -fn push-value-stack _self: (addr value-stack), _val: value { +fn push-int-to-value-stack _self: (addr value-stack), _val: 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 int) <- get dest-addr, scalar-data + var val/esi: int <- copy _val +#? print-int32-hex-to-real-screen val + copy-to *dest-addr2, val + 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 var data-ah/edx: (addr handle array value) <- get self, data @@ -25,28 +42,28 @@ fn push-value-stack _self: (addr value-stack), _val: value { 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 val/eax: value <- copy _val - copy-to *dest-addr, val - add-to *top-addr, 1 + copy-object val, dest-addr + increment *top-addr } -fn pop-value-stack _self: (addr value-stack) -> val/eax: value { -$pop-value-stack:body: { +fn pop-int-from-value-stack _self: (addr value-stack) -> val/eax: int { +$pop-int-from-value-stack:body: { var self/esi: (addr value-stack) <- copy _self var top-addr/ecx: (addr int) <- get self, top { compare *top-addr, 0 break-if-> val <- copy -1 - break $pop-value-stack:body + break $pop-int-from-value-stack:body } - subtract-from *top-addr, 1 + decrement *top-addr 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 result-addr/eax: (addr value) <- index data, dest-offset - val <- copy *result-addr + var result-addr2/eax: (addr int) <- get result-addr, scalar-data + val <- copy *result-addr2 } } @@ -56,8 +73,8 @@ $value-stack-empty?:body: { var top/eax: (addr int) <- get self, top compare *top, 0 { - break-if-= - result <- copy 1 # false + break-if-!= + result <- copy 1 # true break $value-stack-empty?:body } result <- copy 0 # false @@ -69,3 +86,28 @@ fn value-stack-length _self: (addr value-stack) -> result/eax: int { var top-addr/eax: (addr int) <- get self, top result <- copy *top-addr } + +fn value-stack-max-width _self: (addr value-stack) -> result/eax: int { + var self/esi: (addr value-stack) <- copy _self + var data-ah/edi: (addr handle array value) <- get self, data + var _data/eax: (addr array value) <- lookup *data-ah + var data/edi: (addr array value) <- copy _data + var top-addr/ecx: (addr int) <- get self, top + var i/ebx: int <- copy 0 + result <- copy 0 + { + compare i, *top-addr + 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, scalar-data + var w/ecx: int <- int-width-decimal *g2 + compare w, result + { + break-if-<= + result <- copy w + } + i <- increment + loop + } +} |