@@ -143,7 +143,6 @@ let extract_bindings ~(parser : ?pos:position -> string -> string Regexp_types.t
143
143
let r = parser ~pos s in
144
144
let nG, bs = Regexp. bindings r in
145
145
let re_str = Regexp. to_string ~ctx r in
146
- Format. printf " RE: %s@." re_str;
147
146
let loc = Location. none in
148
147
estring ~loc re_str, bs, nG
149
148
@@ -213,81 +212,65 @@ let transform_cases ~mode ~opts ~loc ~ctx cases =
213
212
re, nG, bs, case.pc_rhs, case.pc_guard
214
213
end
215
214
in
216
-
217
215
let cases, default_cases = separate_defaults [] cases in
218
-
219
216
let default_rhs = make_default_rhs ~loc default_cases in
220
- let grouped_cases = group_by_guard cases in
221
-
222
- let compiled_groups =
223
- List. map
224
- begin
225
- fun (guard , group_cases ) ->
226
- let processed_cases = List. rev_map aux group_cases in
227
- let res = pexp_array ~loc @@ List. map (fun (re , _ , _ , _ , _ ) -> re) processed_cases in
228
-
229
- let opts_expr =
230
- let rec opts_to_expr = function
231
- | [] -> [% expr []]
232
- | `Caseless :: rest -> [% expr `Caseless :: [% e opts_to_expr rest]]
233
- | _ -> assert false
234
- in
235
- opts_to_expr opts
236
- in
237
- let comp =
238
- [% expr
239
- let a = Array. map (fun s -> Re. mark (Re.Perl. re ~opts: [% e opts_expr] s)) [% e res] in
240
- let marks = Array. map fst a in
241
- let re = Re. compile (Re. alt (Array. to_list (Array. map snd a))) in
242
- re, marks]
243
- in
244
- let var = Util. fresh_var () in
245
- let re_binding = value_binding ~loc ~pat: (ppat_var ~loc { txt = var; loc }) ~expr: comp in
246
- let e_comp = pexp_ident ~loc { txt = Lident var; loc } in
247
217
248
- let rec handle_cases i offG = function
249
- | [] -> [% expr assert false ]
250
- | (_ , nG , bs , rhs , _ ) :: cases ->
251
- let bs = List. rev bs in
252
- [% expr
253
- if Re.Mark. test _g (snd [% e e_comp]).([% e eint ~loc i]) then
254
- [% e wrap_group_bindings ~captured_acc: [] ~loc rhs offG bs]
255
- else [% e handle_cases (i + 1 ) (offG + nG) cases]]
256
- in
218
+ let processed_cases = List. rev_map aux cases in
219
+ let res = pexp_array ~loc @@ List. map (fun (re , _ , _ , _ , _ ) -> re) processed_cases in
257
220
258
- let match_expr =
259
- [% expr
260
- match Re. exec_opt (fst [% e e_comp]) _ppx_regexp_v with
261
- | None -> None
262
- | Some _g -> Some [% e handle_cases 0 0 processed_cases]]
263
- in
221
+ let opts_expr =
222
+ let rec opts_to_expr = function
223
+ | [] -> [% expr []]
224
+ | `Caseless :: rest -> [% expr `Caseless :: [% e opts_to_expr rest]]
225
+ | _ -> assert false
226
+ in
227
+ opts_to_expr opts
228
+ in
264
229
265
- guard, match_expr, re_binding
266
- end
267
- grouped_cases
230
+ let comp =
231
+ [% expr
232
+ let a = Array. map (fun s -> Re. mark (Re.Perl. re ~opts: [% e opts_expr] s)) [% e res] in
233
+ let marks = Array. map fst a in
234
+ let re = Re. compile (Re. alt (Array. to_list (Array. map snd a))) in
235
+ re, marks]
268
236
in
269
237
270
- let rec try_groups = function
238
+ let var = Util. fresh_var () in
239
+ let re_binding = value_binding ~loc ~pat: (ppat_var ~loc { txt = var; loc }) ~expr: comp in
240
+ let e_comp = pexp_ident ~loc { txt = Lident var; loc } in
241
+
242
+ let rec handle_cases i offG = function
271
243
| [] -> default_rhs
272
- | (None, match_expr , _ ) :: rest ->
273
- [ % expr match [ % e match_expr] with Some result -> result | None -> [ % e try_groups rest]]
274
- | (Some guard_expr , match_expr , _ ) :: rest ->
244
+ | (_ , nG , bs , rhs , guard ) :: cases ->
245
+ let bs = List. rev bs in
246
+ let handled_cases = handle_cases (i + 1 ) (offG + nG) cases in
275
247
[% expr
276
- if [% e guard_expr] then (match [% e match_expr] with Some result -> result | None -> [% e try_groups rest])
277
- else [% e try_groups rest]]
248
+ if Re.Mark. test _g (snd [% e e_comp]).([% e eint ~loc i]) then
249
+ [% e
250
+ let wrapped_with_guard =
251
+ match guard with
252
+ | None -> rhs
253
+ | Some guard_expr -> [% expr if [% e guard_expr] then [% e rhs] else [% e handled_cases]]
254
+ in
255
+ wrap_group_bindings ~captured_acc: [] ~loc wrapped_with_guard offG bs]
256
+ else [% e handled_cases]]
278
257
in
279
258
280
- let final_expr = try_groups compiled_groups in
281
- let all_bindings = List. map (fun (_ , _ , b ) -> b) compiled_groups in
259
+ let match_expr =
260
+ [% expr
261
+ match Re. exec_opt (fst [% e e_comp]) _ppx_regexp_v with
262
+ | None -> [% e default_rhs]
263
+ | Some _g -> [% e handle_cases 0 0 processed_cases]]
264
+ in
282
265
283
266
( [% expr
284
267
let _ppx_regexp_v = [% e pexp_ident ~loc { txt = Lident " _ppx_regexp_v" ; loc }] in
285
- [% e final_expr ]],
286
- all_bindings )
268
+ [% e match_expr ]],
269
+ [ re_binding ] )
287
270
288
271
(* processes each case individually instead of combining them into one RE *)
289
- let transform_mixed_match ~loc ~ctx matched_expr cases acc =
290
- let prepare_case case =
272
+ let transform_mixed_match ~loc ~ctx ? matched_expr cases acc =
273
+ let aux case =
291
274
match case.pc_lhs.ppat_desc with
292
275
| Ppat_extension
293
276
( { txt = " mik" ; _ },
@@ -300,23 +283,26 @@ let transform_mixed_match ~loc ~ctx matched_expr cases acc =
300
283
| _ -> `Regular case
301
284
in
302
285
303
- let prepared_cases = List. map prepare_case cases in
286
+ let prepared_cases = List. map aux cases in
304
287
305
- (* Check if there are any mik cases *)
306
288
let has_mik = List. exists (function `Mik _ -> true | _ -> false ) prepared_cases in
307
289
308
- if not has_mik then pexp_match ~loc matched_expr cases, acc
290
+ if not has_mik then begin
291
+ match matched_expr with None -> pexp_function ~loc cases, acc | Some m -> pexp_match ~loc m cases, acc
292
+ end
309
293
else begin
310
294
let mik_compilations =
311
295
List. mapi
312
- (fun i case ->
313
- match case with
314
- | `Mik (re , _ , _ , _ , _ ) ->
315
- let comp_var = Util. fresh_var () in
316
- let comp_expr = [% expr Re. compile (Re.Perl. re [% e re])] in
317
- let binding = value_binding ~loc ~pat: (ppat_var ~loc { txt = comp_var; loc }) ~expr: comp_expr in
318
- Some (i, comp_var, binding)
319
- | _ -> None )
296
+ begin
297
+ fun i case ->
298
+ match case with
299
+ | `Mik (re , _ , _ , _ , _ ) ->
300
+ let comp_var = Util. fresh_var () in
301
+ let comp_expr = [% expr Re. compile (Re.Perl. re [% e re])] in
302
+ let binding = value_binding ~loc ~pat: (ppat_var ~loc { txt = comp_var; loc }) ~expr: comp_expr in
303
+ Some (i, comp_var, binding)
304
+ | _ -> None
305
+ end
320
306
prepared_cases
321
307
|> List. filter_map (fun x -> x)
322
308
in
@@ -340,11 +326,14 @@ let transform_mixed_match ~loc ~ctx matched_expr cases acc =
340
326
| Some _g ->
341
327
[% e
342
328
let bs = List. rev bs in
343
- let body = wrap_group_bindings ~captured_acc: [] ~loc rhs 0 bs in
329
+ (* let body = wrap_group_bindings ~captured_acc:[] ~loc rhs 0 bs in *)
344
330
match guard with
345
- | None -> body
331
+ | None -> wrap_group_bindings ~captured_acc: [] ~loc rhs 0 bs
346
332
| Some g ->
347
- [% expr if [% e g] then [% e body] else [% e build_ordered_match input_var (case_idx + 1 ) rest rest_comps]]]
333
+ let guarded_rhs =
334
+ [% expr if [% e g] then [% e rhs] else [% e build_ordered_match input_var (case_idx + 1 ) rest rest_comps]]
335
+ in
336
+ wrap_group_bindings ~captured_acc: [] ~loc guarded_rhs 0 bs]
348
337
| None -> [% e build_ordered_match input_var (case_idx + 1 ) rest rest_comps]]
349
338
| `Mik _ :: rest , _ ->
350
339
(* shouldn't happen if indices are correct *)
@@ -354,15 +343,22 @@ let transform_mixed_match ~loc ~ctx matched_expr cases acc =
354
343
let match_body = build_ordered_match [% expr _ppx_regexp_v] 0 prepared_cases mik_compilations in
355
344
356
345
let match_expr =
357
- List. fold_right
358
- (fun binding expr ->
346
+ let init =
347
+ match matched_expr with
348
+ | None -> [% expr fun _ppx_regexp_v -> [% e match_body]]
349
+ | Some m ->
359
350
[% expr
360
- let [% p binding.pvb_pat] = [% e binding.pvb_expr] in
361
- [% e expr]])
362
- bindings
363
- [% expr
364
- let _ppx_regexp_v = [% e matched_expr] in
365
- [% e match_body]]
351
+ let _ppx_regexp_v = [% e m] in
352
+ [% e match_body]]
353
+ in
354
+ List. fold_left
355
+ begin
356
+ fun expr binding ->
357
+ [% expr
358
+ let [% p binding.pvb_pat] = [% e binding.pvb_expr] in
359
+ [% e expr]]
360
+ end
361
+ init bindings
366
362
in
367
363
368
364
match_expr, bindings @ acc
0 commit comments