-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiterator.ml
69 lines (60 loc) · 1.63 KB
/
iterator.ml
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
open Async.Std
open States
module type SequenceIterator_intf =
sig
type t
(* sequence -> max in seq *)
val create : sequence -> int -> int -> t
val single : sequence -> bool
val next : t -> [`Ok of int|`End]
end
module SequenceIterator : SequenceIterator_intf with type t = sequence*int
ref*int ref*int ref*int*int =
struct
(* sequence, next element in sequence, current counter, max for the
counter, overal min and max for the mailbox *)
type t = sequence * int ref*int ref*int ref*int * int
let create seq min max = (seq,ref 0, ref 0, ref 0, min,max)
let single seq =
if Core.Std.List.length seq = 1 then
match (Core.Std.List.hd_exn seq) with
| SeqNumber sn ->
(
match sn with
| Number n -> true
| Wild -> false
)
| SeqRange _ -> false
else
false
let next t =
let s,nc,c,cmax,min,max = t in
let get_n m = function
| Number n -> n
| Wild -> m
in
let update mi mx =
c := mi;
cmax := mx;
`Ok !c
in
c := !c + 1;
if !c > !cmax then (
let seq = Core.Std.List.nth s !nc in
match seq with
| None -> `End
| Some seq ->
(
nc := !nc + 1; (* ref to the next element in the sequence *)
match seq with
| SeqNumber sn ->
(match sn with
| Number n -> update n n
| Wild -> update min max
)
| SeqRange (sn1,sn2) ->
update (get_n min sn1) (get_n max sn2)
)
) else
`Ok !c
end