diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-09-15 22:21:15 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-09-15 22:52:41 -0700 |
commit | ae470b42f102d5da4f7d4255a47e3cf582079f33 (patch) | |
tree | aa251ea7734370b9c152a5cf08a7b97c9c1de0c1 /apps | |
parent | 8815cf7d57e738731dfc43680b4eccbaef9d822c (diff) | |
download | mu-ae470b42f102d5da4f7d4255a47e3cf582079f33.tar.gz |
6781 - new app: RPN (postfix) calculator
This was surprisingly hard; bugs discovered all over the place.
Diffstat (limited to 'apps')
-rwxr-xr-x | apps/assort | bin | 44513 -> 44508 bytes | |||
-rwxr-xr-x | apps/braces | bin | 46376 -> 46371 bytes | |||
-rwxr-xr-x | apps/calls | bin | 51023 -> 51018 bytes | |||
-rwxr-xr-x | apps/crenshaw2-1 | bin | 43854 -> 43849 bytes | |||
-rwxr-xr-x | apps/crenshaw2-1b | bin | 44401 -> 44396 bytes | |||
-rwxr-xr-x | apps/dquotes | bin | 48135 -> 48130 bytes | |||
-rwxr-xr-x | apps/factorial | bin | 42957 -> 42952 bytes | |||
-rwxr-xr-x | apps/hex | bin | 46693 -> 46688 bytes | |||
-rwxr-xr-x | apps/mu | bin | 389400 -> 390307 bytes | |||
-rw-r--r-- | apps/mu.subx | 7 | ||||
-rwxr-xr-x | apps/pack | bin | 57092 -> 57087 bytes | |||
-rw-r--r-- | apps/rpn.mu | 149 | ||||
-rwxr-xr-x | apps/sigils | bin | 58745 -> 58740 bytes | |||
-rwxr-xr-x | apps/survey | bin | 54445 -> 54440 bytes | |||
-rwxr-xr-x | apps/tests | bin | 43285 -> 43299 bytes | |||
-rw-r--r-- | apps/tests.subx | 12 |
16 files changed, 168 insertions, 0 deletions
diff --git a/apps/assort b/apps/assort index 42c0c4d5..91acd903 100755 --- a/apps/assort +++ b/apps/assort Binary files differdiff --git a/apps/braces b/apps/braces index fefabcc8..04c119a4 100755 --- a/apps/braces +++ b/apps/braces Binary files differdiff --git a/apps/calls b/apps/calls index 443dc7f3..fcf9fa3e 100755 --- a/apps/calls +++ b/apps/calls Binary files differdiff --git a/apps/crenshaw2-1 b/apps/crenshaw2-1 index f26dedce..b47821fc 100755 --- a/apps/crenshaw2-1 +++ b/apps/crenshaw2-1 Binary files differdiff --git a/apps/crenshaw2-1b b/apps/crenshaw2-1b index 139327ca..59603ae2 100755 --- a/apps/crenshaw2-1b +++ b/apps/crenshaw2-1b Binary files differdiff --git a/apps/dquotes b/apps/dquotes index 302c3490..fe2b9da5 100755 --- a/apps/dquotes +++ b/apps/dquotes Binary files differdiff --git a/apps/factorial b/apps/factorial index 7e8edb63..424b6a84 100755 --- a/apps/factorial +++ b/apps/factorial Binary files differdiff --git a/apps/hex b/apps/hex index 75edad2d..5087ab7d 100755 --- a/apps/hex +++ b/apps/hex Binary files differdiff --git a/apps/mu b/apps/mu index 3ebe2ab7..8acd93f9 100755 --- a/apps/mu +++ b/apps/mu Binary files differdiff --git a/apps/mu.subx b/apps/mu.subx index 1b68350f..b3cb99de 100644 --- a/apps/mu.subx +++ b/apps/mu.subx @@ -14518,6 +14518,13 @@ size-of-type-id: # t: type-id -> result/eax: int b8/copy-to-eax 8/imm32 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int } + # if t is a slice, return 8 + 3d/compare-eax-and 0xc/imm32/slice + { + 75/jump-if-!= break/disp8 + b8/copy-to-eax 8/imm32 + eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int + } # if t is a user-defined type, return its size # TODO: support non-atom type (find-typeinfo %eax %ecx) diff --git a/apps/pack b/apps/pack index a6211a7d..ebae4f3a 100755 --- a/apps/pack +++ b/apps/pack Binary files differdiff --git a/apps/rpn.mu b/apps/rpn.mu new file mode 100644 index 00000000..5e2fdbb6 --- /dev/null +++ b/apps/rpn.mu @@ -0,0 +1,149 @@ +# Integer arithmetic using postfix notation +# +# Limitations: +# No division yet. +# +# To build: +# $ ./translate_mu apps/rpn.mu +# +# Example session: +# $ ./a.elf +# press ctrl-c or ctrl-d to exit +# > 1 +# 1 +# > 1 1 + +# 2 +# > 1 2 3 + + +# 6 +# > 1 2 3 * + +# 7 +# > 1 2 + 3 * +# 9 +# > 1 3 4 * + +# 13 +# > ^D +# $ +# +# Error handling is non-existent. This is just a prototype. + +fn main -> exit-status/ebx: int { + var in-storage: (stream byte 0x100) + var in/esi: (addr stream byte) <- address in-storage + print-string 0, "press ctrl-c or ctrl-d to exit\n" + # read-eval-print loop + { + # print prompt + print-string 0, "> " + # read line + clear-stream in + read-line-from-real-keyboard in + var done?/eax: boolean <- stream-empty? in + compare done?, 0 + break-if-!= + # parse and eval + var out/eax: int <- simplify in + # print + print-int32-decimal 0, out + print-string 0, "\n" + # + loop + } + exit-status <- copy 0 +} + +type int-stack { + data: (handle array int) + top: int +} + +fn simplify in: (addr stream byte) -> result/eax: int { + var word-storage: slice + var word/ecx: (addr slice) <- address word-storage + var stack-storage: int-stack + var stack/esi: (addr int-stack) <- address stack-storage + initialize-stack stack, 0x10 + $simplify:word-loop: { + next-word in, word + var done?/eax: boolean <- slice-empty? word + compare done?, 0 + break-if-!= + # if word is an operator, perform it + { + var is-add?/eax: boolean <- slice-equal? word, "+" + compare is-add?, 0 + break-if-= + var _b/eax: int <- pop-int-stack stack + var b/edx: int <- copy _b + var a/eax: int <- pop-int-stack stack + a <- add b + push-int-stack stack, a + loop $simplify:word-loop + } + { + var is-sub?/eax: boolean <- slice-equal? word, "-" + compare is-sub?, 0 + break-if-= + var _b/eax: int <- pop-int-stack stack + var b/edx: int <- copy _b + var a/eax: int <- pop-int-stack stack + a <- subtract b + push-int-stack stack, a + loop $simplify:word-loop + } + { + var is-mul?/eax: boolean <- slice-equal? word, "*" + compare is-mul?, 0 + break-if-= + var _b/eax: int <- pop-int-stack stack + var b/edx: int <- copy _b + var a/eax: int <- pop-int-stack stack + a <- multiply b + push-int-stack stack, a + loop $simplify:word-loop + } + # otherwise it's an int + var n/eax: int <- parse-decimal-int-from-slice word + push-int-stack stack, n + loop + } + result <- pop-int-stack stack +} + +fn initialize-stack _self: (addr int-stack), n: int { + var self/esi: (addr int-stack) <- copy _self + var d/edi: (addr handle array int) <- get self, data + populate d, n + var top/eax: (addr int) <- get self, top + copy-to *top, 0 +} + +fn push-int-stack _self: (addr int-stack), _val: int { + var self/esi: (addr int-stack) <- copy _self + var top-addr/ecx: (addr int) <- get self, top + var data-ah/edx: (addr handle array int) <- get self, data + var data/eax: (addr array int) <- lookup *data-ah + var top/edx: int <- copy *top-addr + var dest-addr/edx: (addr int) <- index data, top + var val/eax: int <- copy _val + copy-to *dest-addr, val + add-to *top-addr, 1 +} + +fn pop-int-stack _self: (addr int-stack) -> val/eax: int { +$pop-int-stack:body: { + var self/esi: (addr int-stack) <- copy _self + var top-addr/ecx: (addr int) <- get self, top + { + compare *top-addr, 0 + break-if-> + val <- copy 0 + break $pop-int-stack:body + } + subtract-from *top-addr, 1 + var data-ah/edx: (addr handle array int) <- get self, data + var data/eax: (addr array int) <- lookup *data-ah + var top/edx: int <- copy *top-addr + var result-addr/eax: (addr int) <- index data, top + val <- copy *result-addr +} +} diff --git a/apps/sigils b/apps/sigils index 82f4e43a..087caf38 100755 --- a/apps/sigils +++ b/apps/sigils Binary files differdiff --git a/apps/survey b/apps/survey index abb0d1f0..76cadf48 100755 --- a/apps/survey +++ b/apps/survey Binary files differdiff --git a/apps/tests b/apps/tests index 7a4df46d..8c013997 100755 --- a/apps/tests +++ b/apps/tests Binary files differdiff --git a/apps/tests.subx b/apps/tests.subx index 75f8ef22..d61ea137 100644 --- a/apps/tests.subx +++ b/apps/tests.subx @@ -80,6 +80,8 @@ subx-gen-run-tests: # in: (addr buffered-file), out: (addr buffered-file) # read-line-buffered(in, line) # if (line->write == 0) break # end of file # var word-slice = next-word(line) + # if slice-empty?(word-slice) # empty line + # continue # if is-label?(word-slice) # if slice-starts-with?(word-slice, "test-") # tests-found = true @@ -184,6 +186,16 @@ $subx-gen-run-tests:check0: e8/call next-word/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +$subx-gen-run-tests:check-empty: + # if slice-empty?(word-slice) break + # . eax = slice-empty?(word-slice) + 52/push-edx + e8/call slice-empty?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + # . if (eax != false) break + 3d/compare-eax-and 0/imm32/false + 75/jump-if-!= $subx-gen-run-tests:loop/disp8 $subx-gen-run-tests:check-for-label: # if (!is-label?(word-slice)) continue # . eax = is-label?(word-slice) |