about summary refs log tree commit diff stats
path: root/apps
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-01-01 15:55:12 -0800
committerKartik Agaram <vc@akkartik.com>2020-01-01 15:55:12 -0800
commitdafef4e30fcfb53e6546ce0f53859bf9f1420dd2 (patch)
tree712ed1da30d3543b559b74703d319425873be525 /apps
parent612636182166a706ff1f64e1705a79ac233836fe (diff)
downloadmu-dafef4e30fcfb53e6546ce0f53859bf9f1420dd2.tar.gz
5849 - more integration testing of function calls
I can now run this program:

  fn main -> result/ebx: int {
    result <- do-add 3 4
  }

  fn do-add a: int, b: int -> result/ebx: int {
    result <- copy a
    result <- add b
  }

We still can't define local variables, but can write any programs involving
ints by passing in enough arguments for temporaries.
Diffstat (limited to 'apps')
-rwxr-xr-xapps/mubin74956 -> 77620 bytes
-rw-r--r--apps/mu.subx105
2 files changed, 98 insertions, 7 deletions
diff --git a/apps/mu b/apps/mu
index bef1a8b6..fa7209b5 100755
--- a/apps/mu
+++ b/apps/mu
Binary files differdiff --git a/apps/mu.subx b/apps/mu.subx
index 05e41346..7c056d46 100644
--- a/apps/mu.subx
+++ b/apps/mu.subx
@@ -246,7 +246,7 @@
 
 == data
 
-Program:  # (handle function)
+Program:  # (address (handle function))
   0/imm32
 
 Function-name:
@@ -860,13 +860,101 @@ test-convert-function-literal-arg-2:
     5d/pop-to-ebp
     c3/return
 
+test-convert-function-call-with-literal-arg:
+    # function writes to output
+    #   fn main -> result/ebx: int {
+    #     result <- do-add 3 4
+    #   }
+    #
+    #   fn do-add a: int, b: int -> result/ebx: int {
+    #     result <- copy a
+    #     result <- add b
+    #   }
+    # =>
+    #   main:
+    #     # . prologue
+    #     55/push-ebp
+    #     89/<- %ebp 4/r32/esp
+    #     {
+    #       (do-add 3 4)
+    #     }
+    #     # . epilogue
+    #     89/<- %esp 5/r32/ebp
+    #     5d/pop-to-ebp
+    #     c3/return
+    #   do-add:
+    #     # . prologue
+    #     55/push-ebp
+    #     89/<- %ebp 4/r32/esp
+    #     {
+    #       8b/-> *(ebp+8) 3/r32/ebx
+    #       03/add-to 3/r32/ebx *(ebp+0xc)
+    #     }
+    #     # . 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 main -> result/ebx: int {\n")
+    (write _test-input-stream "  result <- do-add 3 4\n")
+    (write _test-input-stream "}\n")
+    (write _test-input-stream "fn do-add a: int, b: int -> result/ebx: int {\n")
+    (write _test-input-stream "  result <- copy a\n")
+    (write _test-input-stream "  result <- add b\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 "main:"                 "F - test-convert-function-call-with-literal-arg/0")
+    (check-next-stream-line-equal _test-output-stream "# . prologue"          "F - test-convert-function-call-with-literal-arg/1")
+    (check-next-stream-line-equal _test-output-stream "55/push-ebp"           "F - test-convert-function-call-with-literal-arg/2")
+    (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp"  "F - test-convert-function-call-with-literal-arg/3")
+    (check-next-stream-line-equal _test-output-stream "{"                     "F - test-convert-function-call-with-literal-arg/4")
+    (check-next-stream-line-equal _test-output-stream "(do-add 3 4)"          "F - test-convert-function-call-with-literal-arg/5")
+    (check-next-stream-line-equal _test-output-stream "}"                     "F - test-convert-function-call-with-literal-arg/6")
+    (check-next-stream-line-equal _test-output-stream "# . epilogue"          "F - test-convert-function-call-with-literal-arg/7")
+    (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp"  "F - test-convert-function-call-with-literal-arg/8")
+    (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp"         "F - test-convert-function-call-with-literal-arg/9")
+    (check-next-stream-line-equal _test-output-stream "c3/return"             "F - test-convert-function-call-with-literal-arg/10")
+    (check-next-stream-line-equal _test-output-stream "do-add:"               "F - test-convert-function-call-with-literal-arg/11")
+    (check-next-stream-line-equal _test-output-stream "# . prologue"          "F - test-convert-function-call-with-literal-arg/12")
+    (check-next-stream-line-equal _test-output-stream "55/push-ebp"           "F - test-convert-function-call-with-literal-arg/13")
+    (check-next-stream-line-equal _test-output-stream "89/<- %ebp 4/r32/esp"  "F - test-convert-function-call-with-literal-arg/14")
+    (check-next-stream-line-equal _test-output-stream "{"                     "F - test-convert-function-call-with-literal-arg/15")
+    (check-next-stream-line-equal _test-output-stream "8b/copy-from *(ebp+0x00000008) 0x00000003/r32"  "F - test-convert-function-call-with-literal-arg/16")
+    (check-next-stream-line-equal _test-output-stream "03/add *(ebp+0x0000000c) 0x00000003/r32"  "F - test-convert-function-call-with-literal-arg/17")
+    (check-next-stream-line-equal _test-output-stream "}"                     "F - test-convert-function-call-with-literal-arg/18")
+    (check-next-stream-line-equal _test-output-stream "# . epilogue"          "F - test-convert-function-call-with-literal-arg/19")
+    (check-next-stream-line-equal _test-output-stream "89/<- %esp 5/r32/ebp"  "F - test-convert-function-call-with-literal-arg/20")
+    (check-next-stream-line-equal _test-output-stream "5d/pop-to-ebp"         "F - test-convert-function-call-with-literal-arg/21")
+    (check-next-stream-line-equal _test-output-stream "c3/return"             "F - test-convert-function-call-with-literal-arg/22")
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
 #######################################################
 # Parsing
 #######################################################
 
 parse-mu:  # in : (address buffered-file)
     # pseudocode
-    #   var curr-function : (handle function) = Program
+    #   var curr-function : (address (handle function)) = Program
     #   var line : (ref stream byte 512)
     #   var word-slice : (ref slice)
     #   while true                                  # line loop
@@ -908,7 +996,7 @@ parse-mu:  # in : (address buffered-file)
     68/push 0/imm32/end
     68/push 0/imm32/start
     89/<- %edx 4/r32/esp
-    # var curr-function/edi : (handle function) = Program
+    # var curr-function/edi : (address (handle function)) = Program
     bf/copy-to-edi Program/imm32
     # var vars/ebx : (ref stack (address var) 256)
     81 5/subop/subtract %esp 0x400/imm32
@@ -1077,6 +1165,8 @@ populate-mu-function-header:  # first-line : (address stream byte), out : (handl
     # save function name
     (slice-to-string Heap %ecx)  # => eax
     89/<- *edi 0/r32/eax  # Function-name
+    # initialize default subx-name as well
+    89/<- *(edi+4) 0/r32/eax  # Function-subx-name
     # save function inouts
     {
 $populate-mu-function-header:check-for-inout:
@@ -3077,7 +3167,7 @@ $emit-subx-block:check-empty:
 $emit-subx-block:stmt:
         81 7/subop/compare %esi 0/imm32
         74/jump-if-equal break/disp8
-        (emit-subx-statement *(ebp+8) *esi Primitives 0)
+        (emit-subx-statement *(ebp+8) *esi Primitives *Program)
         (write-buffered *(ebp+8) Newline)
         8b/-> *(esi+4) 6/r32/esi  # List-next
         eb/jump loop/disp8
@@ -4064,6 +4154,7 @@ emit-subx-call:  # out : (address buffered-file), stmt : (handle statement), cal
       (emit-subx-call-operand *(ebp+8) *ecx)
       # curr = curr->next
       8b/-> *(ecx+4) 1/r32/ecx
+      eb/jump loop/disp8
     }
     #
     (write-buffered *(ebp+8) ")")
@@ -4158,7 +4249,7 @@ find-matching-function:  # functions : (address function), stmt : (handle statem
         eb/jump $find-matching-function:end/disp8
       }
       # curr = curr->next
-      8b/-> *(ecx+0x10) 1/r32/ecx  # Function-next
+      8b/-> *(ecx+0x14) 1/r32/ecx  # Function-next
       eb/jump loop/disp8
     }
     # return null
@@ -4219,10 +4310,10 @@ mu-stmt-matches-function?:  # stmt : (handle statement), function : (handle func
     89/<- %ebp 4/r32/esp
     # . save registers
     51/push-ecx
-    # return primitive->name == stmt->operation
+    # return function->name == stmt->operation
     8b/-> *(ebp+8) 1/r32/ecx
     8b/-> *(ebp+0xc) 0/r32/eax
-    (string-equal? *(ecx+4) *eax)  # Stmt1-operation, Primitive-name => eax
+    (string-equal? *(ecx+4) *eax)  # Stmt1-operation, Function-name => eax
 $mu-stmt-matches-function?:end:
     # . restore registers
     59/pop-to-ecx