ocaml/camlp4/lib/fstream.ml

78 lines
1.6 KiB
OCaml

(* camlp4r *)
(* $Id$ *)
(* Copyright 2001 INRIA *)
type t 'a = { count : int; data : Lazy.t (data 'a) }
and data 'a =
[ Nil
| Cons of 'a and t 'a
| App of t 'a and t 'a ]
;
value from f =
loop 0 where rec loop i =
{count = 0;
data =
lazy
(match f i with
[ Some x -> Cons x (loop (i + 1))
| None -> Nil ])}
;
value rec next s =
let count = s.count + 1 in
match Lazy.force s.data with
[ Nil -> None
| Cons a s -> Some (a, {count = count; data = s.data})
| App s1 s2 ->
match next s1 with
[ Some (a, s1) -> Some (a, {count = count; data = lazy (App s1 s2)})
| None ->
match next s2 with
[ Some (a, s2) -> Some (a, {count = count; data = s2.data})
| None -> None ] ] ]
;
value empty s =
match next s with
[ Some _ -> None
| None -> Some ((), s) ]
;
value nil = {count = 0; data = lazy Nil};
value cons a s = Cons a s;
value app s1 s2 = App s1 s2;
value flazy f = {count = 0; data = Lazy.lazy_from_fun f};
value of_list l =
List.fold_right (fun x s -> flazy (fun () -> cons x s)) l nil
;
value of_string s =
from (fun c -> if c < String.length s then Some s.[c] else None)
;
value of_channel ic =
from (fun _ -> try Some (input_char ic) with [ End_of_file -> None ])
;
value iter f =
do_rec where rec do_rec strm =
match next strm with
[ Some (a, strm) ->
let _ = f a in
do_rec strm
| None -> () ]
;
value count s = s.count;
value count_unfrozen s =
loop 0 s where rec loop cnt s =
if Lazy.lazy_is_val s.data then
match Lazy.force s.data with
[ Cons _ s -> loop (cnt + 1) s
| _ -> cnt ]
else cnt
;