diff options
Diffstat (limited to 'apps/mu.subx')
-rw-r--r-- | apps/mu.subx | 102 |
1 files changed, 92 insertions, 10 deletions
diff --git a/apps/mu.subx b/apps/mu.subx index 241163fd..e82bda50 100644 --- a/apps/mu.subx +++ b/apps/mu.subx @@ -408,10 +408,12 @@ Typeinfo-id: # type-id # 2. the output var: a constant containing the byte offset; convenient for code-generation Typeinfo-fields: # (handle table string {(handle var), (handle var)}) 4/imm32 -Typeinfo-next: # (handle typeinfo) +Typeinfo-total-size-in-bytes: # int 8/imm32 -Typeinfo-size: # (addr int) +Typeinfo-next: # (handle typeinfo) 0xc/imm32 +Typeinfo-size: # (addr int) + 0x10/imm32 == code @@ -2023,6 +2025,54 @@ test-convert-function-and-type-definition: 5d/pop-to-ebp c3/return +test-convert-function-with-local-var-with-user-defined-type: + # . 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) + c7 0/subop/copy *Next-block-index 1/imm32 + # + (write _test-input-stream "fn foo {\n") + (write _test-input-stream " var a: t\n") + (write _test-input-stream "}\n") + (write _test-input-stream "type t {\n") + (write _test-input-stream " x: int\n") + (write _test-input-stream " y: int\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-with-local-var-with-user-defined-type/0") + (check-next-stream-line-equal _test-output-stream " # . prologue" "F - test-convert-function-with-local-var-with-user-defined-type/1") + (check-next-stream-line-equal _test-output-stream " 55/push-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/2") + (check-next-stream-line-equal _test-output-stream " 89/<- %ebp 4/r32/esp" "F - test-convert-function-with-local-var-with-user-defined-type/3") + (check-next-stream-line-equal _test-output-stream " {" "F - test-convert-function-with-local-var-with-user-defined-type/4") + (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:" "F - test-convert-function-with-local-var-with-user-defined-type/5") + (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/6") + (check-next-stream-line-equal _test-output-stream " 68/push 0/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/7") + (check-next-stream-line-equal _test-output-stream " 81 0/subop/add %esp 0x00000008/imm32" "F - test-convert-function-with-local-var-with-user-defined-type/8") + (check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-local-var-with-user-defined-type/9") + (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-local-var-with-user-defined-type/10") + (check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-local-var-with-user-defined-type/11") + (check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-local-var-with-user-defined-type/12") + (check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-local-var-with-user-defined-type/13") + (check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-local-var-with-user-defined-type/14") + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + ####################################################### # Parsing ####################################################### @@ -2618,6 +2668,10 @@ $parse-var-with-type:write-register: } $parse-var-with-type:save-type: (parse-type Heap *(ebp+0xc)) # => eax +#? (write-buffered Stderr "saving to var ") +#? (print-int32-buffered Stderr %edi) +#? (write-buffered Stderr Newline) +#? (flush Stderr) 89/<- *(edi+4) 0/r32/eax # Var-type $parse-var-with-type:end: # return result @@ -4951,7 +5005,7 @@ $find-or-create-typeinfo:create: 89/<- *(eax+4) 1/r32/ecx # result->next = Program->types 8b/-> *_Program-types 1/r32/ecx - 89/<- *(eax+8) 1/r32/ecx # Typeinfo-next + 89/<- *(eax+0xc) 1/r32/ecx # Typeinfo-next # Program->types = result 89/<- *_Program-types 0/r32/eax } @@ -4981,7 +5035,7 @@ find-typeinfo: # t: type-id -> result/eax: (handle typeinfo) 39/compare *eax 1/r32/ecx # Typeinfo-id 0f 84/jump-if-= $find-or-create-typeinfo:end/disp32 # curr = curr->next - 8b/-> *(eax+8) 0/r32/eax + 8b/-> *(eax+0xc) 0/r32/eax # Typeinfo-next # eb/jump loop/disp8 } @@ -5099,6 +5153,12 @@ $populate-mu-type:line-loop: 0f 85/jump-if-!= break/disp32 # var v/esi: (handle var) = parse-var-with-type(word-slice, first-line) (parse-var-with-type %edx %ecx) # => eax +#? (write-buffered Stderr "populate-mu-type: ") +#? (write-buffered Stderr *eax) # Var-name +#? (write-buffered Stderr " at ") +#? (print-int32-buffered Stderr %eax) +#? (write-buffered Stderr Newline) +#? (flush Stderr) 89/<- %esi 0/r32/eax # var r/eax: (addr {(handle var) (handle var)}) #? (write-buffered Stderr "populate-mu-type: typeinfo: ") @@ -5132,13 +5192,21 @@ $populate-mu-type:line-loop: #? (flush Stderr) 89/<- *(eax+0xc) 3/r32/ebx # curr-offset += size-of(v) +#? (write-buffered Stderr "elem ") +#? (write-buffered Stderr *eax) # Var-name 50/push-eax - (size-of %eax) # => eax + (size-of %esi) # => eax +#? (write-buffered Stderr ": ") +#? (print-int32-buffered Stderr %eax) # Var-name +#? (write-buffered Stderr Newline) +#? (flush Stderr) 01/add-to %ebx 0/r32/eax 58/pop-to-eax # e9/jump loop/disp32 } + # persist the total size of the type + 89/<- *(edi+8) 3/r32/ebx # Typeinfo-total-size-in-bytes $populate-mu-type:end: # . reclaim locals 81 0/subop/add %esp 0x214/imm32 @@ -5215,19 +5283,33 @@ $check-mu-types:end: 5d/pop-to-ebp c3/return -size-of: # v: (addr var) -> result/eax: int +size-of: # v: (handle var) -> result/eax: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp + # . save registers + 51/push-ecx + # ecx = v->type + 8b/-> *(ebp+8) 1/r32/ecx + 8b/-> *(ecx+4) 1/r32/ecx # Var-type # if v is a literal, return 0 - 8b/-> *(ebp+8) 0/r32/eax - 8b/-> *(eax+4) 0/r32/eax # Var-type - 81 7/subop/compare *eax 0/imm32 # Tree-left + 81 7/subop/compare *ecx 0/imm32 # Tree-left b8/copy-to-eax 0/imm32 74/jump-if-= $size-of:end/disp8 - # hard-coded since we only support 'int' types for now + # if v has a user-defined type, return its size + # TODO: support non-atom type + (find-typeinfo *ecx) # => eax + { + 3d/compare-eax-and 0/imm32 + 74/jump-if-= break/disp8 + 8b/-> *(eax+8) 0/r32/eax # Typeinfo-total-size-in-bytes + eb/jump $size-of:end/disp8 + } + # otherwise return the word size b8/copy-to-eax 4/imm32 $size-of:end: + # . restore registers + 59/pop-to-ecx # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp |