@@ -61,6 +61,12 @@ let pat ~loc ?sized s =
6161 let s = name ?sized s in
6262 A. pvar s
6363
64+ let rec add_fuel ~loc expr =
65+ match expr.pexp_desc with
66+ | Pexp_fun (x , y , z , expr ) ->
67+ { expr with pexp_desc = Pexp_fun (x, y, z, add_fuel ~loc expr) }
68+ | _ -> [% expr fun n -> [% e expr]]
69+
6470let rec curry_args ~loc args body =
6571 match args with
6672 | [] -> body
@@ -98,7 +104,7 @@ let sized_and_gen ~loc ?(args = []) typ gen patt =
98104 let gen_expr = curry_args ~loc args gen in
99105 let gen = [% stri let [% p patt] = [% e expr_sized]] in
100106 let gen_sized = [% stri let rec [%p pat_sized ] = [% e gen_expr]] in
101- (gen_sized, Some gen)
107+ (gen_sized, gen)
102108
103109
104110let gen ~loc ?(env = TypeGen. empty) lg =
@@ -146,25 +152,19 @@ let sized ~loc ~env typ_name (is_rec : 'a -> bool)
146152
147153let mutually_recursive_gens ~loc typs gens =
148154 let (module A ) = Ast_builder. make loc in
149- let rec aux l typs =
150- match (l, typs) with
151- | ([% stri let rec [%p ? ppat ] = [% e? expr]], gen) :: xs, typ :: typs
152- | ([%stri let [%p ? ppat ] = [%e ? expr ]], gen ) :: xs , typ :: typs ->
153- (match gen with
154- | None ->
155- (* Current generator is not recursive. However, we want the generators
156- to share the fuel. Thus, we transform the non-recursive generator to
157- a recursive one. *)
158- let expr = [% expr fun n -> [% e expr]] in
159- let ppat' = pat ~loc ~sized: true typ in
160- let (_, gen) = sized_and_gen ~loc typ [% expr None ] ppat in
161- aux (([% stri let [% p ppat'] = [% e expr]], gen) :: xs) (typ :: typs)
162- | Some x ->
163- (A. value_binding ~pat: ppat ~expr , x) :: aux xs typs)
164- | ([] , [] ) -> []
165- | _ -> assert false
155+
156+ let gens =
157+ List. map2 (fun x y -> match (x, y) with
158+ | ([%stri let rec [%p ? ppat ] = [%e ? expr ]], `Needed call_to_size ), _ ->
159+ (A. value_binding ~pat: ppat ~expr , call_to_size)
160+ | ([%stri let [%p ? _ ] = [%e ? expr ]], `Useless call_to_size ), typ ->
161+ let expr = add_fuel ~loc expr in
162+ let ppat = pat ~loc ~sized: true typ in
163+ (A. value_binding ~pat: ppat ~expr , call_to_size)
164+ | (_ , _ ) -> assert false )
165+ gens typs
166166 in
167- let (sized_gens, gens) = List. split (aux gens typs) in
167+ let (sized_gens, gens) = List. split gens in
168168 let mutual_gens = A. pstr_value Recursive sized_gens in
169169 mutual_gens :: gens
170170
@@ -343,8 +343,7 @@ and gen_from_constr ~loc ~env ty xs =
343343 | xs ->
344344 let args = List. map (gen_from_type ~loc ~env ) xs in
345345 match gen with
346- | [% expr [% e? f] [% e? x]] ->
347- [% expr [% e apply_args ~loc args f] [% e x]]
346+ | [% expr [% e? f] [% e? x]] -> [% expr [% e apply_args ~loc args f] [% e x]]
348347 | _ -> apply_args ~loc args gen
349348
350349and gen_from_constr_decl ~loc ?(env = TypeGen. empty)
@@ -490,18 +489,22 @@ let gen_from_type_declaration ~loc ?(env = TypeGen.empty) td =
490489 td.ptype_params
491490 in
492491
492+ let (sized, call_to_size) = sized_and_gen ~loc ~args typ gen_expr gen_pat in
493493 match gen_expr with
494494 | [% expr fun n -> [% e? _]] ->
495- sized_and_gen ~loc ~args typ gen_expr gen_pat
495+ (sized, `Needed call_to_size)
496496 | _ ->
497- ([% stri let [% p gen_pat] = [% e curry_args ~loc args gen_expr]], None )
498-
497+ ([% stri let [% p gen_pat] = [% e curry_args ~loc args gen_expr]],
498+ `Useless call_to_size)
499499
500500let derive_gen ~loc xs : structure =
501501 match xs with
502502 | _ , [ x ] ->
503503 let (sized, gen) = gen_from_type_declaration ~loc x in
504- sized :: Option. fold ~none: [] ~some: (fun x -> [x]) gen
504+ (match gen with
505+ | `Needed gen ->
506+ [sized; gen]
507+ | _ -> [sized])
505508 | _ , xs ->
506509 let (module A ) = Ast_builder. make loc in
507510 let typs = List. map (fun td -> td.ptype_name.txt) xs in
0 commit comments