2
2
module type S = sig
3
3
type input
4
4
type loc
5
+ type span
5
6
type token = loc Token .t
6
7
7
8
val lex : input -> token Stream .t
10
11
module Make (Input : Input.S ) = struct
11
12
open Token
12
13
14
+ module Span = Text. SourceSpan
15
+ module Loc = Text. SourceLoc
16
+
17
+ type input = Input .t
18
+ type loc = Input .loc
19
+ type span = Input .span
20
+ type token = span Token .t
21
+
13
22
let is_name_start chr =
14
23
(chr > = 'a' && chr < = 'z' )
15
24
|| (chr > = 'A' && chr < = 'Z' )
@@ -24,28 +33,27 @@ module Make(Input: Input.S) = struct
24
33
let handle_simple input length token_type = begin
25
34
let start = Input. loc ! input in
26
35
input := Input. advance_by ! input length;
27
- Some (Span. from start (Input. loc ! input), token_type)
36
+ Some (Input. span start (Input. loc ! input), token_type)
28
37
end
29
38
30
- let in_bounds text idx = idx < (String . length text)
39
+ let in_bounds text idx = idx < (Input . length text)
31
40
32
41
let rec read_name text curr =
33
42
if in_bounds text curr then
34
- match String . get text curr with
43
+ match Input . get text curr with
35
44
| c when is_name_body c -> read_name text (curr + 1 )
36
45
| _ -> curr
37
46
else
38
47
curr
39
48
40
49
let lex_name input =
41
- let text = (Input. full_text ! input) in
42
- let curr = (Input. offset ! input) in
43
50
let start = Input. loc ! input in
44
- let end_idx = read_name text curr in
51
+ let start_idx = Input. offset ! input in
52
+ let end_idx = read_name ! input 0 in
45
53
let old_input = ! input in
46
- let len = (end_idx - ( Loc. offset start) ) in
54
+ let len = (end_idx - start_idx ) in
47
55
input := Input. advance_by ! input len;
48
- let span = Span. from start (Input. loc ! input) in
56
+ let span = Input. span start (Input. loc ! input) in
49
57
let matches str = len = (String. length str) && Input. starts_with old_input str in
50
58
let tok = match len with
51
59
| _ when matches " type" -> Type
@@ -63,9 +71,9 @@ module Make(Input: Input.S) = struct
63
71
64
72
let rec read_multiline_comment text curr nesting =
65
73
if in_bounds text curr then
66
- match String . get text curr with
74
+ match Input . get text curr with
67
75
| '*' -> if in_bounds text (curr + 1 ) then
68
- match String . get text (curr + 1 ) with
76
+ match Input . get text (curr + 1 ) with
69
77
| '/' -> if nesting = 1 then
70
78
(curr + 2 , true )
71
79
else
@@ -74,7 +82,7 @@ module Make(Input: Input.S) = struct
74
82
else
75
83
(curr + 1 , false )
76
84
| '/' -> if in_bounds text (curr + 1 ) then
77
- match String . get text (curr + 1 ) with
85
+ match Input . get text (curr + 1 ) with
78
86
| '*' -> read_multiline_comment text (curr + 2 ) (nesting + 1 )
79
87
| _ -> read_multiline_comment text (curr + 1 ) nesting
80
88
else
@@ -84,45 +92,43 @@ module Make(Input: Input.S) = struct
84
92
(curr, false )
85
93
86
94
let lex_multiline_comment input =
87
- let text = Input. full_text ! input in
88
95
let start = Input. loc ! input in
89
- let start_idx = Loc . offset start in
90
- let end_idx, successful = read_multiline_comment text start_idx 0 in
96
+ let start_idx = Input . offset ! input in
97
+ let end_idx, successful = read_multiline_comment ! input 0 0 in
91
98
let len = end_idx - start_idx in
92
99
input := Input. advance_by ! input len;
93
100
let finish = Input. loc ! input in
94
- let span = Span. from start finish in
101
+ let span = Input. span start finish in
95
102
if successful then
96
103
Some (span, Comment Multiline )
97
104
else
98
105
Some (span, Invalid " Invalid multiline comment" )
99
106
100
107
let rec read_line_comment text curr =
101
108
if in_bounds text curr then
102
- match String . get text curr with
109
+ match Input . get text curr with
103
110
| '\n' -> curr
104
111
| _ -> read_line_comment text (curr + 1 )
105
112
else
106
113
curr
107
114
108
115
let lex_line_comment input =
109
- let text = Input. full_text ! input in
110
116
let start = Input. loc ! input in
111
- let start_idx = Loc . offset start in
112
- let end_idx = read_line_comment text (start_idx + 2 ) in
117
+ let start_idx = Input . offset ! input in
118
+ let end_idx = read_line_comment ! input (start_idx + 2 ) in
113
119
let len = end_idx - start_idx in
114
120
input := Input. advance_by ! input len;
115
121
let finish = Input. loc ! input in
116
- let span = Span. from start finish in
122
+ let span = Input. span start finish in
117
123
Some (span, Comment Line )
118
124
119
125
let rec read_whitespace text curr =
120
126
if in_bounds text curr then
121
- match String . get text curr with
127
+ match Input . get text curr with
122
128
| '\n' -> curr + 1
123
129
| '\r' -> begin
124
130
if in_bounds text (curr + 1 ) then
125
- match String . get text (curr + 1 ) with
131
+ match Input . get text (curr + 1 ) with
126
132
| '\n' -> curr + 2
127
133
| _ -> read_whitespace text (curr + 1 )
128
134
else
@@ -134,19 +140,18 @@ module Make(Input: Input.S) = struct
134
140
curr
135
141
136
142
let lex_whitespace input =
137
- let text = Input. full_text ! input in
138
143
let start = Input. loc ! input in
139
- let start_idx = Loc . offset start in
140
- let end_idx = read_whitespace text (start_idx + 1 ) in
144
+ let start_idx = Input . offset ! input in
145
+ let end_idx = read_whitespace ! input (start_idx + 1 ) in
141
146
let len = end_idx - start_idx in
142
147
input := Input. advance_by ! input len;
143
148
let finish = Input. loc ! input in
144
- let span = Span. from start finish in
149
+ let span = Input. span start finish in
145
150
Some (span, Whitespace )
146
151
147
152
let rec read_raw_prefix text curr =
148
153
if in_bounds text curr then
149
- match String . get text curr with
154
+ match Input . get text curr with
150
155
| '#' -> read_raw_prefix text (curr + 1 )
151
156
| '"' -> (curr + 1 , true )
152
157
| _ -> (curr, false )
@@ -158,15 +163,15 @@ module Make(Input: Input.S) = struct
158
163
true
159
164
else
160
165
if in_bounds text curr then
161
- match String . get text curr with
166
+ match Input . get text curr with
162
167
| '#' -> matches_suffix text (curr + 1 ) (len - 1 )
163
168
| _ -> false
164
169
else
165
170
false
166
171
167
172
let rec read_raw_body text curr suffix =
168
173
if in_bounds text curr then
169
- match String . get text curr with
174
+ match Input . get text curr with
170
175
| '"' -> if matches_suffix text (curr + 1 ) suffix then
171
176
(curr, true )
172
177
else
@@ -176,39 +181,38 @@ module Make(Input: Input.S) = struct
176
181
(curr, false )
177
182
178
183
let lex_raw_string input =
179
- let text = Input. full_text ! input in
180
184
let start_idx = Input. offset ! input in
181
- let (pos, successful_prefix) = read_raw_prefix text (start_idx + 1 ) in
185
+ let (pos, successful_prefix) = read_raw_prefix ! input (start_idx + 1 ) in
182
186
let start = Input. loc ! input in
183
187
if successful_prefix then
184
188
begin
185
189
let suffix = (pos - start_idx - 2 ) in
186
- let (end_pos, successful) = read_raw_body text pos suffix in
190
+ let (end_pos, successful) = read_raw_body ! input pos suffix in
187
191
if successful then
188
192
begin
189
193
let len = (end_pos + suffix + 1 ) - start_idx in
190
194
input := Input. advance_by ! input len;
191
- let span = Span. from start (Input. loc ! input) in
195
+ let span = Input. span start (Input. loc ! input) in
192
196
Some (span, Raw_string suffix)
193
197
end
194
198
else
195
199
begin
196
200
let len = end_pos - start_idx in
197
201
input := Input. advance_by ! input len;
198
- let span = Span. from start (Input. loc ! input) in
202
+ let span = Input. span start (Input. loc ! input) in
199
203
Some (span, Invalid " Invalid raw string" )
200
204
end
201
205
end
202
206
else
203
207
begin
204
208
input := Input. advance_by ! input (pos - start_idx);
205
- let span = Span. from start (Input. loc ! input) in
209
+ let span = Input. span start (Input. loc ! input) in
206
210
Some (span, Invalid " Expected \" " )
207
211
end
208
212
209
213
let rec read_string text curr =
210
214
if in_bounds text curr then
211
- match String . get text curr with
215
+ match Input . get text curr with
212
216
| '\\' ->
213
217
begin
214
218
if in_bounds text curr then
@@ -222,22 +226,21 @@ module Make(Input: Input.S) = struct
222
226
(curr, false )
223
227
224
228
let lex_string input =
225
- let text = Input. full_text ! input in
226
229
let start_idx = Input. offset ! input in
227
- let finish, successful = read_string text (start_idx + 1 ) in
230
+ let finish, successful = read_string ! input (start_idx + 1 ) in
228
231
let start = Input. loc ! input in
229
232
if successful then
230
233
begin
231
234
let len = (finish + 1 ) - start_idx in
232
235
input := Input. advance_by ! input len;
233
- let span = Span. from start (Input. loc ! input) in
236
+ let span = Input. span start (Input. loc ! input) in
234
237
Some (span, String )
235
238
end
236
239
else
237
240
begin
238
241
let len = finish - start_idx in
239
242
input := Input. advance_by ! input len;
240
- let span = Span. from start (Input. loc ! input) in
243
+ let span = Input. span start (Input. loc ! input) in
241
244
Some (span, Invalid " Expected \" " )
242
245
end
243
246
@@ -250,7 +253,7 @@ module Make(Input: Input.S) = struct
250
253
251
254
let rec read_digits is_digit text curr =
252
255
if in_bounds text curr then
253
- match String . get text curr with
256
+ match Input . get text curr with
254
257
| c when is_digit c -> read_digits is_digit text (curr + 1 )
255
258
| _ -> curr
256
259
else
@@ -260,9 +263,9 @@ module Make(Input: Input.S) = struct
260
263
if in_bounds text curr then
261
264
let end_digits = read_digits is_decimal_digit text curr in
262
265
if in_bounds text end_digits then
263
- match String . get text end_digits with
266
+ match Input . get text end_digits with
264
267
| '.' -> if in_bounds text (end_digits + 1 ) then
265
- match String . get text (end_digits + 1 ) with
268
+ match Input . get text (end_digits + 1 ) with
266
269
| c when is_decimal_digit c ->
267
270
read_digits is_decimal_digit text (end_digits + 1 )
268
271
| _ -> end_digits
@@ -275,13 +278,13 @@ module Make(Input: Input.S) = struct
275
278
curr
276
279
277
280
let lex_number input prefix_len read_digits =
278
- let text = Input. full_text ! input in
279
- let start_idx = Input. offset ! input in
280
- let start = Input. loc ! input in
281
+ let text = ! input in
282
+ let start_idx = Input. offset text in
283
+ let start = Input. loc text in
281
284
let end_idx = read_digits text (start_idx + prefix_len) in
282
285
let len = end_idx - start_idx in
283
- input := Input. advance_by ! input len;
284
- let span = Span. from start (Input. loc ! input ) in
286
+ input := Input. advance_by text len;
287
+ let span = Input. span start (Input. loc text ) in
285
288
if len = prefix_len then
286
289
Some (span, Invalid " Invalid number" )
287
290
else
@@ -298,22 +301,22 @@ module Make(Input: Input.S) = struct
298
301
299
302
let rec read_invalid text curr =
300
303
if in_bounds text curr then
301
- if is_valid_token_start (String . get text curr) then
304
+ if is_valid_token_start (Input . get text curr) then
302
305
curr
303
306
else
304
307
read_invalid text (curr + 1 )
305
308
else
306
309
curr
307
310
308
311
let lex_invalid input =
309
- let text = Input. full_text ! input in
312
+ let text = ! input in
310
313
let start = Input. loc ! input in
311
- let start_idx = Loc . offset start in
314
+ let start_idx = Input . offset ! input in
312
315
let end_idx = read_invalid text (start_idx + 1 ) in
313
316
let len = end_idx - start_idx in
314
317
input := Input. advance_by ! input len;
315
318
let finish = Input. loc ! input in
316
- let span = Span. from start finish in
319
+ let span = Input. span start finish in
317
320
Some (span, Invalid " Unknown token" )
318
321
319
322
let lex_token input =
0 commit comments