1
2 container stream:_elem [
3 index:num
4 data:&:@:_elem
5 ]
6
7 def new-stream s:&:@:_elem -> result:&:stream:_elem [
8 local-scope
9 load-ingredients
10 result <- new {(stream _elem): type}
11 *result <- put *result, index:offset, 0
12 *result <- put *result, data:offset, s
13 ]
14
15 def rewind in:&:stream:_elem -> in:&:stream:_elem [
16 local-scope
17 load-ingredients
18 *in <- put *in, index:offset, 0
19 ]
20
21 def read in:&:stream:_elem -> result:_elem, empty?:bool, in:&:stream:_elem [
22 local-scope
23 load-ingredients
24 empty? <- copy 0/false
25 idx:num <- get *in, index:offset
26 s:&:@:_elem <- get *in, data:offset
27 len:num <- length *s
28 at-end?:bool <- greater-or-equal idx len
29 {
30 break-unless at-end?
31 empty-result:&:_elem <- new _elem:type
32 return *empty-result, 1/true
33 }
34 result <- index *s, idx
35 idx <- add idx, 1
36 *in <- put *in, index:offset, idx
37 ]
38
39 def peek in:&:stream:_elem -> result:_elem, empty?:bool [
40 local-scope
41 load-ingredients
42 empty?:bool <- copy 0/false
43 idx:num <- get *in, index:offset
44 s:&:@:_elem <- get *in, data:offset
45 len:num <- length *s
46 at-end?:bool <- greater-or-equal idx len
47 {
48 break-unless at-end?
49 empty-result:&:_elem <- new _elem:type
50 return *empty-result, 1/true
51 }
52 result <- index *s, idx
53 ]
54
55 def read-line in:&:stream:char -> result:text, in:&:stream:char [
56 local-scope
57 load-ingredients
58 idx:num <- get *in, index:offset
59 s:text <- get *in, data:offset
60 next-idx:num <- find-next s, 10/newline, idx
61 result <- copy-range s, idx, next-idx
62 idx <- add next-idx, 1
63
64 *in <- put *in, index:offset, idx
65 ]
66
67 def end-of-stream? in:&:stream:_elem -> result:bool [
68 local-scope
69 load-ingredients
70 idx:num <- get *in, index:offset
71 s:&:@:_elem <- get *in, data:offset
72 len:num <- length *s
73 result <- greater-or-equal idx, len
74 ]