123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273(******************************************************************************)(* OASIS: architecture for building OCaml libraries and applications *)(* *)(* Copyright (C) 2011-2016, Sylvain Le Gall *)(* Copyright (C) 2008-2011, OCamlCore SARL *)(* *)(* This library is free software; you can redistribute it and/or modify it *)(* under the terms of the GNU Lesser General Public License as published by *)(* the Free Software Foundation; either version 2.1 of the License, or (at *)(* your option) any later version, with the OCaml static compilation *)(* exception. *)(* *)(* This library 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 file COPYING for more *)(* details. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* along with this library; if not, write to the Free Software Foundation, *)(* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *)(******************************************************************************)(** OCaml data notation.
This module helps to translate OCaml data into a string following
OCaml syntax.
*)(** {2 Types}
*)typemodule_name=stringtypefield_name=stringtypevariant_name=stringtypevar_name=stringtypet=(** Record *)|RECofmodule_name*(field_name*t)list(** List *)|LSToftlist(** String *)|STRofstring(** Variant type constructor *)|VRTofvariant_name*tlist(** Boolean *)|BOOofbool(** Tuple *)|TPLoftlist(** Unit () *)|UNT(** Function application *)|APPofvar_name*(var_name*t)list*tlist(** Variable *)|VARofvar_name(** Polymorphic variant *)|PVRofvariant_name*toption(** {2 Basic conversion}
*)letof_unit()=UNTletof_boolb=BOObletof_strings=STRsletof_optionf=function|Somev->VRT("Some",[fv])|None->VRT("None",[])letof_listflst=LST(List.mapflst)(** {2 Function conversion}
*)(** Function that can be generated using
func_call = APP(func, [], [func_arg]).
*)type'afunc={func_call:'a;func_name:string;func_arg:toption;}(** Return the OCaml function corresponding to a [func].
*)letfuncff_nm={func_call=f;func_name=f_nm;func_arg=None;}(** Create a func with an argument
*)letfunc_with_argff_nmargodn_of_arg={func_call=farg;func_name=f_nm;func_arg=Some(odn_of_argarg);}letfunc_with_arg_ctxtff_nmargodn_of_arg={func_call=(fun~ctxt->f~ctxtarg);func_name=f_nm;func_arg=Some(odn_of_argarg);}(** Return the [t] code corresponding to a [func].
*)letodn_of_funct=matcht.func_argwith|Somearg->APP(t.func_name,[],[arg])|None->VARt.func_name(** Return the OCaml function corresponding to a [func].
*)letfunc_callt=t.func_call(** {2 Formating}
*)openFormatletpp_odn?(opened_modules=[])fmtt=letopened_modules=(* Use opened modules starting with the bigger *)List.sort(funmod1mod2->String.lengthmod2-String.lengthmod1)opened_modulesinletpp_listpp_elemlst_sepfmt=function|[]->()|hd::tl->pp_elemfmthd;List.iter(fune->fprintffmtlst_sep;pp_elemfmte)tlinletpp_print_idfmtid=letchop_opened_modulestr=tryletstr_len=String.lengthstrinletmatching_opened_mod=List.find(funopened_mod->letopened_mod_len=String.lengthopened_modinifopened_mod_len+1<=str_lenthen(opened_mod=String.substr0opened_mod_len)&&str.[opened_mod_len]='.'elsefalse)opened_modulesinletchop_prefix_len=(String.lengthmatching_opened_mod)+1inString.substrchop_prefix_len(str_len-chop_prefix_len)withNot_found->strinpp_print_stringfmt(chop_opened_moduleid)inletrecpp_odn_auxfmt=function|REC(mod_nm,flds)->beginletrecprint_fieldsfmtfirstfields=letprint_fieldfmt(fld,e)=fprintffmt"@[<hv 2>%a =@ %a@]"(* We use the first field to add the module name at the
* beginning. *)pp_print_id(iffirstthenmod_nm^"."^fldelsefld)pp_odn_auxeinmatchfieldswith|[fld,e]->print_fieldfmt(fld,e)|(fld,e)::tl->print_fieldfmt(fld,e);fprintffmt";@ ";print_fieldsfmtfalsetl|[]->()infprintffmt"@[{@[<hv 2>@,";print_fieldsfmttrueflds;fprintffmt"@]@,}@]"end|LSTlst->fprintffmt"@[[@[<hv 2>@,%a@]@,]@]"(pp_listpp_odn_aux";@ ")lst|STRstr->fprintffmt"%S"str|VRT(nm,[])->pp_print_idfmtnm|VRT(nm,lst)->fprintffmt"@[<hv 2>%a@ %a@]"pp_print_idnmpp_odn_aux(TPLlst)|BOOb->pp_print_boolfmtb|TPL[]->pp_print_stringfmt"()"|TPL[(STR_)asv]|TPL[(REC_)asv]|TPL[(LST_)asv]|TPL[(BOO_)asv]|TPL[UNTasv]|TPL[(VAR_)asv]->pp_odn_auxfmtv|TPLlst->fprintffmt"@[<hv 2>(%a)@]"(pp_listpp_odn_aux",@ ")lst|UNT->pp_print_stringfmt"()"|APP(fnm,named_args,args)->fprintffmt"@[<hv 2>%a%a%a@]"pp_print_idfnm(pp_list(funfmt(nm,e)->fprintffmt"@ ~%s:%a"nmpp_odn_auxe)"")named_args(pp_list(funfmte->fprintffmt"@ %a"pp_odn_auxe)"")args|VARnm->pp_print_idfmtnm|PVR(nm,None)->pp_print_idfmt("`"^nm)|PVR(nm,Sometpl)->fprintffmt"@[<hv 2>`%a@ %a@]"pp_print_idnmpp_odn_auxtplinpp_odn_auxfmtt