diff options
Diffstat (limited to 'baremetal/shell')
-rw-r--r-- | baremetal/shell/eval.mu | 96 |
1 files changed, 95 insertions, 1 deletions
diff --git a/baremetal/shell/eval.mu b/baremetal/shell/eval.mu index 8b7ce63f..65fc179e 100644 --- a/baremetal/shell/eval.mu +++ b/baremetal/shell/eval.mu @@ -27,7 +27,7 @@ # If the final word is `break`, pop top of stack # # `{` and `}` don't affect evaluation -# If the final word is `{` or `}`, clear stack +# If the final word is `{` or `}`, clear stack (to suppress rendering it) # # If `->` in middle and top of stack is falsy, skip next word or group # @@ -170,6 +170,30 @@ fn evaluate _in: (addr line), end: (addr word), out: (addr value-stack) { } break $evaluate:process-word } + { + var is-group-start?/eax: boolean <- stream-data-equal? curr-stream, "{" + compare is-group-start?, 0/false + break-if-= + # if this is the final word, clear the stack + compare curr, end + { + break-if-!= + clear-value-stack out + } + break $evaluate:process-word + } + { + var is-group-start?/eax: boolean <- stream-data-equal? curr-stream, "}" + compare is-group-start?, 0/false + break-if-= + # if this is the final word, clear the stack + compare curr, end + { + break-if-!= + clear-value-stack out + } + break $evaluate:process-word + } ## TEMPORARY HACKS; we're trying to avoid turning this into Forth { var is-dup?/eax: boolean <- stream-data-equal? curr-stream, "dup" @@ -501,3 +525,73 @@ fn test-eval-conditional-skipped { var len/eax: int <- value-stack-length out check-ints-equal len, 0, "F - test-eval-conditional-skipped stack size" } + +# curlies have no effect in isolation +fn test-eval-group { + # in + var in-storage: line + var in/esi: (addr line) <- address in-storage + parse-line "{ 1 } 1 +", in + # end + var w-ah/eax: (addr handle word) <- get in, data + var end-h: (handle word) + var end-ah/ecx: (addr handle word) <- address end-h + final-word w-ah, end-ah + var end/eax: (addr word) <- lookup *end-ah + # out + var out-storage: value-stack + var out/edi: (addr value-stack) <- address out-storage + initialize-value-stack out, 8 + # + evaluate in, end, out + # + var len/eax: int <- value-stack-length out + check-ints-equal len, 1, "F - test-eval-group stack size" + var n/xmm0: float <- pop-number-from-value-stack out + var n2/eax: int <- convert n + check-ints-equal n2, 2, "F - test-eval-group result" +} + +fn test-eval-group-open-at-end { + # in + var in-storage: line + var in/esi: (addr line) <- address in-storage + parse-line "1 1 + {", in + # end + var w-ah/eax: (addr handle word) <- get in, data + var end-h: (handle word) + var end-ah/ecx: (addr handle word) <- address end-h + final-word w-ah, end-ah + var end/eax: (addr word) <- lookup *end-ah + # out + var out-storage: value-stack + var out/edi: (addr value-stack) <- address out-storage + initialize-value-stack out, 8 + # + evaluate in, end, out + # + var len/eax: int <- value-stack-length out + check-ints-equal len, 0, "F - test-eval-group-open-at-end stack size" +} + +fn test-eval-group-close-at-end { + # in + var in-storage: line + var in/esi: (addr line) <- address in-storage + parse-line "{ 1 1 + }", in + # end + var w-ah/eax: (addr handle word) <- get in, data + var end-h: (handle word) + var end-ah/ecx: (addr handle word) <- address end-h + final-word w-ah, end-ah + var end/eax: (addr word) <- lookup *end-ah + # out + var out-storage: value-stack + var out/edi: (addr value-stack) <- address out-storage + initialize-value-stack out, 8 + # + evaluate in, end, out + # + var len/eax: int <- value-stack-length out + check-ints-equal len, 0, "F - test-eval-group-close-at-end stack size" +} |