diff options
Diffstat (limited to 'apps')
-rwxr-xr-x | apps/mu | bin | 57992 -> 60284 bytes | |||
-rw-r--r-- | apps/mu.subx | 162 |
2 files changed, 159 insertions, 3 deletions
diff --git a/apps/mu b/apps/mu index 9f6c251d..a09943a1 100755 --- a/apps/mu +++ b/apps/mu Binary files differdiff --git a/apps/mu.subx b/apps/mu.subx index 4bfdb6a6..3cff705d 100644 --- a/apps/mu.subx +++ b/apps/mu.subx @@ -701,13 +701,14 @@ populate-mu-function-header: # first-line : (address stream byte), out : (addre # if (name == '->') break # assert(name != '}') # var v : (address var) = parse-var-with-type(name, first-line) - # out->inouts = new-list(v, out->inouts) + # out->inouts = append(out->inouts, v) # ## outputs # while true # ## name # name = next-word(first-line) # assert(name not in '{' '}' '->') # var v : (address var) = parse-var-with-type(name, first-line) + # out->outputs = append(out->outputs, v) # done: # # . prologue @@ -758,7 +759,7 @@ populate-mu-function-header: # first-line : (address stream byte), out : (addre 0f 85/jump-if-not-equal $populate-mu-function-header:abort/disp32 # (parse-var-with-type %ecx *(ebp+8)) - (new-list Heap %eax *(edi+8)) # Function-inouts + (append-list Heap %eax *(edi+8)) # Function-inouts 89/<- *(edi+8) 0/r32/eax # Function-inouts e9/jump loop/disp32 } @@ -779,7 +780,7 @@ populate-mu-function-header: # first-line : (address stream byte), out : (addre 0f 85/jump-if-not-equal $populate-mu-function-header:abort/disp32 # (parse-var-with-type %ecx *(ebp+8)) - (new-list Heap %eax *(edi+0xc)) # Function-outputs + (append-list Heap %eax *(edi+0xc)) # Function-outputs 89/<- *(edi+0xc) 0/r32/eax # Function-outputs e9/jump loop/disp32 } @@ -829,6 +830,125 @@ $populate-mu-function-header:abort: cd/syscall 0x80/imm8 # never gets here +test-function-header-with-arg: + # 'foo n : int {' + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # setup + (clear-stream _test-input-stream) + (write _test-input-stream "foo n : int {\n") + # result/ecx : (address function) + 2b/subtract-> *Function-size 4/r32/esp + 89/<- %ecx 4/r32/esp + (zero-out %ecx *Function-size) + # convert + (populate-mu-function-header _test-input-stream %ecx) + # check result + (check-string-equal *ecx "foo" "F - test-function-header-with-arg/name") # Function-name + # edx : (address list var) = result->inouts + 8b/-> *(ecx+8) 2/r32/edx # Function-inouts + # ebx : (address var) = result->inouts->value + 8b/-> *edx 3/r32/ebx # List-value + (check-string-equal *ebx "n" "F - test-function-header-with-arg/inout:0") # Var-name + (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/inout:0/type") # Var-type + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +test-function-header-with-multiple-args: + # 'fn foo a: int, b: int, c: int {' + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # setup + (clear-stream _test-input-stream) + (write _test-input-stream "foo a: int, b: int c: int {\n") + # result/ecx : (address function) + 2b/subtract-> *Function-size 4/r32/esp + 89/<- %ecx 4/r32/esp + (zero-out %ecx *Function-size) + # convert + (populate-mu-function-header _test-input-stream %ecx) + # check result + (check-string-equal *ecx "foo") # Function-name + # edx : (address list var) = result->inouts + 8b/-> *(ecx+8) 2/r32/edx # Function-inouts + # ebx : (address var) = result->inouts->value + 8b/-> *edx 3/r32/ebx # List-value + (check-string-equal *ebx "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name + (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/inout:0/type") # Var-type + # edx = result->inouts->next + 8b/-> *(edx+4) 2/r32/edx # List-next + # ebx = result->inouts->next->value + 8b/-> *edx 3/r32/ebx # List-value + (check-string-equal *ebx "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name + (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/inout:1/type") # Var-type + # edx = result->inouts->next->next + 8b/-> *(edx+4) 2/r32/edx # List-next + # ebx = result->inouts->next->next->value + 8b/-> *edx 3/r32/ebx # List-value + (check-string-equal *ebx "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name + (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/inout:2/type") # Var-type + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +test-function-with-multiple-args-and-outputs: + # fn foo a: int, b: int, c: int -> x: int, y: int { + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # setup + (clear-stream _test-input-stream) + (write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx : int {\n") + # result/ecx : (address function) + 2b/subtract-> *Function-size 4/r32/esp + 89/<- %ecx 4/r32/esp + (zero-out %ecx *Function-size) + # convert + (populate-mu-function-header _test-input-stream %ecx) + # check result + (check-string-equal *ecx "foo") # Function-name + # edx : (address list var) = result->inouts + 8b/-> *(ecx+8) 2/r32/edx # Function-inouts + # ebx : (address var) = result->inouts->value + 8b/-> *edx 3/r32/ebx # List-value + (check-string-equal *ebx "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name + (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/inout:0/type") # Var-type + # edx = result->inouts->next + 8b/-> *(edx+4) 2/r32/edx # List-next + # ebx = result->inouts->next->value + 8b/-> *edx 3/r32/ebx # List-value + (check-string-equal *ebx "b" "F - test-function-header-with-multiple-args/inout:1") # Var-name + (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/inout:1/type") # Var-type + # edx = result->inouts->next->next + 8b/-> *(edx+4) 2/r32/edx # List-next + # ebx = result->inouts->next->next->value + 8b/-> *edx 3/r32/ebx # List-value + (check-string-equal *ebx "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name + (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/inout:2/type") # Var-type + # edx : (address list var) = result->outputs + 8b/-> *(ecx+0xc) 2/r32/edx # Function-outputs + # ebx : (address var) = result->outputs->value + 8b/-> *edx 3/r32/ebx # List-value + (check-string-equal *ebx "x" "F - test-function-header-with-multiple-args/output:0") # Var-name + (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/output:0/type") # Var-type + (check-string-equal *(ebx+0x10) "ecx" "F - test-function-header-with-arg/output:0/register") # Var-register + # edx = result->outputs->next + 8b/-> *(edx+4) 2/r32/edx # List-next + # ebx = result->outputs->next->value + 8b/-> *edx 3/r32/ebx # List-value + (check-string-equal *ebx "y" "F - test-function-header-with-multiple-args/output:1") # Var-name + (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/output:1/type") # Var-type + (check-string-equal *(ebx+0x10) "edx" "F - test-function-header-with-arg/output:0/register") # Var-register + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + # format for variables with types # x : int # x: int @@ -1762,6 +1882,42 @@ $new-list:end: 5d/pop-to-ebp c3/return +append-list: # ad: allocation-descriptor, value: _type, list: (address list _type) -> result/eax : (address list _type) + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 51/push-ecx + # + (allocate *(ebp+8) *List-size) # => eax + 8b/-> *(ebp+0xc) 1/r32/ecx + 89/<- *eax 1/r32/ecx # List-value + # if (list == null) return result + 81 7/subop/compare *(ebp+0x10) 0/imm32 + 74/jump-if-equal $new-list:end/disp8 + # otherwise append + # var curr/ecx = list + 8b/-> *(ebp+0x10) 1/r32/ecx + # while (curr->next != null) curr = curr->next + { + 81 7/subop/compare *(ecx+4) 0/imm32 # List-next + 74/jump-if-equal break/disp8 + # curr = curr->next + 8b/-> *(ecx+4) 1/r32/ecx + eb/jump loop/disp8 + } + # curr->next = result + 89/<- *(ecx+4) 0/r32/eax + # return list + 8b/-> *(ebp+0x10) 0/r32/eax +$append-list:end: + # . restore registers + 59/pop-to-ecx + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + ####################################################### # Type-checking ####################################################### |