|
1 | 1 | open Types
|
2 | 2 | open Typedtree
|
| 3 | +open Parsetree |
3 | 4 |
|
4 | 5 | let mkpat desc = Ast_helper.Pat.mk desc
|
5 | 6 |
|
@@ -37,7 +38,78 @@ let untype typed =
|
37 | 38 | let ps = loop typed in
|
38 | 39 | ps
|
39 | 40 |
|
| 41 | +module Non_empty_list : sig |
| 42 | + type 'a t = 'a * 'a list |
| 43 | + |
| 44 | + val concat : 'a t -> 'a t -> 'a t |
| 45 | +end = struct |
| 46 | + type 'a t = 'a * 'a list |
| 47 | + |
| 48 | + let concat l r = |
| 49 | + let lhead, ltail = l in |
| 50 | + let rhead, rtail = r in |
| 51 | + (lhead, ltail @ (rhead :: rtail)) |
| 52 | +end |
| 53 | + |
| 54 | +let join_or_patterns = function |
| 55 | + | p, [] -> p |
| 56 | + | init_l, init_r :: t -> |
| 57 | + let initial_value = mkpat (Ppat_or (init_l, init_r)) in |
| 58 | + let result = |
| 59 | + List.fold_left (fun l r -> mkpat (Ppat_or (l, r))) initial_value t |
| 60 | + in |
| 61 | + result |
| 62 | + |
| 63 | +let flatten_or_patterns p = |
| 64 | + let rec loop p = |
| 65 | + match p.ppat_desc with |
| 66 | + | Ppat_or (l, r) -> |
| 67 | + let lhs_patterns = loop l in |
| 68 | + let rhs_patterns = loop r in |
| 69 | + Non_empty_list.concat lhs_patterns rhs_patterns |
| 70 | + | _ -> (p, []) |
| 71 | + in |
| 72 | + loop p |
| 73 | + |
| 74 | +(* group or patterns from left to right *) |
| 75 | +let normalize_or_patterns pat = |
| 76 | + let rec loop pat = |
| 77 | + match pat.ppat_desc with |
| 78 | + | Ppat_or (l, r) -> |
| 79 | + let p = mkpat (Ppat_or (loop l, loop r)) in |
| 80 | + let c = p |> flatten_or_patterns |> join_or_patterns in |
| 81 | + c |
| 82 | + | Ppat_any -> pat |
| 83 | + | Ppat_var _ -> pat |
| 84 | + | Ppat_constant _ -> pat |
| 85 | + | Ppat_interval _ -> pat |
| 86 | + | Ppat_alias (p, _) -> p |
| 87 | + | Ppat_open _ -> pat (* Not produced by typedtree *) |
| 88 | + | Ppat_extension _ -> pat |
| 89 | + | Ppat_constraint _ -> pat |
| 90 | + | Ppat_exception _ -> pat |
| 91 | + | Ppat_unpack _ -> pat |
| 92 | + | Ppat_type _ -> pat |
| 93 | + | Ppat_lazy p -> mkpat (Ppat_lazy (loop p)) |
| 94 | + | Ppat_array lst -> mkpat (Ppat_array (List.map loop lst)) |
| 95 | + | Ppat_tuple ps -> |
| 96 | + let ps = List.map loop ps in |
| 97 | + mkpat (Ppat_tuple ps) |
| 98 | + | Ppat_variant (lbl, maybe_p) -> |
| 99 | + let maybe_p = Option.map loop maybe_p in |
| 100 | + mkpat (Ppat_variant (lbl, maybe_p)) |
| 101 | + | Ppat_record (fields, closed_flag) -> |
| 102 | + let fields = |
| 103 | + List.map (fun field -> (fst field, loop (snd field))) fields |
| 104 | + in |
| 105 | + mkpat (Ppat_record (fields, closed_flag)) |
| 106 | + | Ppat_construct (lbl, maybe_p) -> |
| 107 | + let maybe_p = Option.map loop maybe_p in |
| 108 | + mkpat (Ppat_construct (lbl, maybe_p)) |
| 109 | + in |
| 110 | + loop pat |
| 111 | + |
40 | 112 | let print_pattern typed =
|
41 |
| - let pat = untype typed in |
| 113 | + let pat = typed |> untype |> normalize_or_patterns in |
42 | 114 | let doc = Res_printer.printPattern pat Res_comments_table.empty in
|
43 | 115 | Res_doc.toString ~width:80 doc
|
0 commit comments