6687 - stream-empty? and stream-full?

This commit is contained in:
Kartik Agaram 2020-07-30 19:34:29 -07:00
parent ca237761bf
commit 3001235028
6 changed files with 154 additions and 3 deletions

View File

@ -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

3
400.mu
View File

@ -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

11
401test.mu Normal file
View File

@ -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
}

View File

@ -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?"
}

BIN
apps/mu

Binary file not shown.

View File

@ -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