File: fstream.ml

package info (click to toggle)
camlp5 8.04.00-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,968 kB
  • sloc: ml: 137,918; makefile: 2,055; perl: 1,729; sh: 1,653; python: 38
file content (166 lines) | stat: -rw-r--r-- 3,355 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
(* camlp5r *)
(* fstream.ml,v *)
(* Copyright (c) INRIA 2007-2017 *)

exception Cut;;

type 'a mlazy_c =
    Lfun of (unit -> 'a)
  | Lval of 'a
;;
type 'a mlazy =
    Cval of 'a
  | Clazy of 'a mlazy_c ref
;;
let mlazy f = Clazy (ref (Lfun f));;
let mlazy_force l =
  match l with
    Cval v -> v
  | Clazy l ->
      match !l with
        Lfun f -> let x = f () in l := Lval x; x
      | Lval v -> v
;;
let mlazy_is_val l =
  match l with
    Cval _ -> true
  | Clazy l ->
      match !l with
        Lval _ -> true
      | Lfun _ -> false
;;

type 'a t = { count : int; data : 'a data mlazy }
and 'a data =
    Nil
  | Cons of 'a * 'a t
  | App of 'a t * 'a t
;;

let from f =
  let rec loop i =
    {count = 0;
     data =
       mlazy
         (fun () ->
            match f i with
              Some x -> Cons (x, loop (i + 1))
            | None -> Nil)}
  in
  loop 0
;;

let rec next s =
  let count = s.count + 1 in
  match mlazy_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 = mlazy (fun () -> App (s1, s2))})
      | None ->
          match next s2 with
            Some (a, s2) -> Some (a, {count = count; data = s2.data})
          | None -> None
;;

let empty s =
  match next s with
    Some _ -> None
  | None -> Some ((), s)
;;

let nil = {count = 0; data = Cval Nil};;
let cons a s = Cons (a, s);;
let app s1 s2 = App (s1, s2);;
let flazy f = {count = 0; data = mlazy f};;

let of_list l =
  List.fold_right (fun x s -> flazy (fun () -> cons x s)) l nil
;;

let of_string s =
  from (fun c -> if c < String.length s then Some s.[c] else None)
;;

let of_channel ic =
  from (fun _ -> try Some (input_char ic) with End_of_file -> None)
;;

let iter f =
  let rec do_rec strm =
    match next strm with
      Some (a, strm) -> let _ = f a in do_rec strm
    | None -> ()
  in
  do_rec
;;

let count s = s.count;;

let count_unfrozen s =
  let rec loop cnt s =
    if mlazy_is_val s.data then
      match mlazy_force s.data with
        Cons (_, s) -> loop (cnt + 1) s
      | _ -> cnt
    else cnt
  in
  loop 0 s
;;

(* backtracking parsers *)

type ('a, 'b) kont =
    K of (unit -> ('b * 'a t * ('a, 'b) kont) option)
;;
type ('a, 'b) bp = 'a t -> ('b * 'a t * ('a, 'b) kont) option;;

let bcontinue =
  function
    K k -> k ()
;;

let bparse_all p strm =
  let rec loop p =
    match p () with
      Some (r, _, K k) -> r :: loop k
    | None -> []
  in
  loop (fun () -> p strm)
;;

let b_seq a b strm =
  let rec app_a kont1 () =
    match kont1 () with
      Some (x, strm, K kont1) -> app_b (fun () -> b x strm) kont1 ()
    | None -> None
  and app_b kont2 kont1 () =
    match kont2 () with
      Some (y, strm, K kont2) -> Some (y, strm, K (app_b kont2 kont1))
    | None -> app_a kont1 ()
  in
  app_a (fun () -> a strm) ()
;;

let b_or a b strm =
  let rec loop kont () =
    match kont () with
      Some (x, strm, K kont) -> Some (x, strm, K (loop kont))
    | None -> b strm
  in
  loop (fun () -> a strm) ()
;;

let b_term f strm =
  match next strm with
    Some (x, strm) ->
      begin match f x with
        Some y -> Some (y, strm, K (fun _ -> None))
      | None -> None
      end
  | None -> None
;;

let b_act a strm = Some (a, strm, K (fun _ -> None));;