123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108(** This module provides the [[%%marshal.target]] PPX for the Gendarme library *)openPpxlibopenAst_builder.Default(** Generate a structure error node *)leterr~locmsg=[pstr_extension~loc(Location.error_extensionf~loc"[%s] %s""%%marshal.target"msg)[]](** Generate a signature error node *)leterr'~locmsg=[psig_extension~loc(Location.error_extensionf~loc"[%s] %s""%%marshal.target"msg)[]](** Common private flag *)letprivate_=Public(** Rewrite the extension node to declare the encoder *)letprocessloclidarg_locarg=(* Helper functions *)letlx=Loc.make~locxinletalx=Loc.make~loc:arg_locxinletv=pstr_value~locNonrecursiveinletlarg=Lident("%"^arg)|>alinletm~locnameexpr=letexpr=pmod_structure~locexprinmodule_binding~loc~name:(l(Somename))~expr|>pstr_module~locin(* type Gendarme.target += %Mod *)letkind=Pext_decl([],Pcstr_tuple[ptyp_constr~loclid[]],None)inletpath=Ldot(lident"Gendarme","target")|>linletconstructors=[extension_constructor~loc~name:(al("%"^arg))~kind]inletext=type_extension~loc~path~params:[]~constructors~private_|>pstr_typext~locin(* type Gendarme.encoder += Mod *)letkind=Pext_decl([],Pcstr_tuple[],None)inletpath=Ldot(lident"Gendarme","encoder")|>linletconstructors=[extension_constructor~loc~name:(alarg)~kind]inletext'=type_extension~loc~path~params:[]~constructors~private_|>pstr_typext~locin(* type t = ty *)letdecl=type_declaration~loc~name:(l"t")~params:[]~cstrs:[]~kind:Ptype_abstract~private_~manifest:(Some(ptyp_constr~loclid[]))inlett_def=pstr_type~locRecursive[decl]in(* let v = Mod *)letpat=l"t"|>ppat_var~locinletexpr=pexp_construct~loc(Ldot(lident"Prelude",arg)|>l)Noneinlett_def'=pstr_value~locNonrecursive[value_binding~loc~pat~expr]in(* let pack = ... *)letvpat=l"%v"|>ppat_var~locinletvexp=lident"%v"|>l|>pexp_ident~locinletexpr=Somevexp|>pexp_construct~loclarg|>pexp_fun~locNolabelNonevpatinletpack_def=v[value_binding~loc~pat:(l"pack"|>ppat_var~loc)~expr]in(* let unpack = ... *)letexpr=pexp_function~loc[case~lhs:(Somevpat|>ppat_construct~loclarg)~guard:None~rhs:vexp;case~lhs:(ppat_any~loc)~guard:None~rhs:(pexp_apply~loc(lident"raise"|>l|>pexp_ident~loc)[Nolabel,pexp_construct~loc(Ldot(lident"Gendarme","Unpack_error")|>l)None])]inletunpack_def=v[value_binding~loc~pat:(ppat_var~loc(l"unpack"))~expr]in[ext;m~loc"Prelude"[ext'];m~loc"E"[t_def;t_def';pack_def;unpack_def]](** Handle PPX arguments *)letdeclare_target~loc~path:_~arglid=matchargwith|Some({txt=Lidentarg;loc=arg_loc})->processloclidarg_locarg|Some{loc;_}->err~loc"expected a valid non-prefixed constructor"|None->err~loc"expected a constructor"(** Declare the extension *)letdeclare_target_ext=Extension.(declare_inline_with_path_arg"marshal.target"Context.structure_item)Ast_pattern.(pstr(pstr_eval(pexp_ident__')nil^::nil))declare_target(** Rewrite the extension node to declare the encoder signature *)letprocess'loclidarg_locarg=letlx=Loc.make~locxinletparams=[]inletmanifest=Some(ptyp_constr~loclid[])inletpath=Ldot(Lident"Gendarme","encoder")|>linletcons=[Pwith_type(lident"t"|>l,type_declaration~loc~name:(l"t")~params~cstrs:[]~kind:Ptype_abstract~private_~manifest)]inletconstructors=[extension_constructor~loc:arg_loc~name:(larg)~kind:(Pext_decl([],Pcstr_tuple[],None))]inlettype_=pmty_signature~loc[psig_typext~loc(type_extension~loc~path~params~constructors~private_)]in[psig_include~loc(pmty_with~loc(pmty_ident~loc(Ldot(lident"Gendarme","S")|>l))cons|>include_infos~loc);psig_module~loc(module_declaration~loc~name:(Some"Prelude"|>l)~type_)](** Handle PPX arguments *)letdeclare_target'~loc~path:_~arglid=matchargwith|Some({txt=Lidentarg;loc=arg_loc})->process'loclidarg_locarg|Some{loc;_}->err'~loc"expected a valid non-prefixed constructor"|None->err'~loc"expected a constructor"(** Declare the extension *)letdeclare_target_ext'=Extension.(declare_inline_with_path_arg"marshal.target"Context.signature_item)Ast_pattern.(pstr(pstr_eval(pexp_ident__')nil^::nil))declare_target'(** Register the extension *)let()=Driver.register_transformation"ppx_marshal_ext"~extensions:[declare_target_ext;declare_target_ext']