diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-07-30 19:34:29 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-07-30 19:34:29 -0700 |
commit | 30012350281844611bda2f4668f6a0b318a95b36 (patch) | |
tree | 56ac2b67b2dd02c3caa4aa02f47be9ea492349ad | |
parent | ca237761bf0f9b16838e2d3f7079d1725e3bd87b (diff) | |
download | mu-30012350281844611bda2f4668f6a0b318a95b36.tar.gz |
6687 - stream-empty? and stream-full?
-rw-r--r-- | 309stream.subx | 52 | ||||
-rw-r--r-- | 400.mu | 3 | ||||
-rw-r--r-- | 401test.mu | 11 | ||||
-rw-r--r-- | 403stream.mu | 25 | ||||
-rwxr-xr-x | apps/mu | bin | 365432 -> 366124 bytes | |||
-rw-r--r-- | apps/mu.subx | 66 |
6 files changed, 154 insertions, 3 deletions
diff --git a/309stream.subx b/309stream.subx index 3d38eda9..8e6d0fbf 100644 --- a/309stream.subx +++ b/309stream.subx @@ -1,7 +1,55 @@ # Some unsafe methods not intended to be used directly in SubX, only through # Mu after proper type-checking. -write-to-stream: # s: (addr stream), in: (addr byte), n: int +stream-empty?: # s: (addr stream _) -> result/eax: boolean + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 51/push-ecx + 56/push-esi + # result = false + b8/copy-to-eax 0/imm32/false + # esi = s + 8b/-> *(ebp+8) 6/r32/esi + # return s->read >= s->write + 8b/-> *esi 1/r32/ecx + 39/compare-with *(esi+4) 1/r32/ecx + 0f 9d/set-if->= %al +$stream-empty?:end: + # . restore registers + 5e/pop-to-esi + 59/pop-to-ecx + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +stream-full?: # s: (addr stream _) -> result/eax: boolean + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 51/push-ecx + 56/push-esi + # result = false + b8/copy-to-eax 0/imm32/false + # esi = s + 8b/-> *(ebp+8) 6/r32/esi + # return s->write >= s->size + 8b/-> *(esi+8) 1/r32/ecx + 39/compare-with *esi 1/r32/ecx + 0f 9d/set-if->= %al +$stream-full?:end: + # . restore registers + 5e/pop-to-esi + 59/pop-to-ecx + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +write-to-stream: # s: (addr stream _), in: (addr byte), n: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -54,7 +102,7 @@ $write-to-stream:abort: (syscall_exit) # never gets here -read-from-stream: # s: (addr stream), out: (addr byte), n: int +read-from-stream: # s: (addr stream _), out: (addr byte), n: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp diff --git a/400.mu b/400.mu index 369e29cd..bf63e87c 100644 --- a/400.mu +++ b/400.mu @@ -157,3 +157,6 @@ sig enable-keyboard-type-mode sig read-key -> result/eax: byte sig open filename: (addr array byte), write?: boolean, out: (addr handle buffered-file) #sig size in: (addr array _) -> result/eax: int + +sig stream-empty? s: (addr stream _) -> result/eax: boolean +sig stream-full? s: (addr stream _) -> result/eax: boolean diff --git a/401test.mu b/401test.mu new file mode 100644 index 00000000..65b765df --- /dev/null +++ b/401test.mu @@ -0,0 +1,11 @@ +# Some helpers for Mu tests. + +fn check-true val: boolean, msg: (addr array byte) { + var tmp/eax: int <- copy val + check-ints-equal tmp, 1, msg +} + +fn check-false val: boolean, msg: (addr array byte) { + var tmp/eax: int <- copy val + check-ints-equal tmp, 0, msg +} diff --git a/403stream.mu b/403stream.mu index e7661658..10e9e212 100644 --- a/403stream.mu +++ b/403stream.mu @@ -4,12 +4,37 @@ fn test-stream { # write an int to a stream, then read it back var s: (stream int 4) var s2/ecx: (addr stream int 4) <- address s + var tmp/eax: boolean <- stream-empty? s2 + check-true tmp, "F - test-stream/empty?/0" + tmp <- stream-full? s2 + check-false tmp, "F - test-stream/full?/0" var x: int copy-to x, 0x34 var x2/edx: (addr int) <- address x write-to-stream s2, x2 + tmp <- stream-empty? s2 + check-false tmp, "F - test-stream/empty?/1" + tmp <- stream-full? s2 + check-false tmp, "F - test-stream/full?/1" var y: int var y2/ebx: (addr int) <- address y read-from-stream s2, y2 check-ints-equal y, 0x34, "F - test-stream" + tmp <- stream-empty? s2 + check-true tmp, "F - test-stream/empty?/2" + tmp <- stream-full? s2 + check-false tmp, "F - test-stream/full?/2" +} + +fn test-stream-full { + # write an int to a stream of capacity 1 + var s: (stream int 1) + var s2/ecx: (addr stream int 1) <- address s + var tmp/eax: boolean <- stream-full? s2 + check-false tmp, "F - test-stream-full?/pre" + var x: int + var x2/edx: (addr int) <- address x + write-to-stream s2, x2 + tmp <- stream-full? s2 + check-true tmp, "F - test-stream-full?" } diff --git a/apps/mu b/apps/mu index a86811c9..8db17e84 100755 --- a/apps/mu +++ b/apps/mu Binary files differdiff --git a/apps/mu.subx b/apps/mu.subx index 3c64c467..2cc5d82a 100644 --- a/apps/mu.subx +++ b/apps/mu.subx @@ -1665,6 +1665,51 @@ test-convert-function-call-with-inout-with-multiple-type-parameters: 5d/pop-to-ebp c3/return +test-type-parameter-matches-rest-of-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) + (clear-stream _test-error-stream) + (clear-stream $_test-error-buffered-file->buffer) + # var ed/edx: exit-descriptor = tailor-exit-descriptor(16) + 68/push 0/imm32 + 68/push 0/imm32 + 89/<- %edx 4/r32/esp + (tailor-exit-descriptor %edx 0x10) + # + (write _test-input-stream "fn f {\n") + (write _test-input-stream " var x: (addr array int)\n") + (write _test-input-stream " g x\n") + (write _test-input-stream "}\n") + (write _test-input-stream "fn g a: (addr _) {\n") + (write _test-input-stream "}\n") + # convert + (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx) + # registers except esp clobbered at this point + # restore ed + 89/<- %edx 4/r32/esp + (flush _test-output-buffered-file) + (flush _test-error-buffered-file) +#? # dump _test-error-stream {{{ +#? (write 2 "^") +#? (write-stream 2 _test-error-stream) +#? (write 2 "$\n") +#? (rewind-stream _test-error-stream) +#? # }}} + # no errors + (check-stream-equal _test-error-stream "" "F - test-type-parameter-matches-rest-of-type: error stream should be empty") + # don't bother checking the generated code + # don't restore from ebp + 81 0/subop/add %esp 8/imm32 + # . epilogue + 5d/pop-to-ebp + c3/return + test-convert-function-call-with-inout-with-incompatible-type-parameters: # . prologue 55/push-ebp @@ -12780,7 +12825,7 @@ $type-component-match?:compare-addr: 39/compare %edx 0/r32/eax # Var-type b8/copy-to-eax 1/imm32/true 0f 84/jump-if-= $type-component-match?:end/disp32 - # if def is a type parameter, return true + # if def is a type parameter, just check in type-parameters { $type-component-match?:check-type-parameter: 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom @@ -12791,6 +12836,25 @@ $type-component-match?:type-parameter: (type-parameter-match? *(ecx+8) *(ecx+0xc) %edx *(ebp+0x10)) # => eax e9/jump $type-component-match?:end/disp32 } + # if def is a list containing just a type parameter, just check in type-parameters + { +$type-component-match?:check-list-type-parameter: + # if def is a list.. + 81 7/subop/compare *ecx 0/imm32/false # Type-tree-is-atom + 75/jump-if-!= break/disp8 + # ..that's a singleton + 81 7/subop/compare *(ecx+0xc) 0/imm32 # Type-tree-left + 75/jump-if-!= break/disp8 + # ..and whose head is a type parameter + (lookup *(ecx+4) *(ecx+8)) # Type-tree-left Type-tree-left => eax + 81 7/subop/compare *eax 0/imm32/false # Type-tree-is-atom + 74/jump-if-= break/disp8 + 81 7/subop/compare *(eax+4) 0xa/imm32/type-parameter # Type-tree-value + 75/jump-if-!= break/disp8 +$type-component-match?:list-type-parameter: + (type-parameter-match? *(eax+8) *(eax+0xc) %edx *(ebp+0x10)) # => eax + e9/jump $type-component-match?:end/disp32 + } $type-component-match?:compare-atom-state: # if (def->is-atom? != call->is-atom?) return false 8b/-> *ecx 3/r32/ebx # Type-tree-is-atom |