-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStream.ml
More file actions
72 lines (62 loc) · 2.32 KB
/
Copy pathStream.ml
File metadata and controls
72 lines (62 loc) · 2.32 KB
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
open Errors
open Result
let of_string s =
let n = String.length s in
let rec loop i =
if i = n then [] else s.[i] :: loop (i + 1)
in
loop 0
let of_chars chars =
let buf = Buffer.create 16 in
List.iter (Buffer.add_char buf) chars;
Buffer.contents buf
class stream (s : char list) =
object (self : 'self)
val p = 0
val errors = Errors.empty
method errors = errors
method pos = p
method str = of_chars s
method chrs = s
method rest =
let rec f l p' = if (p' = 0) then l else f (List.tl l) (p' - 1)
in of_chars (f s p)
method equal : stream -> bool =
fun s' -> (s = s' # chrs) && (p = s' # pos) && (Errors.equal errors (s' # errors))
method look : 'b . string -> (string -> 'self -> ('b, 'self) result) -> ('b, 'self) result =
fun cs k ->
let rec loop chars result =
match chars with
| [] -> k (of_chars result)
| c :: tail -> fun s -> s # lookChar c (fun res s' -> loop tail (res :: result) s')
in loop (of_string cs) [] self
method lookChar : 'b . char -> (char -> 'self -> ('b, 'self) result) -> ('b, 'self) result =
fun c k ->
try
if c = List.nth s p
then k c {< p = p + 1 >}
else begin
let err1 = Errors.Delete (List.nth s p, p) in
let err2 = Errors.Replace (c, p) in
let res1 = (match ({< p = p + 1; errors = Errors.addError err1 errors >} # lookChar c k) with
| Parsed (res, _) -> Failed (Some (res, err1))
| Failed x -> Failed x) in
let res2 = (match (k c {< p = p + 1; errors = Errors.addError err2 errors>}) with
| Parsed (res, _) -> Failed (Some (res, err2))
| Failed x -> Failed x) in
res1 <@> res2 (*
({< p = p + 1; errors = Errors.addError (Errors.Delete (List.nth s p, p)) errors >} # look c k) <@>
(k c {< p = p + 1; errors = Errors.addError (Errors.Replace (c, p)) errors>})*)
end
with _ -> emptyResult
method getCONST : 'b . (string -> 'self -> ('b, 'self) result) -> ('b, 'self) result =
fun k ->
if List.nth s p = '1'
then k "ha" {< p = p + 1 >}
else emptyResult
method getEOF : 'b . (string -> 'self -> ('b, 'self) result) -> ('b, 'self) result =
fun k ->
if p = List.length s
then k "eof" self
else emptyResult
end