about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--066stream.mu38
-rw-r--r--lambda-to-mu.mu11
2 files changed, 30 insertions, 19 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
 ]
diff --git a/lambda-to-mu.mu b/lambda-to-mu.mu
index cda352a7..fdde50ef 100644
--- a/lambda-to-mu.mu
+++ b/lambda-to-mu.mu
@@ -170,17 +170,18 @@ scenario cell-operations-on-pair [
 def parse in:address:array:character -> out:address:cell [
   local-scope
   load-ingredients
-  s:address:stream <- new-stream in
+  s:address:stream:character <- new-stream in
   out, s <- parse s
   trace 2, [app/parse], out
 ]
 
-def parse in:address:stream -> out:address:cell, in:address:stream [
+def parse in:address:stream:character -> out:address:cell, in:address:stream:character [
   local-scope
   load-ingredients
   # skip whitespace
   in <- skip-whitespace in
-  c:character <- peek in
+  c:character, eof?:boolean <- peek in
+  reply-if eof?, 0/nil
   pair?:boolean <- equal c, 40/open-paren
   {
     break-if pair?
@@ -221,11 +222,11 @@ def parse in:address:stream -> out:address:cell, in:address:stream [
     # read in any remaining elements
     curr:address:cell <- copy out
     {
+      in <- skip-whitespace in
       end?:boolean <- end-of-stream? in
       not-end?:boolean <- not end?
       assert not-end?, [unbalanced '(' in expression]
       # termination check: ')'
-      in <- skip-whitespace in
       c <- peek in
       {
         close-paren?:boolean <- equal c, 41/close-paren
@@ -264,7 +265,7 @@ def parse in:address:stream -> out:address:cell, in:address:stream [
   }
 ]
 
-def skip-whitespace in:address:stream -> in:address:stream [
+def skip-whitespace in:address:stream:character -> in:address:stream:character [
   local-scope
   load-ingredients
   {