Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file deriving_reify.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262(*
* OCanren. PPX syntax extensions.
* Copyright (C) 2015-2021
* Dmitri Boulytchev, Dmitry Kosarev, Alexey Syomin, Evgeny Moiseenko
* St.Petersburg State University, JetBrains Research
*
* This software is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2, as published by the Free Software Foundation.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU Library General Public License version 2 for more details
* (enclosed in the file COPYING).
*)modulePprintast_=PprintastopenBaseopenPpxlibopenPpxlib.Ast_builder.DefaultmoduleFormat=Caml.FormatopenMyhelpersletfailwiths?(loc=Location.none)fmt=Location.raise_errorf~locfmtincludestructletmake_typ_exn?(ccompositional=false)~lococa_logic_identkindtyp=letrechelper=function|[%type:int]ast->oca_logic_ident~loc:t.ptyp_loct|t->(matcht.ptyp_descwith|Ptyp_constr({txt=Ldot(Lident"GT",s)},[])->oca_logic_ident~loc:t.ptyp_loct|Ptyp_constr({txt=Ldot(Lident"GT","list")},xs)->ptyp_constr~loc(Located.mk~loc:t.ptyp_loc(lident_of_list["OCanren";"Std";"List";kind]))(List.map~f:helperxs)|Ptyp_constr({txt=Ldot(path,"ground")},xs)->ptyp_constr~loc(Located.mk~loc(Ldot(path,kind)))(List.map~f:helperxs)|Ptyp_constr({txt=Lident"ground"},xs)->ptyp_constr~loc(Located.mk~loc(Lidentkind))xs|Ptyp_tuple[l;r]->ptyp_constr~loc(Located.mk~loc:t.ptyp_loc(lident_of_list["OCanren";"Std";"Pair";kind]))[helperl;helperr]|Ptyp_constr({txt=Lidents},[])->oca_logic_ident~loc:t.ptyp_loct|Ptyp_constr(({txt=Lident"t"}asid),xs)->oca_logic_ident~loc:t.ptyp_loc@@ptyp_constr~locid(List.map~f:helperxs)|_->t)inmatchtypwith|{ptyp_desc=Ptyp_constr(id,args)}->ifccompositionalthenhelpertypelse(letttt=ptyp_constr~locid(List.map~f:helperargs)inoca_logic_ident~locttt)|{ptyp_desc=Ptyp_tuple[l;r]}->ptyp_constr~loc(Located.mk~loc@@lident_of_list["OCanren";"Std";"Pair";kind])(List.map~f:helper[l;r])|_->Location.raise_errorf~loc"can't generate %s type: %a"kindPpxlib.Pprintast.core_typetyp;;letltypify_exn?(ccompositional=false)~loctyp=letoca_logic_ident~loc=Located.mk~loc(lident_of_list["OCanren";"logic"])inmake_typ_exn~ccompositional~loc(fun~loct->ptyp_constr~loc(oca_logic_ident~loc:t.ptyp_loc)[t])"logic"typ;;letgtypify_exn?(ccompositional=false)~loctyp=make_typ_exn~ccompositional~loc(fun~loct->t)"ground"typ;;let%expect_test_=letloc=Location.noneinlettesti=lett2=matchi.pstr_descwith|Pstr_type(_,[{ptype_manifest=Somet}])->ltypify_exn~ccompositional:true~loct|_->assertfalseinFormat.printf"%a\n%!"Ppxlib.Pprintast.core_typet2intest[%stritypet1=(int*int)Std.List.ground];[%expect{| (int OCanren.logic, int OCanren.logic) OCanren.Std.Pair.logic Std.List.logic |}];();;endtypekind=|Reify|Prj_exnletunwrap_kind~loc=function|Reify->[%exprOCanren.reify],"reify"|Prj_exn->[%exprOCanren.prj_exn],"prj_exn";;letreifier_of_core_type~lockind=letbase_reifier,reifier_name=unwrap_kind~lockindinletrechelpertyp=letloc=typ.ptyp_locinmatchtypwith|{ptyp_desc=Ptyp_constr({txt=Ldot(Lident"GT","list")},xs)}->Exp.apply~loc(pexp_ident~loc(Located.mk~loc(lident_of_list["Std";"List";reifier_name])))(List.mapxs~f:helper)|[%type:GT.string]|[%type:string]|[%type:GT.bool]|[%type:bool]|[%type:GT.int]|[%type:int]->base_reifier|{ptyp_desc=Ptyp_constr({txt=Lident"ground"},xs)}->Exp.apply~loc(pexp_ident~loc(Located.mk~loc(lidentreifier_name)))(List.map~f:helperxs)|{ptyp_desc=Ptyp_constr({txt=Ldot(m,"ground")},xs)}->Exp.apply~loc(pexp_ident~loc(Located.mk~loc(Ldot(m,reifier_name))))(List.mapxs~f:helper)|{ptyp_desc=Ptyp_vars}->pexp_ident~loc(Located.mk~loc(lidents))|{ptyp_desc=Ptyp_constr({txt=Ldot(Lidentm,_)},args)}->pexp_apply~loc(pexp_ident~loc(Located.mk~loc(Ldot(lidentm,reifier_name))))(List.mapargs~f:(funt->Nolabel,helpert))|{ptyp_desc=Ptyp_constr({txt=Lident"t"},args)}->pexp_apply~loc(pexp_ident~loc(Located.mk~loc(Lidentreifier_name)))(List.mapargs~f:(funt->Nolabel,helpert))|{ptyp_desc=Ptyp_tuple[l;r]}->Exp.apply~loc(pexp_ident~loc(Located.mk~loc(Ldot(Ldot(Lident"Std","Pair"),reifier_name))))[helperl;helperr]|_->failwiths~loc"Generation of compositional reifier is not supported yet"inhelper;;letmake_reifier_composition~pat?(typ=None)kindtdecl=letnames=extract_names@@(name_type_params_in_tdtdecl).ptype_paramsinletmk_arg_reifier=Fn.idinletadd_args=letloc=tdecl.ptype_locinletargsrhs=List.fold_rightnames~init:rhs~f:(funnameacc->[%exprfun[%pppat_var~loc(Located.mk~loc(mk_arg_reifiername))]->[%eacc]])inargsinlethelper=reifier_of_core_typekindinletmanifest=matchtdecl.ptype_manifestwith|None->failwiths"A type without manifest %s %d"Caml.__FILE__Caml.__LINE__|Somem->minletbody=letloc=manifest.ptyp_locinmatchmanifest.ptyp_descwith|Ptyp_constr({txt},args)->helper~locmanifest|Ptyp_tuple[l;r]->letbase_reifier,reifier_name=unwrap_kind~lockindinExp.apply~loc(Exp.ident~loc@@lident_of_list["OCanren";"Std";"Pair";reifier_name])[helper~locl;helper~locr]|_->failwiths~loc"This type is not expected as manifest %s %d"Caml.__FILE__Caml.__LINE__inletloc=tdecl.ptype_locinletpat=matchtypwith|None->pat|Somet->ppat_constraint~locpattinpstr_value~locNonrecursive[value_binding~loc~pat~expr:(add_argsbody)];;letprocess1tdecl=letloc=tdecl.ptype_locinmatchtdecl.ptype_manifestwith|Somem->(* TODO: find a way not to pass both manifest and type declration *)[make_reifier_compositionReify~typ:(ifList.is_emptytdecl.ptype_paramsthenSome[%type:(_,[%tltypify_exn~ccompositional:true~locm])Reifier.t]elseNone)~pat:(ppat_var~loc(Located.mk~loc@@Format.sprintf"reify_%s"tdecl.ptype_name.txt))tdecl;make_reifier_compositionPrj_exn~typ:(ifList.is_emptytdecl.ptype_paramsthenSome[%type:(_,[%tgtypify_exn~ccompositional:true~locm])Reifier.t]elseNone)~pat:(ppat_var~loc(Located.mk~loc@@Format.sprintf"prj_exn_%s"tdecl.ptype_name.txt))tdecl]|None->failwiths~loc"no manifest";;letstr_type_decl:(_,_)Deriving.Generator.t=Deriving.Generator.makeDeriving.Args.empty(fun~loc~path(_,info)->List.concat_mapinfo~f:process1);;let()=Deriving.add"reify"~str_type_decl~extension:(fun~loc~path:_->reifier_of_core_type~locReify)|>Deriving.ignore;;let()=Deriving.add"prj_exn"~extension:(fun~loc~path:_->reifier_of_core_type~locPrj_exn)|>Deriving.ignore;;