about summary refs log tree commit diff stats
path: root/apps
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-11-09 12:09:20 -0800
committerKartik Agaram <vc@akkartik.com>2019-11-09 12:09:20 -0800
commit364bd7edc2bc50259b12bdb9ecc8205dcbfbf886 (patch)
tree00d15ce4580de40365c04cb96584d1f3ad0e1032 /apps
parent34e01d7f26a0dbbc8bdaedc39bb181e861b2636c (diff)
downloadmu-364bd7edc2bc50259b12bdb9ecc8205dcbfbf886.tar.gz
5733
Diffstat (limited to 'apps')
-rw-r--r--apps/mu.subx71
1 files changed, 60 insertions, 11 deletions
diff --git a/apps/mu.subx b/apps/mu.subx
index 13ce5bf2..7ece54ae 100644
--- a/apps/mu.subx
+++ b/apps/mu.subx
@@ -171,6 +171,22 @@
 Program:  # (address function)
   0/imm32
 
+Function-name:
+  0/imm32
+Function-inouts:
+  4/imm32
+Function-outputs:
+  8/imm32
+Function-body:
+  0xc/imm32
+Function-next:
+  0x10/imm32
+Function-size:
+  0x14/imm32/20
+
+Var-name:
+  0/imm32
+
 == code
 
 Entry:
@@ -796,21 +812,20 @@ emit-subx-statement:  # out : (address buffered-file), stmt : (address statement
     # . save registers
     50/push-eax
     51/push-ecx
-    # var curr/ecx : (address primitive) = primitives
-    8b/-> *(ebp+0x18) 1/r32/ecx
+    # if statement doesn't match either a primitive or function, abort
     {
-      # if (curr != null) abort
-      81 7/subop/compare *(ebp+0xc) 0/imm32
-      0f 84/jump-if-equal $emit-subx-statement:abort/disp32
-      # if (match(curr, stmt)) break
-      (mu-stmt-matches-primitive? *(ebp+0xc) %ecx)  # => eax
+      # if find-matching-function(primitives, statement) break
+      (find-matching-function *(ebp+0x18) *(ebp+0xc))
       3d/compare-eax-and 0/imm32
       75/jump-if-not-equal break/disp8
-      # emit code for stmt according to curr and vars
-      # curr = curr->next
-      8b/-> *(ecx+0x10) 1/r32/ecx
-      e9/jump loop/disp32
+      # if find-matching-function(functions, statement) break
+      (find-matching-function *(ebp+0x20) *(ebp+0xc))
+      3d/compare-eax-and 0/imm32
+      75/jump-if-not-equal break/disp8
+      # abort
+      e9/jump $emit-subx-statement:abort/disp32
     }
+    # emit code for stmt according to curr and vars
 $emit-subx-statement:end:
     # . restore registers
     59/pop-to-ecx
@@ -832,6 +847,40 @@ $emit-subx-statement:abort:
     cd/syscall  0x80/imm8
     # never gets here
 
+find-matching-function:  # functions : (address function), stmt : (address statement) -> result/eax : (address function)
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    51/push-ecx
+    # var curr/ecx : (address function) = functions
+    8b/-> *(ebp+0xc) 1/r32/ecx
+    {
+      # if (curr == null) break
+      81 7/subop/compare %ecx 0/imm32
+      74/jump-if-equal break/disp8
+      # if match(curr, stmt) return curr
+      {
+        (mu-stmt-matches-primitive? *(ebp+0xc) %ecx)  # => eax
+        3d/compare-eax-and 0/imm32
+        74/jump-if-equal break/disp8
+        89/<- %eax 1/r32/ecx
+        eb/jump $find-matching-function:end/disp8
+      }
+      # curr = curr->next
+      8b/-> *(ecx+0x10) 1/r32/ecx
+      eb/jump loop/disp8
+    }
+    # return null
+    b8/copy-to-eax 0/imm32
+$find-matching-function:end:
+    # . restore registers
+    59/pop-to-ecx
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
 mu-stmt-matches-primitive?:  # stmt : (address statement), primitive : (address opcode-info) => result/eax : boolean
     # . prologue
     55/push-ebp