@@ -61,9 +61,9 @@ module Regexp = struct
61
61
| Nongreedy e -> recurse must_match e
62
62
| Capture _ -> error ~loc " Unnamed capture is not allowed for %%pcre."
63
63
| Capture_as (idr , e ) -> fun (nG , bs ) -> recurse must_match e (nG + 1 , (idr, Some nG, must_match) :: bs)
64
- | Named_subs (idr , None, e ) -> fun ( nG , bs ) -> recurse must_match e (nG + 1 , ( idr, Some nG, must_match) :: bs)
65
- | Named_subs ( _ , Some idr , e ) -> fun (nG , bs ) -> recurse must_match e (nG + 1 , (idr, Some nG, must_match) :: bs)
66
- | Unnamed_subs (_ , e ) -> fun ( nG , bs ) -> recurse must_match e (nG + 1 , bs)
64
+ | Named_subs (idr , None , e ) | Named_subs ( _ , Some idr , e ) ->
65
+ fun (nG , bs ) -> recurse must_match e (nG + 1 , (idr, Some nG, must_match) :: bs)
66
+ | Unnamed_subs (_ , e ) -> recurse must_match e
67
67
| Call _ -> error ~loc " (&...) is not implemented for %%pcre."
68
68
in
69
69
function
@@ -75,6 +75,17 @@ module Regexp = struct
75
75
let delimit_if b s = if b then " (?:" ^ s ^ " )" else s in
76
76
let rec recurse p (e' : _ Location.loc ) =
77
77
let loc = e'.Location. loc in
78
+ let parse_inside idr =
79
+ let var_name = idr.txt in
80
+ let content =
81
+ match Ctx. find var_name ctx with
82
+ | Some (value , _ ) -> parse_exn value
83
+ | None ->
84
+ error ~loc " Variable '%s' not found. %%pcre only supports global let bindings for substitution." var_name
85
+ in
86
+ Ctx. update_used var_name ctx;
87
+ content
88
+ in
78
89
match e'.Location. txt with
79
90
| Code s ->
80
91
(* Delimiters not needed as Regexp.parse_exn only returns single
@@ -89,16 +100,12 @@ module Regexp = struct
89
100
| Nongreedy e -> recurse p_suffix e ^ " ?"
90
101
| Capture _ -> error ~loc " Unnamed capture is not allowed for %%pcre."
91
102
| Capture_as (_ , e ) -> " (" ^ recurse p_alt e ^ " )"
92
- | Named_subs (idr , _ , _ ) | Unnamed_subs (idr , _ ) ->
93
- let var_name = idr.txt in
94
- let content =
95
- match Ctx. find var_name ctx with
96
- | Some (value , _ ) -> parse_exn value
97
- | None ->
98
- error ~loc " Variable '%s' not found. %%pcre only supports global let bindings for substitution." var_name
99
- in
100
- Ctx. update_used var_name ctx;
103
+ | Named_subs (idr , _ , _ ) ->
104
+ let content = parse_inside idr in
101
105
" (" ^ recurse p_alt content ^ " )"
106
+ | Unnamed_subs (idr , _ ) ->
107
+ let content = parse_inside idr in
108
+ recurse p_alt content
102
109
| Call _ -> error ~loc " (&...) is not implemented for %%pcre."
103
110
in
104
111
function { Location. txt = Capture_as (_ , e ); _ } -> recurse 0 e | e -> recurse 0 e
@@ -124,7 +131,6 @@ let rec must_match p i =
124
131
let extract_bindings ~ctx ~pos s =
125
132
let r = Regexp. parse_exn ~pos s in
126
133
let nG, bs = Regexp. bindings r in
127
- List. iter (fun (idr , i , b ) -> Format. printf " %s, %i, %b@." idr.txt (match i with Some i -> i | None -> - 1 ) b) bs;
128
134
let re_str = Regexp. to_string ~ctx r in
129
135
let loc = Location. none in
130
136
estring ~loc re_str, bs, nG
@@ -142,7 +148,7 @@ let rec wrap_group_bindings ~loc rhs offG = function
142
148
let [% p ppat_var ~loc varG] = [% e eG] in
143
149
[% e wrap_group_bindings ~loc rhs offG bs]]
144
150
145
- let transform_cases ~loc ~ctx cases =
151
+ let transform_cases ~opts ~ loc ~ctx cases =
146
152
let aux case =
147
153
if case.pc_guard <> None then error ~loc " Guards are not implemented for match%%pcre."
148
154
else
@@ -177,9 +183,17 @@ let transform_cases ~loc ~ctx cases =
177
183
in
178
184
let cases = List. rev_map aux cases in
179
185
let res = pexp_array ~loc (List. map (fun (re , _ , _ , _ ) -> re) cases) in
186
+ let opts_expr =
187
+ let rec opts_to_expr = function
188
+ | [] -> [% expr []]
189
+ | `Caseless :: rest -> [% expr `Caseless :: [% e opts_to_expr rest]]
190
+ | _ -> assert false
191
+ in
192
+ opts_to_expr opts
193
+ in
180
194
let comp =
181
195
[% expr
182
- let a = Array. map (fun s -> Re. mark (Re.Perl. re s)) [% e res] in
196
+ let a = Array. map (fun s -> Re. mark (Re.Perl. re ~opts: [ % e opts_expr] s)) [% e res] in
183
197
let marks = Array. map fst a in
184
198
let re = Re. compile (Re. alt (Array. to_list (Array. map snd a))) in
185
199
re, marks]
@@ -226,22 +240,26 @@ let transformation ctx =
226
240
227
241
method! expression e_ext acc =
228
242
let e_ext, acc = super#expression e_ext acc in
243
+ let make_transformations ~opts ~loc = function
244
+ | Pexp_match (e , cases ) ->
245
+ let cases, binding = transform_cases ~opts ~loc ~ctx cases in
246
+ ( [% expr
247
+ let _ppx_regexp_v = [% e e] in
248
+ [% e cases]],
249
+ binding :: acc )
250
+ | Pexp_function cases ->
251
+ (* | Pexp_function (_, _, Pfunction_cases (cases, _, _)) -> *)
252
+ let cases, binding = transform_cases ~opts ~loc ~ctx cases in
253
+ [% expr fun _ppx_regexp_v -> [% e cases]], binding :: acc
254
+ | _ -> error ~loc " [%%pcre] only applies to match and function."
255
+ in
229
256
match e_ext.pexp_desc with
230
257
| Pexp_extension ({ txt = "pcre" ; _ } , PStr [ { pstr_desc = Pstr_eval (e , _ ); _ } ]) ->
231
258
let loc = e.pexp_loc in
232
- begin
233
- match e.pexp_desc with
234
- | Pexp_match (e , cases ) ->
235
- let cases, binding = transform_cases ~loc ~ctx cases in
236
- ( [% expr
237
- let _ppx_regexp_v = [% e e] in
238
- [% e cases]],
239
- binding :: acc )
240
- | Pexp_function cases ->
241
- let cases, binding = transform_cases ~ctx ~loc cases in
242
- [% expr fun _ppx_regexp_v -> [% e cases]], binding :: acc
243
- | _ -> error ~loc " [%%pcre] only applies to match and function."
244
- end
259
+ make_transformations ~opts: [] ~loc e.pexp_desc
260
+ | Pexp_extension ({ txt = "pcre_i" ; _ } , PStr [ { pstr_desc = Pstr_eval (e , _ ); _ } ]) ->
261
+ let loc = e.pexp_loc in
262
+ make_transformations ~opts: [ `Caseless ] ~loc e.pexp_desc
245
263
| _ -> e_ext, acc
246
264
end
247
265
0 commit comments