1
- module Sexp = struct
2
-
3
- let is_unquoted_atom_char = function
4
- | 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '-' | '_' ->
5
- true
6
- | _ ->
7
- false
8
- (*
9
- let fold_sexp atom list input =
10
- let scan_unquoted_atom start =
11
- let rec scan i =
12
- if i = String.length input then
13
- i, String.sub input start (i - start)
14
- else
15
- if is_unquoted_atom_char input.[i] then
16
- scan (i+1)
17
- else
18
- i, String.sub input start (i - start)
19
- in
20
- scan start
21
- in
22
- let scan_quoted_atom start =
23
- let b = Buffer.create 128 in
24
- let rec scan i =
25
- if i = String.length input then
26
- failwith "unexpected end of input during quoted atom"
27
- else
28
- match input.[i] with
29
- | '"' ->
30
- i+1, Buffer.contents b
31
- | '\\' ->
32
- (if i + 1 = String.length input then
33
- failwith "unexpected end of input during quoted atom"
34
- else
35
- match input.[i+1] with
36
- | 'n' -> Buffer.add_char b '\n'; scan (i+2)
37
- | 't' -> Buffer.add_char b '\t'; scan (i+2)
38
- | '\\' -> Buffer.add_char b '\\'; scan (i+2)
39
- | '"' -> Buffer.add_char b '"'; scan (i+2)
40
- | _ -> failwith "invalid escape character")
41
- | c ->
42
- Buffer.add_char b c; scan (i+1)
43
- in
44
- scan start
45
- in
46
- let rec scan i acc =
47
- if i = String.length input then
48
- i, List.rev acc
49
- else
50
- match input.[i] with
51
- | ' ' | '\n' | '\t' ->
52
- scan (i+1) acc
53
- | ')' ->
54
- i, List.rev acc
55
- | '(' ->
56
- (let i, items = scan (i+1) [] in
57
- if i = String.length input then
58
- failwith "unexpected end of input"
59
- else if input.[i] = ')' then
60
- scan (i+1) (list items :: acc)
61
- else
62
- failwith "expecting ')'")
63
- | c when is_unquoted_atom_char c ->
64
- let i, str = scan_unquoted_atom i in
65
- scan i (atom str :: acc)
66
- | '"' ->
67
- let i, str = scan_quoted_atom (i+1) in
68
- scan i (atom str :: acc)
69
- | _ ->
70
- failwith "unexpected character"
71
- in
72
- let i, result = scan 0 [] in
73
- if i = String.length input then
74
- result
75
- else
76
- failwith "Unexpected junk at end of input"
77
- *)
78
- end
79
-
80
1
open Generalities
2
+ open Sexp
81
3
82
- type sexp =
83
- | Atom of string
84
- | List of sexp list
85
-
86
- (* FIXME: spans *)
87
- let of_lexbuf lexbuf =
88
- let rec scan acc =
89
- match Sexp_reader. token lexbuf with
90
- | Sexp_reader. EOF ->
91
- List. rev acc, `eof
92
- | RParen ->
93
- List. rev acc, `rparen
94
- | LParen ->
95
- (let list , terminator = scan [] in
96
- match terminator with
97
- | `eof -> failwith " Unfinished '('"
98
- | `rparen -> scan (List list :: acc))
99
- | BareAtom atom | QuotedAtom atom ->
100
- scan (Atom atom :: acc)
101
- in
102
- let sexps, terminator = scan [] in
103
- match terminator with
104
- | `eof -> sexps
105
- | `rparen -> failwith " Non-matching ')'"
4
+ let is_unquoted_atom_char = function
5
+ | 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '-' | '_' ->
6
+ true
7
+ | _ ->
8
+ false
106
9
107
10
let is_bare_atom =
108
- String. for_all Sexp. is_unquoted_atom_char
11
+ String. for_all is_unquoted_atom_char
109
12
110
13
let quote str =
111
14
let b = Buffer. create 128 in
112
15
Buffer. add_string b " \" " ;
113
- str |> String. iter (function
114
- | '"' -> Buffer. add_string b " \\\" "
115
- | '\\' -> Buffer. add_string b " \\\\ "
116
- | '\n' -> Buffer. add_string b " \\ n"
117
- | '\t' -> Buffer. add_string b " \\ t"
118
- | c -> Buffer. add_char b c);
16
+ String. iter
17
+ (function
18
+ | '"' -> Buffer. add_string b " \\\" "
19
+ | '\\' -> Buffer. add_string b " \\\\ "
20
+ | '\n' -> Buffer. add_string b " \\ n"
21
+ | '\t' -> Buffer. add_string b " \\ t"
22
+ | c -> Buffer. add_char b c)
23
+ str;
119
24
Buffer. add_string b " \" " ;
120
25
Buffer. contents b
121
26
@@ -125,8 +30,9 @@ let atom str =
125
30
else
126
31
Pretty. text (quote str)
127
32
128
- and list = function
129
- | [] -> Pretty. text " ()"
33
+ let list = function
34
+ | [] ->
35
+ Pretty. text " ()"
130
36
| [head] ->
131
37
Pretty. (text " (" ^^ head ^^ text " )" )
132
38
| head :: rest ->
@@ -140,6 +46,6 @@ let rec pretty = function
140
46
let () =
141
47
stdin
142
48
|> Lexing. from_channel
143
- |> of_lexbuf
144
- |> List . map pretty
145
- |> List . iter (fun doc -> Pretty. print doc; print_newline () )
49
+ |> Sexp_reader. of_lexbuf
50
+ |> Seq . map pretty
51
+ |> Seq . iter (fun doc -> Pretty. print doc; print_newline () )
0 commit comments