@@ -89,7 +89,7 @@ let extract_bindings ~loc p =
89
89
(match stack with
90
90
| [] -> error ~loc " Unmached end of group."
91
91
| ((Some varG , iG , bs' ) :: stack' ) ->
92
- let bs = (varG, iG, true ) :: bs in
92
+ let bs = (varG, Some iG, true ) :: bs in
93
93
(bs, bs', stack')
94
94
| ((None, _ , bs' ) :: stack' ) ->
95
95
(bs, bs', stack'))
@@ -100,30 +100,53 @@ let extract_bindings ~loc p =
100
100
in
101
101
parse_normal nG stack' (List. rev_append bs bs') i
102
102
in
103
- let bs, nG = parse_normal 0 [] [] 0 in
104
- (Buffer. contents buf, bs, nG)
103
+ let parse_first () =
104
+ if l > = 4 && p.[0 ] = '?' && p.[1 ] = '<' then
105
+ let j = String. index_from p 2 '>' in
106
+ let varG = String. sub p 2 (j - 2 ) in
107
+ parse_normal 0 [] [varG, None , true ] (j + 1 )
108
+ else
109
+ parse_normal 0 [] [] 0
110
+ in
111
+ let bs, nG = parse_first () in
112
+ let re_str = Buffer. contents buf in
113
+ (try ignore (Re_pcre. regexp re_str) with
114
+ | Re_perl. Not_supported -> error ~loc " Unsupported regular expression."
115
+ | Re_perl. Parse_error -> error ~loc " Invalid regular expression." );
116
+ (Exp. constant (Const. string re_str), bs, nG)
105
117
106
- let transform_cases ~loc e cases =
118
+ let transform_cases ~loc cases =
107
119
let aux case =
108
120
if case.pc_guard <> None then
109
121
error ~loc " Guards are not implemented for match%pcre." else
110
122
(match case.pc_lhs with
111
123
| { ppat_desc = Ppat_constant (Pconst_string (re_src,_));
112
124
ppat_loc = loc; _ } ->
113
- let re_str, bs, nG = extract_bindings ~loc re_src in
114
- (try ignore (Re_pcre. regexp re_str) with
115
- | Re_perl. Not_supported -> error ~loc " Unsupported regular expression."
116
- | Re_perl. Parse_error -> error ~loc " Invalid regular expression." );
117
- (Exp. constant (Const. string re_str), nG, bs, case.pc_rhs)
125
+ let re, bs, nG = extract_bindings ~loc re_src in
126
+ (re, nG, bs, case.pc_rhs)
127
+ (*
128
+ | {ppat_desc = Ppat_alias
129
+ ({ ppat_desc = Ppat_constant (Pconst_string (re_src,_));
130
+ ppat_loc = loc; _ },
131
+ var); _} ->
132
+ let re, bs, nG = extract_bindings ~loc re_src in
133
+ let rhs =
134
+ (* TODO: Should this be (_ppx_regexp_v or Re.Group.get _g 0? *)
135
+ [%expr let [%p Pat.var var] = _ppx_regexp_v in [%e case.pc_rhs]] in
136
+ (re, nG, bs, rhs)
137
+ *)
118
138
| {ppat_desc = Ppat_any ; _} ->
119
139
error ~loc " Universal wildcard must be the last pattern."
120
140
| {ppat_loc = loc ; _} ->
121
141
error ~loc " Regular expression pattern should be a string." )
122
142
in
123
143
let cases, default_rhs =
124
144
(match List. rev cases with
125
- | {pc_lhs = {ppat_desc = Ppat_any ; _} ; pc_rhs; _ } :: cases ->
145
+ | {pc_lhs = {ppat_desc = Ppat_any ; _} ; pc_rhs; pc_guard = None } :: cases ->
126
146
(cases, pc_rhs)
147
+ | {pc_lhs = {ppat_desc = Ppat_var var; _}; pc_rhs; pc_guard = None } ::
148
+ cases ->
149
+ (cases, [% expr let [% p Pat. var var] = _ppx_regexp_v in [% e pc_rhs]])
127
150
| cases ->
128
151
let open Lexing in
129
152
let pos = loc.Location. loc_start in
@@ -148,8 +171,11 @@ let transform_cases ~loc e cases =
148
171
let rec wrap_groups rhs offG = function
149
172
| [] -> rhs
150
173
| (varG , iG , mustG ) :: bs ->
151
- let eG =
152
- [% expr Re.Group. get _g [% e Exp. constant (Const. int (offG + iG + 1 ))]]
174
+ let eG = match iG with
175
+ | None ->
176
+ [% expr Re.Group. get _g 0 ]
177
+ | Some iG ->
178
+ [% expr Re.Group. get _g [% e Exp. constant (Const. int (offG + iG + 1 ))]]
153
179
in
154
180
let eG =
155
181
if mustG then eG else
@@ -170,7 +196,7 @@ let transform_cases ~loc e cases =
170
196
[% e handle_cases (i + 1 ) (offG + nG) cases]]
171
197
in
172
198
[% expr
173
- (match Re. exec_opt (fst [% e e_comp]) [ % e e] with
199
+ (match Re. exec_opt (fst [% e e_comp]) _ppx_regexp_v with
174
200
| None -> [% e default_rhs]
175
201
| Some _g -> [% e handle_cases 0 0 cases])]
176
202
@@ -181,9 +207,9 @@ let rewrite_expr mapper e_ext =
181
207
let loc = e.pexp_loc in
182
208
(match e.pexp_desc with
183
209
| Pexp_match (e , cases ) ->
184
- transform_cases ~loc e cases
210
+ [ % expr let _ppx_regexp_v = [ % e e] in [ % e transform_cases ~loc cases]]
185
211
| Pexp_function (cases ) ->
186
- [% expr fun _s -> [% e transform_cases ~loc [ % expr _s] cases]]
212
+ [% expr fun _ppx_regexp_v -> [% e transform_cases ~loc cases]]
187
213
| _ ->
188
214
error ~loc " [%pcre] only applies to match an function." )
189
215
| _ -> default_mapper.expr mapper e_ext)
0 commit comments