diff options
author | Kartik Agaram <vc@akkartik.com> | 2019-11-29 00:09:06 -0800 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2019-11-29 00:09:06 -0800 |
commit | 65b26ea169f638e57f5ae3ef523d1d180331215f (patch) | |
tree | 97b3212b7c38c0a5a8ef762806a84a778c8e278d /apps/mu.subx | |
parent | 31ed455886aefa1403d3fca2e2041a1786e75f2c (diff) | |
download | mu-65b26ea169f638e57f5ae3ef523d1d180331215f.tar.gz |
5774
Function headers seem to be parsing right.
Diffstat (limited to 'apps/mu.subx')
-rw-r--r-- | apps/mu.subx | 108 |
1 files changed, 82 insertions, 26 deletions
diff --git a/apps/mu.subx b/apps/mu.subx index d9fbac97..e768d5d7 100644 --- a/apps/mu.subx +++ b/apps/mu.subx @@ -324,6 +324,13 @@ Any-register: # "*" # data 2a/asterisk +List-value: + 0/imm32 +List-next: + 4/imm32 +List-size: + 8/imm32 + == code Entry: @@ -570,7 +577,8 @@ parse-mu: # in : (address buffered-file) # break # end of line # else if slice-equal(word-slice, "fn") # var new-function : (address function) = new function - # populate-mu-function(in, new-function) + # populate-mu-function-header(in, new-function) + # populate-mu-function-body(in, new-function) # *curr-function = new-function # curr-function = &new-function->next # else @@ -669,12 +677,39 @@ $parse-mu:abort: cd/syscall 0x80/imm8 # never gets here -# errors considered: -# fn foo { { -# fn foo { } -# fn foo { } { -# fn foo # no block +# scenarios considered: +# ✗ fn foo # no block +# ✓ fn foo { +# ✗ fn foo { { +# ✗ fn foo { } +# ✗ fn foo { } { +# ✗ fn foo x { +# ✗ fn foo x : { +# ✓ fn foo x : int { +# ✓ fn foo x: int { +# ✓ fn foo x: int -> y/eax: int { populate-mu-function-header: # first-line : (address stream byte), out : (address function) + # pseudocode: + # var name : slice = next-word(first-line) + # assert(name not in '{' '}' '->') + # out->name = slice-to-string(name) + # ## inouts + # while true + # ## name + # name = next-word(first-line) + # if (name == '{') goto done + # if (name == '->') break + # assert(name != '}') + # var v : (address var) = parse-var-with-type(name, first-line) + # out->inouts = new-list(v, out->inouts) + # ## outputs + # while true + # ## name + # name = next-word(first-line) + # assert(name not in '{' '}' '->') + # var v : (address var) = parse-var-with-type(name, first-line) + # done: + # # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -688,10 +723,8 @@ populate-mu-function-header: # first-line : (address stream byte), out : (addre 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp - # save function name + # read function name (next-word *(ebp+8) %ecx) - (slice-to-string Heap %ecx) # => eax - 89/<- *edi 0/r32/eax # Function-name # error checking # if (word-slice == '{') abort (slice-equal? %ecx "{") # => eax @@ -705,13 +738,16 @@ populate-mu-function-header: # first-line : (address stream byte), out : (addre (slice-equal? %ecx "}") # => eax 3d/compare-eax-and 0/imm32 0f 85/jump-if-not-equal $populate-mu-function-header:abort/disp32 + # save function name + (slice-to-string Heap %ecx) # => eax + 89/<- *edi 0/r32/eax # Function-name # save function inouts - # while (word-slice not in "{" "->") { - # if (word-slice == '{') break + (next-word *(ebp+8) %ecx) + # if (word-slice == '{') goto done (slice-equal? %ecx "{") # => eax 3d/compare-eax-and 0/imm32 - 75/jump-if-not-equal break/disp8 + 0f 85/jump-if-not-equal $populate-mu-function-header:done/disp32 # if (word-slice == '->') break (slice-equal? %ecx "->") # => eax 3d/compare-eax-and 0/imm32 @@ -721,19 +757,14 @@ populate-mu-function-header: # first-line : (address stream byte), out : (addre 3d/compare-eax-and 0/imm32 0f 85/jump-if-not-equal $populate-mu-function-header:abort/disp32 # - (next-word *(ebp+8) %ecx) + (parse-var-with-type %ecx *(ebp+8)) + (new-list Heap %eax *(edi+8)) # Function-inouts + 89/<- *(edi+8) 0/r32/eax # Function-inouts e9/jump loop/disp32 } - # if (word-slice == "->") skip it - { - (slice-equal? %ecx "->") # => eax - 3d/compare-eax-and 0/imm32 - 74/jump-if-equal break/disp8 - (next-word *(ebp+8) %ecx) - } # save function outputs - # while (word-slice not == "{") { + (next-word *(ebp+8) %ecx) # if (word-slice == '{') break (slice-equal? %ecx "{") # => eax 3d/compare-eax-and 0/imm32 @@ -747,9 +778,12 @@ populate-mu-function-header: # first-line : (address stream byte), out : (addre 3d/compare-eax-and 0/imm32 0f 85/jump-if-not-equal $populate-mu-function-header:abort/disp32 # - (next-word *(ebp+8) %ecx) + (parse-var-with-type %ecx *(ebp+8)) + (new-list Heap %eax *(edi+0xc)) # Function-outputs + 89/<- *(edi+0xc) 0/r32/eax # Function-outputs e9/jump loop/disp32 } +$populate-mu-function-header:done: # assert that there's no further token { # word-slice = next-word(line) @@ -760,7 +794,7 @@ populate-mu-function-header: # first-line : (address stream byte), out : (addre 75/jump-if-not-equal break/disp8 # if (slice-starts-with?(word-slice, "#")) break # . eax = *word-slice->start - 8b/-> *edx 0/r32/eax + 8b/-> *ecx 0/r32/eax 8a/copy-byte *eax 0/r32/AL 81 4/subop/and %eax 0xff/imm32 # . if (eax == '#') break @@ -883,7 +917,7 @@ parse-var-with-type: # name: slice, first-line: (address stream) -> result/eax: (slice-equal? %ecx ":") { 3d/compare-eax-and 0/imm32 - 74/jump-if-equal break/disp8 + 0f 84/jump-if-equal break/disp32 (next-word *(ebp+0xc) %ecx) # if (word-slice == '{') abort (slice-equal? %ecx "{") # => eax @@ -904,6 +938,8 @@ parse-var-with-type: # name: slice, first-line: (address stream) -> result/eax: $parse-var-with-type:end: # return result 89/<- %eax 7/r32/edi + # . reclaim locals + 81 0/subop/add %esp 8/imm32 # . restore registers 5f/pop-to-edi 5e/pop-to-esi @@ -1489,7 +1525,7 @@ $new-var:end: 5d/pop-to-ebp c3/return -new-block: # ad: allocation-descriptor, data: (address list statement) +new-block: # ad: allocation-descriptor, data: (address list statement) -> result/eax: (address statement) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -1575,7 +1611,7 @@ $new-regvardef:end: 5d/pop-to-ebp c3/return -new-named-block: # ad: allocation-descriptor, name: string, data: (address list statement) +new-named-block: # ad: allocation-descriptor, name: string, data: (address list statement) -> result/eax: (address statement) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -1596,6 +1632,26 @@ $new-named-block:end: 5d/pop-to-ebp c3/return +new-list: # ad: allocation-descriptor, value: _type, next: (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 + 8b/-> *(ebp+0x10) 1/r32/ecx + 89/<- *(eax+4) 1/r32/ecx # List-next +$new-list:end: + # . restore registers + 59/pop-to-ecx + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + ####################################################### # Type-checking ####################################################### |