6687 - stream-empty? and stream-full?
This commit is contained in:
parent
ca237761bf
commit
3001235028
|
@ -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
3
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
|
||||
|
|
|
@ -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
|
||||
}
|
25
403stream.mu
25
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?"
|
||||
}
|
||||
|
|
66
apps/mu.subx
66
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
|
||||
|
|
Loading…
Reference in New Issue