about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-12-31 21:58:52 -0800
committerKartik Agaram <vc@akkartik.com>2019-12-31 21:58:52 -0800
commita9baaac00b4bacfbee2986482ac0c37a7461927c (patch)
tree3f083db163d153b9d0356b0b5e77fc2ed0b74cae
parentf1344589daa99bfc247367280be3ea3588166c8a (diff)
downloadmu-a9baaac00b4bacfbee2986482ac0c37a7461927c.tar.gz
5847 - literal inputs
-rw-r--r--075print-int-decimal.subx101
-rwxr-xr-xapps/assortbin42800 -> 43152 bytes
-rwxr-xr-xapps/bracesbin42816 -> 43168 bytes
-rwxr-xr-xapps/callsbin47526 -> 47878 bytes
-rwxr-xr-xapps/crenshaw2-1bin42208 -> 42560 bytes
-rwxr-xr-xapps/crenshaw2-1bbin42755 -> 43107 bytes
-rwxr-xr-xapps/dquotesbin46450 -> 46802 bytes
-rwxr-xr-xapps/factorialbin41227 -> 41579 bytes
-rwxr-xr-xapps/handlebin42125 -> 42477 bytes
-rwxr-xr-xapps/hexbin45047 -> 45399 bytes
-rwxr-xr-xapps/mubin71441 -> 74956 bytes
-rw-r--r--apps/mu.subx208
-rwxr-xr-xapps/packbin55192 -> 55544 bytes
-rwxr-xr-xapps/sigilsbin55201 -> 55553 bytes
-rwxr-xr-xapps/surveybin52041 -> 52393 bytes
-rwxr-xr-xapps/testsbin41598 -> 41950 bytes
16 files changed, 308 insertions, 1 deletions
diff --git a/075print-int-decimal.subx b/075print-int-decimal.subx
index 8e8c7da4..6eba81a1 100644
--- a/075print-int-decimal.subx
+++ b/075print-int-decimal.subx
@@ -304,4 +304,105 @@ test-print-int32-decimal-negative-multiple-digits:
     # . end
     c3/return
 
+is-decimal-digit?:  # c : byte -> eax : boolean
+    # . prologue
+    55/push-ebp
+    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+    # . save registers
+    51/push-ecx
+    # ecx = c
+    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   8/disp8         .                 # copy *(ebp+8) to ecx
+    # return false if c < '0'
+    81          7/subop/compare     3/mod/direct    1/rm32/ecx    .           .             .           .           .               0x30/imm32        # compare ecx
+    7c/jump-if-lesser  $is-decimal-digit?:false/disp8
+    # return true if c <= '9'
+    81          7/subop/compare     3/mod/direct    1/rm32/ecx    .           .             .           .           .               0x39/imm32        # compare ecx
+    7e/jump-if-lesser-or-equal  $is-decimal-digit?:true/disp8
+    # otherwise return false
+$is-decimal-digit?:false:
+    b8/copy-to-eax  0/imm32/false
+    eb/jump $is-decimal-digit?:end/disp8
+$is-decimal-digit?:true:
+    b8/copy-to-eax  1/imm32/true
+$is-decimal-digit?:end:
+    # . restore registers
+    59/pop-to-ecx
+    # . epilogue
+    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+    5d/pop-to-ebp
+    c3/return
+
+test-is-decimal-digit-below-0:
+    # eax = is-decimal-digit?(0x2f)
+    # . . push args
+    68/push  0x2f/imm32
+    # . . call
+    e8/call  is-decimal-digit?/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+    # check-ints-equal(eax, 0, msg)
+    # . . push args
+    68/push  "F - test-is-decimal-digit-below-0"/imm32
+    68/push  0/imm32/false
+    50/push-eax
+    # . . call
+    e8/call  check-ints-equal/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+    c3/return
+
+test-is-decimal-digit-0-to-9:
+    # eax = is-decimal-digit?(0x30)
+    # . . push args
+    68/push  0x30/imm32
+    # . . call
+    e8/call  is-decimal-digit?/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+    # check-ints-equal(eax, 1, msg)
+    # . . push args
+    68/push  "F - test-is-decimal-digit-at-0"/imm32
+    68/push  1/imm32/true
+    50/push-eax
+    # . . call
+    e8/call  check-ints-equal/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+    # eax = is-decimal-digit?(0x39)
+    # . . push args
+    68/push  0x39/imm32
+    # . . call
+    e8/call  is-decimal-digit?/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+    # check-ints-equal(eax, 1, msg)
+    # . . push args
+    68/push  "F - test-is-decimal-digit-at-9"/imm32
+    68/push  1/imm32/true
+    50/push-eax
+    # . . call
+    e8/call  check-ints-equal/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+    c3/return
+
+test-is-decimal-digit-above-9:
+    # eax = is-decimal-digit?(0x3a)
+    # . . push args
+    68/push  0x3a/imm32
+    # . . call
+    e8/call  is-decimal-digit?/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+    # check-ints-equal(eax, 0, msg)
+    # . . push args
+    68/push  "F - test-is-decimal-digit-above-9"/imm32
+    68/push  0/imm32/false
+    50/push-eax
+    # . . call
+    e8/call  check-ints-equal/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+    c3/return
+
 # . . vim:nowrap:textwidth=0
diff --git a/apps/assort b/apps/assort
index b8cba438..c351c1d0 100755
--- a/apps/assort
+++ b/apps/assort
Binary files differdiff --git a/apps/braces b/apps/braces
index ef7eb54a..6d210604 100755
--- a/apps/braces
+++ b/apps/braces
Binary files differdiff --git a/apps/calls b/apps/calls
index 15bbc5db..023f3faf 100755
--- a/apps/calls
+++ b/apps/calls
Binary files differdiff --git a/apps/crenshaw2-1 b/apps/crenshaw2-1
index a579ee45..173e1f0f 100755
--- a/apps/crenshaw2-1
+++ b/apps/crenshaw2-1
Binary files differdiff --git a/apps/crenshaw2-1b b/apps/crenshaw2-1b
index a398a0bc..c960d67f 100755
--- a/apps/crenshaw2-1b
+++ b/apps/crenshaw2-1b
Binary files differdiff --git a/apps/dquotes b/apps/dquotes
index ae526a6c..d3bc8105 100755
--- a/apps/dquotes
+++ b/apps/dquotes
Binary files differdiff --git a/apps/factorial b/apps/factorial
index dd981d0d..90f5d904 100755
--- a/apps/factorial
+++ b/apps/factorial
Binary files differdiff --git a/apps/handle b/apps/handle
index 23993ca6..46571e0a 100755
--- a/apps/handle
+++ b/apps/handle
Binary files differdiff --git a/apps/hex b/apps/hex
index d349dea8..2e91f142 100755
--- a/apps/hex
+++ b/apps/hex
Binary files differdiff --git a/apps/mu b/apps/mu
index 16f01034..bef1a8b6 100755
--- a/apps/mu
+++ b/apps/mu
Binary files differdiff --git a/apps/mu.subx b/apps/mu.subx
index 624846a1..5f3513f4 100644
--- a/apps/mu.subx
+++ b/apps/mu.subx
@@ -742,6 +742,124 @@ test-convert-function-returns-result:
     5d/pop-to-ebp
     c3/return
 
+test-convert-function-literal-arg:
+    # function writes to output
+    #   fn foo a: int, b: int -> result/eax: int {
+    #     result <- copy a
+    #     result <- add 1
+    #   }
+    # =>
+    #   foo:
+    #     # . prologue
+    #     55/push-ebp
+    #     89/<- %ebp 4/r32/esp
+    #     {
+    #       89/-> *(ebp+8) 0/r32/eax
+    #       05/add-to-eax 1/imm32
+    #     }
+    #     # . epilogue
+    #     89/<- %esp 5/r32/ebp
+    #     5d/pop-to-ebp
+    #     c3/return
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # setup
+    (clear-stream _test-input-stream)
+    (clear-stream $_test-input-buffered-file->buffer)
+    (clear-stream _test-output-stream)
+    (clear-stream $_test-output-buffered-file->buffer)
+    #
+    (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n")
+    (write _test-input-stream "  result <- copy a\n")
+    (write _test-input-stream "  result <- add 1\n")
+    (write _test-input-stream "}\n")
+    # convert
+    (convert-mu _test-input-buffered-file _test-output-buffered-file)
+    (flush _test-output-buffered-file)
+#?     # dump _test-output-stream {{{
+#?     (write 2 "^")
+#?     (write-stream 2 _test-output-stream)
+#?     (write 2 "$\n")
+#?     (rewind-stream _test-output-stream)
+#?     # }}}
+    # check output
+    (check-next-stream-line-equal _test-output-stream "foo:"                  "F - test-convert-function-literal-arg/0")
+    (check-next-stream-line-equal _test-output-stream "# . prologue"          "F - test-convert-function-literal-arg/1")
+    (check-next-stream-line-equal _test-output-stream "55/push-ebp"           "F - test-convert-function-literal-arg/2")
+    (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp"  "F - test-convert-function-literal-arg/3")
+    (check-next-stream-line-equal _test-output-stream "{"                     "F - test-convert-function-literal-arg/4")
+    (check-next-stream-line-equal _test-output-stream "8b/copy-from *(ebp+0x00000008) 0x00000000/r32"  "F - test-convert-function-literal-arg/5")
+    (check-next-stream-line-equal _test-output-stream "05/add-to-eax 1/imm32"  "F - test-convert-function-literal-arg/6")
+    (check-next-stream-line-equal _test-output-stream "}"                     "F - test-convert-function-literal-arg/7")
+    (check-next-stream-line-equal _test-output-stream "# . epilogue"          "F - test-convert-function-literal-arg/8")
+    (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp"  "F - test-convert-function-literal-arg/9")
+    (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp"         "F - test-convert-function-literal-arg/10")
+    (check-next-stream-line-equal _test-output-stream "c3/return"             "F - test-convert-function-literal-arg/11")
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
+test-convert-function-literal-arg-2:
+    # function writes to output
+    #   fn foo a: int, b: int -> result/ebx: int {
+    #     result <- copy a
+    #     result <- add 1
+    #   }
+    # =>
+    #   foo:
+    #     # . prologue
+    #     55/push-ebp
+    #     89/<- %ebp 4/r32/esp
+    #     {
+    #       89/-> *(ebp+8) 3/r32/ebx
+    #       81 0/subop/add %ebx 1/imm32
+    #     }
+    #     # . epilogue
+    #     89/<- %esp 5/r32/ebp
+    #     5d/pop-to-ebp
+    #     c3/return
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # setup
+    (clear-stream _test-input-stream)
+    (clear-stream $_test-input-buffered-file->buffer)
+    (clear-stream _test-output-stream)
+    (clear-stream $_test-output-buffered-file->buffer)
+    #
+    (write _test-input-stream "fn foo a: int, b: int -> result/ebx: int {\n")
+    (write _test-input-stream "  result <- copy a\n")
+    (write _test-input-stream "  result <- add 1\n")
+    (write _test-input-stream "}\n")
+    # convert
+    (convert-mu _test-input-buffered-file _test-output-buffered-file)
+    (flush _test-output-buffered-file)
+#?     # dump _test-output-stream {{{
+#?     (write 2 "^")
+#?     (write-stream 2 _test-output-stream)
+#?     (write 2 "$\n")
+#?     (rewind-stream _test-output-stream)
+#?     # }}}
+    # check output
+    (check-next-stream-line-equal _test-output-stream "foo:"                  "F - test-convert-function-literal-arg-2/0")
+    (check-next-stream-line-equal _test-output-stream "# . prologue"          "F - test-convert-function-literal-arg-2/1")
+    (check-next-stream-line-equal _test-output-stream "55/push-ebp"           "F - test-convert-function-literal-arg-2/2")
+    (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp"  "F - test-convert-function-literal-arg-2/3")
+    (check-next-stream-line-equal _test-output-stream "{"                     "F - test-convert-function-literal-arg-2/4")
+    (check-next-stream-line-equal _test-output-stream "8b/copy-from *(ebp+0x00000008) 0x00000003/r32"  "F - test-convert-function-literal-arg-2/5")
+    (check-next-stream-line-equal _test-output-stream "81 0/subop/add %ebx 1/imm32"  "F - test-convert-function-literal-arg-2/6")
+    (check-next-stream-line-equal _test-output-stream "}"                     "F - test-convert-function-literal-arg-2/7")
+    (check-next-stream-line-equal _test-output-stream "# . epilogue"          "F - test-convert-function-literal-arg-2/8")
+    (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp"  "F - test-convert-function-literal-arg-2/9")
+    (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp"         "F - test-convert-function-literal-arg-2/10")
+    (check-next-stream-line-equal _test-output-stream "c3/return"             "F - test-convert-function-literal-arg-2/11")
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
 #######################################################
 # Parsing
 #######################################################
@@ -2237,7 +2355,7 @@ $parse-mu-stmt:read-inouts:
       3d/compare-eax-and 0/imm32
       0f 85/jump-if-not-equal $parse-mu-stmt:abort2/disp32
       #
-      (lookup-var %ecx *(ebp+0xc))  # => eax  # TODO: lookup-var-or-literal
+      (lookup-var-or-literal %ecx *(ebp+0xc))  # => eax
       (append-list Heap %eax *(edi+8))  # Stmt1-inouts => eax
       89/<- *(edi+8) 0/r32/eax  # Stmt1-inouts
       e9/jump loop/disp32
@@ -2326,6 +2444,55 @@ $stmt-has-outputs:end:
     5d/pop-to-ebp
     c3/return
 
+# if 'name' starts with a digit, create a new literal var for it
+# otherwise return first 'name' from the top (back) of 'vars' and abort if not found
+lookup-var-or-literal:  # name: (address slice), vars : (address stack (handle var)) -> result/eax: (handle var)
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    51/push-ecx
+    56/push-esi
+    # esi = name
+    8b/-> *(ebp+8) 6/r32/esi
+    # if slice-empty?(name) abort
+    (slice-empty? %esi)  # => eax
+    3d/compare-eax-and 0/imm32
+    0f 85/jump-if-not-equal $lookup-var-or-literal:abort/disp32
+    # var ecx : byte = *name->start
+    8b/-> *esi 1/r32/ecx
+    8a/copy-byte *ecx 1/r32/CL
+    81 4/subop/and %ecx 0xff/imm32
+    # if is-decimal-digit?(*name->start) return new var(name)
+    (is-decimal-digit? %ecx)  # => eax
+    81 7/subop/compare %eax 0/imm32
+    {
+      74/jump-if-equal break/disp8
+      (new-literal-integer Heap %esi)  # => eax
+    }
+    # otherwise return lookup-var(name, vars)
+    {
+      75/jump-if-not-equal break/disp8
+      (lookup-var %esi *(ebp+0xc))  # => eax
+    }
+$lookup-var-or-literal:end:
+    # . restore registers
+    5e/pop-to-esi
+    59/pop-to-ecx
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
+$lookup-var-or-literal:abort:
+    (write-buffered Stderr "empty variable!")
+    (flush Stderr)
+    # . syscall(exit, 1)
+    bb/copy-to-ebx  1/imm32
+    b8/copy-to-eax  1/imm32/exit
+    cd/syscall  0x80/imm8
+    # never gets here
+
 # return first 'name' from the top (back) of 'vars' and abort if not found
 lookup-var:  # name: (address slice), vars : (address stack (handle var)) -> result/eax: (handle var)
     # . prologue
@@ -2578,6 +2745,45 @@ $new-var:end:
     5d/pop-to-ebp
     c3/return
 
+new-literal-integer:  # ad: (address allocation-descriptor), name: (address slice) -> result/eax: (handle var)
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    51/push-ecx
+    # if (!is-hex-int?(name)) abort
+    (is-hex-int? *(ebp+0xc))  # => eax
+    3d/compare-eax-and 0/imm32
+    0f 84/jump-if-equal $new-literal-integer:abort/disp32
+    # var s/ecx : (address array byte)
+    (slice-to-string Heap *(ebp+0xc))  # => eax
+    89/<- %ecx 0/r32/eax
+    #
+    (allocate *(ebp+8) *Var-size)  # => eax
+    89/<- *eax 1/r32/ecx  # Var-name
+    c7 0/subop/copy *(eax+4) 0/imm32/tag/literal  # Var-type
+    c7 0/subop/copy *(eax+8) 0/imm32  # Var-block
+    c7 0/subop/copy *(eax+0xc) 0/imm32  # Var-stack-offset
+    c7 0/subop/copy *(eax+0x10) 0/imm32  # Var-register
+$new-literal-integer:end:
+    # . restore registers
+    59/pop-to-ecx
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
+$new-literal-integer:abort:
+    (write-buffered Stderr "variable cannot begin with a digit '")
+    (write-slice-buffered Stderr *(ebp+0xc))
+    (write-buffered Stderr "'\n")
+    (flush Stderr)
+    # . syscall(exit, 1)
+    bb/copy-to-ebx  1/imm32
+    b8/copy-to-eax  1/imm32/exit
+    cd/syscall  0x80/imm8
+    # never gets here
+
 new-block:  # ad: (address allocation-descriptor), data: (handle list statement) -> result/eax: (handle statement)
     # . prologue
     55/push-ebp
diff --git a/apps/pack b/apps/pack
index 005c42f8..18eec14c 100755
--- a/apps/pack
+++ b/apps/pack
Binary files differdiff --git a/apps/sigils b/apps/sigils
index a1f33ada..53166e58 100755
--- a/apps/sigils
+++ b/apps/sigils
Binary files differdiff --git a/apps/survey b/apps/survey
index 2ec38e5d..f0a911d4 100755
--- a/apps/survey
+++ b/apps/survey
Binary files differdiff --git a/apps/tests b/apps/tests
index b292f93b..fcbde7e2 100755
--- a/apps/tests
+++ b/apps/tests
Binary files differ