Skip to content

Commit 06dd288

Browse files
committed
ppx_optcomp_light: more robust pattern matching
Use Ast_pattern rather than a direct pattern matching over OCaml expressions.
1 parent 46d02f7 commit 06dd288

File tree

1 file changed

+65
-55
lines changed

1 file changed

+65
-55
lines changed

compiler/ppx/ppx_optcomp_light.ml

Lines changed: 65 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -155,61 +155,71 @@ let keep loc (attrs : attributes) =
155155
| PStr [ { pstr_desc = Pstr_eval (e, []); _ } ] -> e
156156
| _ -> raise (Invalid attr_loc)
157157
in
158-
let loc = e.pexp_loc in
159-
let rec eval = function
160-
| { pexp_desc = Pexp_ident { txt = Lident "ocaml_version"; _ }; _ } ->
161-
Version Version.current
162-
| { pexp_desc = Pexp_ident { txt = Lident "ast_version"; _ }; _ } ->
163-
Int Ppxlib.Selected_ast.version
164-
| { pexp_desc = Pexp_construct ({ txt = Lident "true"; _ }, None); _ } ->
165-
Bool true
166-
| { pexp_desc = Pexp_construct ({ txt = Lident "false"; _ }, None); _ } ->
167-
Bool false
168-
| { pexp_desc = Pexp_constant (Pconst_integer (d, None)); _ } ->
169-
Int (int_of_string d)
170-
| { pexp_desc = Pexp_tuple l; _ } -> Tuple (List.map l ~f:eval)
171-
| { pexp_desc = Pexp_apply (op, [ (Nolabel, a); (Nolabel, b) ]); pexp_loc; _ }
172-
-> (
173-
let op = get_bin_op op in
174-
let a = eval a in
175-
let b = eval b in
176-
match op with
177-
| LE | GE | LT | GT | NEQ | EQ ->
178-
let comp =
179-
match a, b with
180-
| Version _, _ | _, Version _ ->
181-
Version.compare (version a) (version b)
182-
| Int a, Int b -> compare a b
183-
| _ -> raise (Invalid pexp_loc)
184-
in
185-
let op =
186-
match op with
187-
| LE -> ( <= )
188-
| GE -> ( >= )
189-
| LT -> ( < )
190-
| GT -> ( > )
191-
| EQ -> ( = )
192-
| NEQ -> ( <> )
193-
| _ -> assert false
194-
in
195-
Bool (op comp 0)
196-
| AND -> (
197-
match a, b with
198-
| Bool a, Bool b -> Bool (a && b)
199-
| _ -> raise (Invalid loc))
200-
| OR -> (
201-
match a, b with
202-
| Bool a, Bool b -> Bool (a || b)
203-
| _ -> raise (Invalid loc))
204-
| NOT -> raise (Invalid loc))
205-
| { pexp_desc = Pexp_apply (op, [ (Nolabel, a) ]); _ } -> (
206-
let op = get_un_op op in
207-
let a = eval a in
208-
match op, a with
209-
| NOT, Bool b -> Bool (not b)
210-
| NOT, _ -> raise (Invalid loc)
211-
| _ -> raise (Invalid loc))
212-
| _ -> raise (Invalid loc)
158+
let rec eval e =
159+
let open Ppxlib.Ast_pattern in
160+
let loc = e.pexp_loc in
161+
match
162+
(parse_res
163+
(pexp_ident (lident (string "ocaml_version"))
164+
>>| (fun () -> Version Version.current)
165+
||| (pexp_ident (lident (string "ast_version"))
166+
>>| fun () -> Int Ppxlib.Selected_ast.version)
167+
||| (pexp_construct (lident (string "true")) drop >>| fun () -> Bool true)
168+
||| (pexp_constant (pconst_integer __ none)
169+
>>| fun () d -> Int (int_of_string d))
170+
||| (pexp_construct (lident (string "false")) drop
171+
>>| fun () -> Bool false)
172+
||| (pexp_tuple __ >>| fun () l -> Tuple (List.map l ~f:eval))
173+
||| (pexp_apply __ __
174+
>>| fun () op l ->
175+
match l with
176+
| [ (Nolabel, a); (Nolabel, b) ] -> (
177+
let op = get_bin_op op in
178+
let a = eval a in
179+
let b = eval b in
180+
match op with
181+
| LE | GE | LT | GT | NEQ | EQ ->
182+
let comp =
183+
match a, b with
184+
| Version _, _ | _, Version _ ->
185+
Version.compare (version a) (version b)
186+
| Int a, Int b -> compare a b
187+
| _ -> raise (Invalid loc)
188+
in
189+
let op =
190+
match op with
191+
| LE -> ( <= )
192+
| GE -> ( >= )
193+
| LT -> ( < )
194+
| GT -> ( > )
195+
| EQ -> ( = )
196+
| NEQ -> ( <> )
197+
| _ -> assert false
198+
in
199+
Bool (op comp 0)
200+
| AND -> (
201+
match a, b with
202+
| Bool a, Bool b -> Bool (a && b)
203+
| _ -> raise (Invalid loc))
204+
| OR -> (
205+
match a, b with
206+
| Bool a, Bool b -> Bool (a || b)
207+
| _ -> raise (Invalid loc))
208+
| NOT -> raise (Invalid loc))
209+
| [ (Nolabel, a) ] -> (
210+
let op = get_un_op op in
211+
let a = eval a in
212+
match op, a with
213+
| NOT, Bool b -> Bool (not b)
214+
| NOT, _ -> raise (Invalid loc)
215+
| _ -> raise (Invalid loc))
216+
| _ -> raise (Invalid loc))))
217+
loc
218+
e
219+
()
220+
with
221+
| Ok res -> res
222+
| Error _ -> raise (Invalid loc)
213223
in
214224
match eval e with
215225
| Bool b -> b

0 commit comments

Comments
 (0)