about summary refs log tree commit diff stats
path: root/066stream.mu
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-07-27 22:33:18 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-07-27 22:33:18 -0700
commit4f3510d05a144addc9612a046a1f2fa31a8a8c41 (patch)
tree014d681ff9f082d9e013b1b37302b1af82b9f56c /066stream.mu
parent814333e288a75af10fc39b8ca8d8eefcb855fb25 (diff)
downloadmu-4f3510d05a144addc9612a046a1f2fa31a8a8c41.tar.gz
3156
Make 'stream' generic.
Diffstat (limited to '066stream.mu')
-rw-r--r--066stream.mu38
1 files changed, 24 insertions, 14 deletions
diff --git a/066stream.mu b/066stream.mu
index 75685fd0..cd99e882 100644
--- a/066stream.mu
+++ b/066stream.mu
@@ -1,48 +1,58 @@
-# new type to help incrementally read texts (arrays of characters)
-container stream [
+# new type to help incrementally scan arrays
+container stream:_elem [
   index:number
-  data:address:array:character
+  data:address:array:_elem
 ]
 
-def new-stream s:address:array:character -> result:address:stream [
+def new-stream s:address:array:_elem -> result:address:stream:_elem [
   local-scope
   load-ingredients
-  result <- new stream:type
+  result <- new {(stream _elem): type}
   *result <- put *result, index:offset, 0
   *result <- put *result, data:offset, s
 ]
 
-def rewind in:address:stream -> in:address:stream [
+def rewind in:address:stream:_elem -> in:address:stream:_elem [
   local-scope
   load-ingredients
   *in <- put *in, index:offset, 0
 ]
 
-def read in:address:stream -> result:character, in:address:stream [
+def read in:address:stream:_elem -> result:_elem, empty?:boolean, in:address:stream:_elem [
   local-scope
   load-ingredients
+  empty? <- copy 0/false
   idx:number <- get *in, index:offset
-  s:address:array:character <- get *in, data:offset
+  s:address:array:_elem <- get *in, data:offset
   len:number <- length *s
   at-end?:boolean <- greater-or-equal idx len
-  return-if at-end?, 0/nul, in
+  {
+    break-unless at-end?
+    empty-result:address:_elem <- new _elem:type
+    return *empty-result, 1/true
+  }
   result <- index *s, idx
   idx <- add idx, 1
   *in <- put *in, index:offset, idx
 ]
 
-def peek in:address:stream -> result:character [
+def peek in:address:stream:_elem -> result:_elem, empty?:boolean [
   local-scope
   load-ingredients
+  empty?:boolean <- copy 0/false
   idx:number <- get *in, index:offset
   s:address:array:character <- get *in, data:offset
   len:number <- length *s
   at-end?:boolean <- greater-or-equal idx len
-  return-if at-end?, 0/nul
+  {
+    break-unless at-end?
+    empty-result:address:_elem <- new _elem:type
+    return *empty-result, 1/true
+  }
   result <- index *s, idx
 ]
 
-def read-line in:address:stream -> result:address:array:character, in:address:stream [
+def read-line in:address:stream:character -> result:address:array:character, in:address:stream:character [
   local-scope
   load-ingredients
   idx:number <- get *in, index:offset
@@ -54,11 +64,11 @@ def read-line in:address:stream -> result:address:array:character, in:address:st
   *in <- put *in, index:offset, idx
 ]
 
-def end-of-stream? in:address:stream -> result:boolean [
+def end-of-stream? in:address:stream:_elem -> result:boolean [
   local-scope
   load-ingredients
   idx:number <- get *in, index:offset
-  s:address:array:character <- get *in, data:offset
+  s:address:array:_elem <- get *in, data:offset
   len:number <- length *s
   result <- greater-or-equal idx, len
 ]