123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683openBaseopenPpxlibopenPpxlib.Ast_builder.Defaultletderiver="hardcaml"letraise_errorf=Location.raise_errorf(*
* Option parsing
*)typeoptions_t={rtlprefix:expressionoption;rtlsuffix:expressionoption;rtlmangle:bool;ast:bool;}letparse_booloptionexpr~loc=matchexprwith|[%exprtrue]->true|[%exprfalse]->false|_->raise_errorf~loc"[%s] %s option must be a boolean"deriveroption;;(*
* Attribute definition and parsing
*)moduleAttribute:sigtypetvalfind:t->label_declaration->expressionoptionvalbits:tvallength:tvalrtlmangle:tvalrtlname:tvalrtlprefix:tvalrtlsuffix:tvaldoc:tend=structtypet=(label_declaration,expression)Attribute.tletfindtlabel_declaration=Attribute.gettlabel_declarationletcreatename=Attribute.declarenameLabel_declarationAst_pattern.(pstr(pstr_eval__nil^::nil))(funx->x);;letbits=create"bits"letlength=create"length"letrtlmangle=create"rtlmangle"letrtlname=create"rtlname"letrtlprefix=create"rtlprefix"letrtlsuffix=create"rtlsuffix"(* This represents the [ocaml.doc] attribute, which maps to documentation comments. The
leading [hardcaml.] token is required to bypass some compiler (or ppx) related
checks. I mention it because it's an undocumented hack. *)letdoc=create"hardcaml.ocaml.doc"endletget_bits~loclabel_declaration=matchAttribute.(findbits)label_declarationwith|Some(expr)->expr|None->pexp_constant~loc(Pconst_integer("1",None))letget_length~loclabel_declaration=matchAttribute.(findlength)label_declarationwith|Some(expr)->expr|None->raise_errorf~loc"[%s] length attribute must be set"deriverletfield_name~loctxt=estring~loctxtletget_rtlname~loctxtlabel_declaration=matchAttribute.(findrtlname)label_declarationwith|Some(expr)->expr|None->field_name~loctxtletget_rtlprefix~loc:_optslabel_declaration=matchAttribute.(findrtlprefix)label_declarationwith|Some(expr)->Some(expr)|None->opts.rtlprefixletget_rtlsuffix~loc:_optslabel_declaration=matchAttribute.(findrtlsuffix)label_declarationwith|Some(expr)->Some(expr)|None->opts.rtlsuffixletget_rtlmangle~locoptslabel_declaration=matchAttribute.(findrtlmangle)label_declarationwith|Some([%exprtrue])->true|Some([%exprfalse])->false|Some(_)->raise_errorf~loc"[%s] rtlmangle attribute must be a boolean"deriver|None->opts.rtlmangleletget_doc~loclabel_declaration=matchAttribute.(finddoc)label_declarationwith|Some(expr)->(matchexpr.pexp_descwith|Pexp_constant(Pconst_string(str,_,_))->Somestr|_->raise_errorf~loc"[%s] doc atttribute must be a string"deriver)|None->None(*
* Identifier manipulation
*)letmk_rtlident~locnameprefixsuffix=matchprefix,suffixwith|None,None->[%expr([%ename])]|Some(pre),None->[%exprPpx_deriving_hardcaml_runtime.concat[[%epre];[%ename]]]|None,Some(suf)->[%exprPpx_deriving_hardcaml_runtime.concat[[%ename];[%esuf]]]|Some(pre),Some(suf)->[%exprPpx_deriving_hardcaml_runtime.concat[[%epre];[%ename];[%esuf]]][@metalocloc]letmangle_name~locnamemangle=ifmanglethen[%exprPpx_deriving_hardcaml_runtime.concat[[%ename];"_";_n]]else[%expr_n](*
* Code generation utility functions
*)letcheck_list_and_array_labelvarloc=function|Ptyp_varv|Ptyp_constr({txt=Ldot(_,_);_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->()|_->raise_errorf~loc"[%s] check_label: only supports abstract record labels"deriverletcheck_labelvar({pld_name={loc;_};_}aslabel)=matchlabel.pld_type.ptyp_descwith|Ptyp_varv|Ptyp_constr({txt=Ldot(_,_);_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->()|Ptyp_constr({txt=Lident("list");_},[{ptyp_desc;_}])|Ptyp_constr({txt=Lident("array");_},[{ptyp_desc;_}])->check_list_and_array_labelvarlocptyp_desc|_->raise_errorf~loc"[%s] check_label: only supports abstract record labels"deriverletexpand_array_init~locvnamelabel_declaration=letnbits=get_bits~loclabel_declarationinletlength=get_length~loclabel_declarationin[%exprPpx_deriving_hardcaml_runtime.Array.init[%elength]~f:(fun_i->Ppx_deriving_hardcaml_runtime.concat[[%evname];Ppx_deriving_hardcaml_runtime.Int.to_string_i],[%enbits])]letexpand_array_init_str~locvnamemapidmidlabel_declaration=letlength=get_length~loclabel_declarationin[%exprPpx_deriving_hardcaml_runtime.Array.init[%elength]~f:(fun_i->[%emapid][%epexp_ident~locmid]~f:(fun(_n,_b)->([%evname],_b)))](*
* Expand t label
*)letexpand_t_label_arrayvarloclabel_declarationnameprefixsuffixmangle=function(* 'a *)|Ptyp_var(v)whenString.equalvvar->letrtlident=mk_rtlident~locnameprefixsuffixinexpand_array_init~locrtlidentlabel_declaration(* 'a Module.t *)|Ptyp_constr(({txt=Ldot(mname,_);_}asmid),[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->letmangled=[%exprPpx_deriving_hardcaml_runtime.concat[[%emangle_name~locnamemangle];Ppx_deriving_hardcaml_runtime.Int.to_string_i]]inletrtlident=mk_rtlident~locmangledprefixsuffixinletmapid=pexp_ident~loc(Located.mk~loc(Ldot(mname,"map")))inexpand_array_init_str~locrtlidentmapidmidlabel_declaration(* Default *)|_->raise_errorf~loc"[%s] expand_t_label_array: only supports abstract record labels"deriverletexpand_t_label_listvarloclabel_declarationnameprefixsuffixmangledesc=letainit=expand_t_label_arrayvarloclabel_declarationnameprefixsuffixmangledescin[%exprPpx_deriving_hardcaml_runtime.Array.to_list[%eainit]]letexpand_t_labeloptsvar({pld_name={txt;loc;_};pld_type;_}aslabel_declaration)=letrtlname=get_rtlname~loctxtlabel_declarationandrtlprefix=get_rtlprefix~locoptslabel_declarationandrtlsuffix=get_rtlsuffix~locoptslabel_declarationandrtlmangle=get_rtlmangle~locoptslabel_declarationinletexpr=matchpld_type.ptyp_descwith(* 'a *)|Ptyp_varvwhenString.equalvvar->letnbits=get_bits~loclabel_declarationandrtlident=mk_rtlident~locrtlnamertlprefixrtlsuffixinpexp_tuple~loc[rtlident;nbits](* 'a Module.t *)|Ptyp_constr(({txt=Ldot(mname,_);_}asmid),[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->letmangled=mangle_name~locrtlnamertlmangleinletrtlident=mk_rtlident~locmangledrtlprefixrtlsuffixinletmapid=pexp_ident~loc(Located.mk~loc(Ldot(mname,"map")))in[%expr[%emapid][%epexp_ident~locmid]~f:(fun(_n,_b)->[%ertlident],_b)](* 'a list, 'a Module.t list *)|Ptyp_constr({txt=Lident("list");_},[{ptyp_desc;_}])->expand_t_label_listvarloclabel_declarationrtlnamertlprefixrtlsuffixrtlmangleptyp_desc(* 'a array, 'a Module.t array *)|Ptyp_constr({txt=Lident("array");_},[{ptyp_desc;_}])->expand_t_label_arrayvarloclabel_declarationrtlnamertlprefixrtlsuffixrtlmangleptyp_desc(* Default *)|_->raise_errorf~loc"[%s] expand_t_label: only supports abstract record labels"deriverin(Located.mk~loc(Lidenttxt),expr)(*
* Expand map label
*)letmkfieldvarmemb=letloc=Location.noneinpexp_field~loc(pexp_ident~loc(Located.mk~loc(Lident(var))))(Located.mk~loc(Lident(memb)))moduleIter_or_map=structtypet=Iter|Mapletname=function|Iter->"iter"|Map->"map"letname2=function|Iter->"iter2"|Map->"map2"letarray_maptloc=matchtwith|Iter->[%exprPpx_deriving_hardcaml_runtime.Array.iter]|Map->[%exprPpx_deriving_hardcaml_runtime.Array.map]letarray_inittloc=matchtwith|Iter->[%exprPpx_deriving_hardcaml_runtime.Array.for_]|Map->[%exprPpx_deriving_hardcaml_runtime.Array.init]letlist_maptloc=matchtwith|Iter->[%exprPpx_deriving_hardcaml_runtime.List.iter]|Map->[%exprPpx_deriving_hardcaml_runtime.List.map]letlist_map2_exntloc=matchtwith|Iter->[%exprPpx_deriving_hardcaml_runtime.List.iter2_exn]|Map->[%exprPpx_deriving_hardcaml_runtime.List.map2_exn]endletexpand_map_label_listiter_or_mapvarlocident=function(* 'a *)|Ptyp_var(v)whenString.equalvvar->[%expr[%eIter_or_map.list_mapiter_or_maploc][%eident]~f](* 'a Module.t *)|Ptyp_constr({txt=Ldot(mname,_);_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->letmapid=pexp_ident~loc(Located.mk~loc(Ldot(mname,Iter_or_map.nameiter_or_map)))in[%expr[%eIter_or_map.list_mapiter_or_maploc][%eident]~f:(fun_e->[%emapid]_e~f)](* Default *)|_->raise_errorf~loc"[%s] expand_map_label_list: only supports abstract record labels"deriverletexpand_map_label_arrayiter_or_mapvarlocident=function(* 'a *)|Ptyp_var(v)whenString.equalvvar->[%expr[%eIter_or_map.array_mapiter_or_maploc][%eident]~f](* 'a Module.t *)|Ptyp_constr({txt=Ldot(mname,_);_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->letmapid=pexp_ident~loc(Located.mk~loc(Ldot(mname,Iter_or_map.nameiter_or_map)))in[%expr[%eIter_or_map.array_mapiter_or_maploc][%eident]~f:(fun_e->[%emapid]_e~f)](* Default *)|_->raise_errorf~loc"[%s] expand_map_label_list: only supports abstract record labels"derivermoduleRecord_field=structtypet={label_declaration:label_declaration;expression:expression}letexpressiont=t.expressionletlabel_textt=t.label_declaration.pld_name.txtendletexpand_map_labeliter_or_mapvar({pld_name={txt;loc;_};_}aslabel_declaration):Record_field.t=letident=mkfield"x"txtinletexpression=matchlabel_declaration.pld_type.ptyp_descwith(* 'a *)|Ptyp_varvwhenString.equalvvar->[%exprf[%eident]](* 'a Module.t *)|Ptyp_constr({txt=Ldot(mname,_);_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->letmapid=pexp_ident~loc(Located.mk~loc(Ldot(mname,Iter_or_map.nameiter_or_map)))in[%expr[%emapid][%eident]~f](* 'a list, 'a Module.t list *)|Ptyp_constr({txt=Lident("list");_},[{ptyp_desc;_}])->expand_map_label_listiter_or_mapvarlocidentptyp_desc(* 'a array, 'a Module.t array *)|Ptyp_constr({txt=Lident("array");_},[{ptyp_desc;_}])->expand_map_label_arrayiter_or_mapvarlocidentptyp_desc(* Default *)|_->raise_errorf~loc"[%s] expand_map_label: only supports abstract record labels"deriverin{label_declaration;expression}(*
* Expand map2 label
*)letexpand_map2_label_listiter_or_mapvarlocident0ident1=function(* 'a *)|Ptyp_var(v)whenString.equalvvar->[%expr[%eIter_or_map.list_map2_exniter_or_maploc][%eident0][%eident1]~f](* 'a Module.t *)|Ptyp_constr({txt=Ldot(mname,_);_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->letmapid=pexp_ident~loc(Located.mk~loc(Ldot(mname,Iter_or_map.name2iter_or_map)))in[%expr[%eIter_or_map.list_map2_exniter_or_maploc][%eident0][%eident1]~f:(fun_e0_e1->[%emapid]_e0_e1~f)](* Default *)|_->raise_errorf~loc"[%s] expand_map_label_list: only supports abstract record labels"deriverletexpand_map2_label_arrayiter_or_mapvarlocident0ident1=function(* 'a *)|Ptyp_var(v)whenString.equalvvar->[%expr[%eIter_or_map.array_inititer_or_maploc](Array.length[%eident0])~f:(fun_i->f(Ppx_deriving_hardcaml_runtime.Array.get[%eident0]_i)(Ppx_deriving_hardcaml_runtime.Array.get[%eident1]_i))](* 'a Module.t *)|Ptyp_constr({txt=Ldot(mname,_);_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->letmapid=pexp_ident~loc(Located.mk~loc(Ldot(mname,Iter_or_map.name2iter_or_map)))in[%expr[%eIter_or_map.array_inititer_or_maploc](Array.length[%eident0])~f:(fun_i->[%emapid](Ppx_deriving_hardcaml_runtime.Array.get[%eident0]_i)(Ppx_deriving_hardcaml_runtime.Array.get[%eident1]_i)~f)](* Default *)|_->raise_errorf~loc"[%s] expand_map_label_list: only supports abstract record labels"deriverletexpand_map2_labeliter_or_mapvar({pld_name={txt;loc;_};_}aslabel_declaration):Record_field.t=letident0=mkfield"x0"txtinletident1=mkfield"x1"txtinletexpression=matchlabel_declaration.pld_type.ptyp_descwith(* 'a *)|Ptyp_varvwhenString.equalvvar->[%exprf[%eident0][%eident1]](* 'a Module.t *)|Ptyp_constr({txt=Ldot(mname,_);_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->letmapid=pexp_ident~loc(Located.mk~loc(Ldot(mname,Iter_or_map.name2iter_or_map)))in[%expr[%emapid][%eident0][%eident1]~f](* 'a list, 'a Module.t list *)|Ptyp_constr({txt=Lident("list");_},[{ptyp_desc;_}])->expand_map2_label_listiter_or_mapvarlocident0ident1ptyp_desc(* 'a array, 'a Module.t array *)|Ptyp_constr({txt=Lident("array");_},[{ptyp_desc;_}])->expand_map2_label_arrayiter_or_mapvarlocident0ident1ptyp_desc(* Default *)|_->raise_errorf~loc"[%s] expand_map2_label: only supports abstract record labels"deriverin{label_declaration;expression}(*
* Expand to_list label
*)letexpand_to_list_label_listvarlocident=function(* 'a *)|Ptyp_var(v)whenString.equalvvar->ident(* 'a Module.t *)|Ptyp_constr({txt=Ldot(mname,_);_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->letto_list_id=pexp_ident~loc(Located.mk~loc(Ldot(mname,"to_list")))in[%exprPpx_deriving_hardcaml_runtime.List.concat(Ppx_deriving_hardcaml_runtime.List.map[%eident]~f:(fun_e->[%eto_list_id]_e))](* Default *)|_->raise_errorf~loc"[%s] expand_map_label_list: only supports abstract record labels"deriverletexpand_to_list_label_arrayvarlocidentdesc=expand_to_list_label_listvarloc[%exprPpx_deriving_hardcaml_runtime.Array.to_list[%eident]]descletexpand_to_list_labelvar({pld_name={txt;loc;_};_}aslabel)=letident=mkfield"x"txtinmatchlabel.pld_type.ptyp_descwith(* 'a *)|Ptyp_varvwhenString.equalvvar->[%expr[[%eident]]](* 'a Module.t *)|Ptyp_constr({txt=Ldot(mname,_);_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->pexp_apply~loc(pexp_ident~loc(Located.mk~loc(Ldot(mname,"to_list"))))[(Nolabel,ident)](* 'a list, 'a Module.t list *)|Ptyp_constr({txt=Lident("list");_},[{ptyp_desc;_}])->expand_to_list_label_listvarlocidentptyp_desc(* 'a array, 'a Module.t array *)|Ptyp_constr({txt=Lident("array");_},[{ptyp_desc;_}])->expand_to_list_label_arrayvarlocidentptyp_desc(* Default *)|_->raise_errorf~loc"[%s] expand_to_list_label: only supports abstract record labels"deriverletbuild_expr_listlabels=letloc=Location.noneinList.fold_rightlabels~f:(funexpracc->pexp_construct~loc(Located.mk~loc(Lident"::"))(Some(pexp_tuple~loc[expr;acc])))~init:(pexp_construct~loc(Located.mk~loc(Lident"[]"))None)(*
* Expand ast label
*)letexpand_ast_labeloptsvar({pld_name={txt;loc;_};pld_type;_}aslabel_declaration)=letexpand_exprptyp_desc=letrtlname=get_rtlname~loctxtlabel_declarationandrtlprefix=get_rtlprefix~locoptslabel_declarationandrtlsuffix=get_rtlsuffix~locoptslabel_declaration(* and rtlmangle = get_rtlmangle ~loc opts label_declaration *)inletsignal()=letrtlident=mk_rtlident~locrtlnamertlprefixrtlsuffixinletbits=get_bits~loclabel_declarationin[%exprSignal{bits=[%ebits];rtlname=[%ertlident]}]inletmodule_mname=letast=pexp_ident~loc(Located.mk~loc(Ldot(mname,"ast")))inletmname=letmname=Longident.flatten_exnmname|>String.concat~sep:"."inestring~locmnamein[%exprModule{name=[%emname];ast=[%east]}]inletsequencekind=letlength=get_length~loclabel_declarationin[%exprSome{kind=[%ekind];length=[%elength]}]inlettype_,sequence=matchptyp_descwith(* 'a *)|Ptyp_varvwhenString.equalvvar->signal(),[%exprNone](* 'a Module.t *)|Ptyp_constr({txt=Ldot(mname,_);_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->module_mname,[%exprNone](* 'a list *)|Ptyp_constr({txt=Lident("list");_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->signal(),sequence[%exprList](* 'a Module.t list *)|Ptyp_constr({txt=Lident("list");_},[{ptyp_desc=Ptyp_constr({txt=Ldot(mname,_);_},[{ptyp_desc=Ptyp_var(v);_}]);_}])whenString.equalvvar->module_mname,sequence[%exprList](* 'a array *)|Ptyp_constr({txt=Lident("array");_},[{ptyp_desc=Ptyp_var(v);_}])whenString.equalvvar->signal(),sequence[%exprArray](* 'a Module.t array *)|Ptyp_constr({txt=Lident("array");_},[{ptyp_desc=Ptyp_constr({txt=Ldot(mname,_);_},[{ptyp_desc=Ptyp_var(v);_}]);_}])whenString.equalvvar->module_mname,sequence[%exprArray](* Default *)|_->raise_errorf~loc"[%s] expand_doc_label: only supports abstract record labels"deriverinletfield_name=field_name~loctxtinletdoc=matchget_doc~loclabel_declarationwith|None->[%exprNone]|Somedoc->[%exprSome[%eestring~locdoc]]in[%expr{Ppx_deriving_hardcaml_runtime.Interface.Ast.Field.name=[%efield_name];type_=[%etype_];sequence=[%esequence];doc=[%edoc]}]inexpand_exprpld_type.ptyp_desc(*
* PPX deriving
*)letpexp_sequenceN~locexprs=matchList.revexprswith|[]->[%expr()]|[e]->e|last::es->List.foldes~init:last~f:(funace->pexp_sequence~loceac)letrecord_fields(iter_or_map:Iter_or_map.t)~locfields=matchiter_or_mapwith|Iter->pexp_sequenceN~loc(List.mapfields~f:Record_field.expression)|Map->pexp_let~locNonrecursive(List.mapfields~f:(funrecord_field->value_binding~loc~pat:(pvar~loc(Record_field.label_textrecord_field))~expr:record_field.expression))(pexp_record~loc(List.mapfields~f:(funrecord_field->letid=Located.mk~loc(Lident(Record_field.label_textrecord_field))in(id,pexp_ident~locid)))None)letstr_of_type~options({ptype_loc=loc;_}astype_decl)=matchtype_decl.ptype_kind,type_decl.ptype_params,type_decl.ptype_manifestwith|Ptype_recordlabels,[({ptyp_desc=Ptyp_var(var);_},_)],None->letstr_t_labels=List.maplabels~f:(expand_t_labeloptionsvar)inletstr_t=pexp_record~locstr_t_labelsNoneinletstr_mapiter_or_map=letfields=List.maplabels~f:(expand_map_labeliter_or_mapvar)in[%exprfunx~f->[%erecord_fieldsiter_or_map~locfields]]inletstr_map2iter_or_map=letfields=List.maplabels~f:(expand_map2_labeliter_or_mapvar)in[%exprfunx0x1~f->[%erecord_fieldsiter_or_map~locfields]]inletstr_to_list_labels=List.maplabels~f:(expand_to_list_labelvar)inletstr_to_list_args=build_expr_liststr_to_list_labelsinletstr_to_list=[%exprfunx->Ppx_deriving_hardcaml_runtime.List.concat[%estr_to_list_args]]inletstr_ast_labels()=List.maplabels~f:(expand_ast_labeloptionsvar)inletstr_ast()=build_expr_list(str_ast_labels())in[pstr_value~locNonrecursive([value_binding~loc~pat:(pvar~loc"t")~expr:str_t;value_binding~loc~pat:(pvar~loc"iter")~expr:(str_mapIter);value_binding~loc~pat:(pvar~loc"iter2")~expr:(str_map2Iter);value_binding~loc~pat:(pvar~loc"map")~expr:(str_mapMap);value_binding~loc~pat:(pvar~loc"map2")~expr:(str_map2Map);value_binding~loc~pat:(pvar~loc"to_list")~expr:str_to_list]@ifoptions.astthen[value_binding~loc~pat:(pvar~loc"ast")~expr:(str_ast())]else[]);[%striincludePpx_deriving_hardcaml_runtime.Interface.Make(structtypenonrec'at='atletsexp_of_t=sexp_of_tlett=tletiter=iterletiter2=iter2letmap=mapletmap2=map2letto_list=to_listend)]]|_->raise_errorf~loc"[%s] str_of_type: only supports record types"deriverletsig_of_type~ast({ptype_loc=loc;_}astype_decl)=matchtype_decl.ptype_kind,type_decl.ptype_paramswith|Ptype_recordlabels,[({ptyp_desc=Ptyp_var(v);_},_)]->List.iterlabels~f:(check_labelv);letintf=[%sigi:includePpx_deriving_hardcaml_runtime.Interface.Swithtype'at:='at]inifastthen[intf;[%sigi:valast:Ppx_deriving_hardcaml_runtime.Interface.Ast.t]]else[intf]|_,_->raise_errorf~loc"[%s] sig_of_type: only supports record types"deriverlet()=letget_bool_option~locoptionname=matchoptionwith|None->false|Somee->parse_boolnamee~locinDeriving.addderiver~str_type_decl:(Deriving.Generator.makeDeriving.Args.(empty+>arg"rtlprefix"Ast_pattern.__+>arg"rtlsuffix"Ast_pattern.__+>arg"rtlmangle"Ast_pattern.__+>flag"ast")(fun~loc~path:_(_,type_declarations)rtlprefixrtlsuffixrtlmangleast->letoptions={rtlprefix;rtlsuffix;rtlmangle=get_bool_option~locrtlmangle"rtlmangle";ast}inList.concat_maptype_declarations~f:(fundecl->str_of_type~optionsdecl)))~sig_type_decl:(Deriving.Generator.makeDeriving.Args.(empty+>flag"ast")~deps:[Ppx_sexp_conv.sexp_of](fun~loc:_~path:_(_,type_declarations)ast->List.concat_maptype_declarations~f:(sig_of_type~ast)))|>Deriving.ignore;;