1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813(**************************************************************************)(* *)(* OCaml *)(* *)(* Thomas Gazagnaire, OCamlPro *)(* Fabrice Le Fessant, INRIA Saclay *)(* Hongbo Zhang, University of Pennsylvania *)(* *)(* Copyright 2007 Institut National de Recherche en Informatique et *)(* en Automatique. *)(* *)(* All rights reserved. This file is distributed under the terms of *)(* the GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)(* Original Code from Ber-metaocaml, modified for 3.12.0 and fixed *)(* Printing code expressions *)(* Authors: Ed Pizzi, Fabrice Le Fessant *)(* Extensive Rewrite: Hongbo Zhang: University of Pennsylvania *)(* TODO more fine-grained precedence pretty-printing *)openAst_502openAsttypesopenFormatopenLocationopenLongidentopenParsetreemoduleOption=structletvaluet~default=matchtwithNone->default|Somex->xendletvarify_type_constructorsvar_namest=letcheck_variablevllocv=ifList.memvvlthenLocation.raise_errorf~loc"variable in scope syntax error: %s"vinletvar_names=List.map(funv->v.txt)var_namesinletrecloopt=letdesc=matcht.ptyp_descwith|Ptyp_any->Ptyp_any|Ptyp_varx->check_variablevar_namest.ptyp_locx;Ptyp_varx|Ptyp_arrow(label,core_type,core_type')->Ptyp_arrow(label,loopcore_type,loopcore_type')|Ptyp_tuplelst->Ptyp_tuple(List.maplooplst)|Ptyp_constr({txt=Longident.Lidents},[])whenList.memsvar_names->Ptyp_vars|Ptyp_constr(longident,lst)->Ptyp_constr(longident,List.maplooplst)|Ptyp_object(lst,o)->Ptyp_object(List.maploop_object_fieldlst,o)|Ptyp_class(longident,lst)->Ptyp_class(longident,List.maplooplst)|Ptyp_alias(core_type,string)->check_variablevar_namest.ptyp_locstring.txt;Ptyp_alias(loopcore_type,string)|Ptyp_variant(row_field_list,flag,lbl_lst_option)->Ptyp_variant(List.maploop_row_fieldrow_field_list,flag,lbl_lst_option)|Ptyp_poly(string_lst,core_type)->List.iter(funv->check_variablevar_namest.ptyp_locv.txt)string_lst;Ptyp_poly(string_lst,loopcore_type)|Ptyp_package(longident,lst)->Ptyp_package(longident,List.map(fun(n,typ)->(n,looptyp))lst)|Ptyp_extension(s,arg)->Ptyp_extension(s,arg)|Ptyp_open(s,ct)->Ptyp_open(s,loopct)in{twithptyp_desc=desc}andloop_row_fieldfield=letprf_desc=matchfield.prf_descwith|Rtag(label,flag,lst)->Rtag(label,flag,List.maplooplst)|Rinheritt->Rinherit(loopt)in{fieldwithprf_desc}andloop_object_fieldfield=letpof_desc=matchfield.pof_descwith|Otag(label,t)->Otag(label,loopt)|Oinheritt->Oinherit(loopt)in{fieldwithpof_desc}inlooptletprefix_symbols=['!';'?';'~']letinfix_symbols=['=';'<';'>';'@';'^';'|';'&';'+';'-';'*';'/';'$';'%';'#'](* type fixity = Infix| Prefix *)letspecial_infix_strings=["asr";"land";"lor";"lsl";"lsr";"lxor";"mod";"or";":=";"!=";"::"]letletops=String.lengths>3&&s.[0]='l'&&s.[1]='e'&&s.[2]='t'&&List.mems.[3]infix_symbolsletandops=String.lengths>3&&s.[0]='a'&&s.[1]='n'&&s.[2]='d'&&List.mems.[3]infix_symbols(* determines if the string is an infix string.
checks backwards, first allowing a renaming postfix ("_102") which
may have resulted from Pexp -> Texp -> Pexp translation, then checking
if all the characters in the beginning of the string are valid infix
characters. *)letfixity_of_string=function|""->`Normal|swhenList.memsspecial_infix_strings->`Infixs|swhenList.mems.[0]infix_symbols->`Infixs|swhenList.mems.[0]prefix_symbols->`Prefixs|swhens.[0]='.'->`Mixfixs|swhenletops->`Letops|swhenandops->`Andops|_->`Normalletview_fixity_of_exp=function|{pexp_desc=Pexp_ident{txt=Lidentl;_};pexp_attributes=[]}->fixity_of_stringl|_->`Normalletis_infix=function`Infix_->true|_->falseletis_mixfix=function`Mixfix_->true|_->falseletis_kwdop=function`Letop_|`Andop_->true|_->falseletfirst_iscstr=str<>""&&str.[0]=cletlast_iscstr=str<>""&&str.[String.lengthstr-1]=cletfirst_is_incsstr=str<>""&&List.memstr.[0]cs(* which identifiers are in fact operators needing parentheses *)letneeds_parenstxt=letfix=fixity_of_stringtxtinis_infixfix||is_mixfixfix||is_kwdopfix||first_is_inprefix_symbolstxt(* some infixes need spaces around parens to avoid clashes with comment
syntax *)letneeds_spacestxt=first_is'*'txt||last_is'*'txtletstring_locppfx=fprintfppf"%s"x.txt(* add parentheses to binders when they are in fact infix or prefix operators *)letprotect_identppftxt=letformat:(_,_,_)format=ifnot(needs_parenstxt)then"%s"elseifneeds_spacestxtthen"(@;%s@;)"else"(%s)"infprintfppfformattxtletprotect_longidentppfprint_longidentlongprefixtxt=letformat:(_,_,_)format=ifnot(needs_parenstxt)then"%a.%s"elseifneeds_spacestxtthen"%a.(@;%s@;)"else"%a.(%s)"infprintfppfformatprint_longidentlongprefixtxttypespace_formatter=(unit,Format.formatter,unit)formatletoverride=functionOverride->"!"|Fresh->""(* variance encoding: need to sync up with the [parser.mly] *)lettype_variance=function|NoVariance->""|Covariant->"+"|Contravariant->"-"lettype_injectivity=functionNoInjectivity->""|Injective->"!"typeconstruct=[`consofexpressionlist|`listofexpressionlist|`nil|`normal|`simpleofLongident.t|`tuple]letview_exprx=matchx.pexp_descwith|Pexp_construct({txt=Lident"()";_},_)->`tuple|Pexp_construct({txt=Lident"[]";_},_)->`nil|Pexp_construct({txt=Lident"::";_},Some_)->letrecloopexpacc=matchexpwith|{pexp_desc=Pexp_construct({txt=Lident"[]";_},_);pexp_attributes=[];}->(List.revacc,true)|{pexp_desc=Pexp_construct({txt=Lident"::";_},Some{pexp_desc=Pexp_tuple[e1;e2];pexp_attributes=[]});pexp_attributes=[];}->loope2(e1::acc)|e->(List.rev(e::acc),false)inletls,b=loopx[]inifbthen`listlselse`consls|Pexp_construct(x,None)->`simplex.txt|_->`normalletis_simple_construct:construct->bool=function|`nil|`tuple|`list_|`simple_->true|`cons_|`normal->falseletpp=fprintftypectxt={pipe:bool;semi:bool;ifthenelse:bool;functionrhs:bool}letreset_ctxt={pipe=false;semi=false;ifthenelse=false;functionrhs=false}letunder_pipectxt={ctxtwithpipe=true}letunder_semictxt={ctxtwithsemi=true}letunder_ifthenelsectxt={ctxtwithifthenelse=true}letunder_functionrhsctxt={ctxtwithfunctionrhs=true}(*
let reset_semi ctxt = { ctxt with semi=false }
let reset_ifthenelse ctxt = { ctxt with ifthenelse=false }
let reset_pipe ctxt = { ctxt with pipe=false }
*)letlist:'a.?sep:space_formatter->?first:space_formatter->?last:space_formatter->(Format.formatter->'a->unit)->Format.formatter->'alist->unit=fun?sep?first?lastfufxs->letfirst=matchfirstwithSomex->x|None->("":_format6)andlast=matchlastwithSomex->x|None->("":_format6)andsep=matchsepwithSomex->x|None->("@ ":_format6)inletauxf=function|[]->()|[x]->fufx|xs->letrecloopf=function|[x]->fufx|x::xs->fufx;ppfsep;loopfxs|_->assertfalseinppffirst;loopfxs;ppflastinauxfxsletoption:'a.?first:space_formatter->?last:space_formatter->(Format.formatter->'a->unit)->Format.formatter->'aoption->unit=fun?first?lastfufa->letfirst=matchfirstwithSomex->x|None->("":_format6)andlast=matchlastwithSomex->x|None->("":_format6)inmatchawith|None->()|Somex->ppffirst;fufx;ppflastletparen:'a.?first:space_formatter->?last:space_formatter->bool->(Format.formatter->'a->unit)->Format.formatter->'a->unit=fun?(first=("":_format6))?(last=("":_format6))bfufx->ifbthen(ppf"(";ppffirst;fufx;ppflast;ppf")")elsefufxletreclongidentf=function|Lidents->protect_identfs|Ldot(y,s)->protect_longidentflongidentys|Lapply(y,s)->ppf"%a(%a)"longidentylongidentsletlongident_locfx=ppf"%a"longidentx.txtletconstantf=function|Pconst_chari->ppf"%C"i|Pconst_string(i,_,None)->ppf"%S"i|Pconst_string(i,_,Somedelim)->ppf"{%s|%s|%s}"delimidelim|Pconst_integer(i,None)->paren(first_is'-'i)(funf->ppf"%s")fi|Pconst_integer(i,Somem)->paren(first_is'-'i)(funf(i,m)->ppf"%s%c"im)f(i,m)|Pconst_float(i,None)->paren(first_is'-'i)(funf->ppf"%s")fi|Pconst_float(i,Somem)->paren(first_is'-'i)(funf(i,m)->ppf"%s%c"im)f(i,m)(* trailing space*)letmutable_flagf=functionImmutable->()|Mutable->ppf"mutable@;"letvirtual_flagf=functionConcrete->()|Virtual->ppf"virtual@;"(* trailing space added *)letrec_flagfrf=matchrfwithNonrecursive->()|Recursive->ppf"rec "letnonrec_flagfrf=matchrfwithNonrecursive->ppf"nonrec "|Recursive->()letdirection_flagf=function|Upto->ppf"to@ "|Downto->ppf"downto@ "letprivate_flagf=functionPublic->()|Private->ppf"private@ "letiter_locfctxt{txt;loc=_}=fctxttxtletconstant_stringfs=ppf"%S"slettyvarppfs=ifString.lengths>=2&&s.[1]='\''then(* without the space, this would be parsed as
a character literal *)Format.fprintfppf"' %s"selseFormat.fprintfppf"'%s"slettyvar_locfstr=tyvarfstr.txtletstring_quotfx=ppf"`%s"x(* c ['a,'b] *)letrecclass_params_defctxtf=function|[]->()|l->ppf"[%a] "(* space *)(list(type_paramctxt)~sep:",")landtype_with_labelctxtf(label,c)=matchlabelwith|Nolabel->core_type1ctxtfc(* otherwise parenthesize *)|Labelleds->ppf"%s:%a"s(core_type1ctxt)c|Optionals->ppf"?%s:%a"s(core_type1ctxt)candcore_typectxtfx=ifx.ptyp_attributes<>[]thenppf"((%a)%a)"(core_typectxt){xwithptyp_attributes=[]}(attributesctxt)x.ptyp_attributeselsematchx.ptyp_descwith|Ptyp_arrow(l,ct1,ct2)->ppf"@[<2>%a@;->@;%a@]"(* FIXME remove parens later *)(type_with_labelctxt)(l,ct1)(core_typectxt)ct2|Ptyp_alias(ct,s)->ppf"@[<2>%a@;as@;%a@]"(core_type1ctxt)cttyvar_locs|Ptyp_poly([],ct)->core_typectxtfct|Ptyp_poly(sl,ct)->ppf"@[<2>%a%a@]"(funfl->ppf"%a"(funfl->matchlwith|[]->()|_->ppf"%a@;.@;"(listtyvar_loc~sep:"@;")l)l)sl(core_typectxt)ct|_->ppf"@[<2>%a@]"(core_type1ctxt)xandcore_type1ctxtfx=ifx.ptyp_attributes<>[]thencore_typectxtfxelsematchx.ptyp_descwith|Ptyp_any->ppf"_"|Ptyp_vars->tyvarfs|Ptyp_tuplel->ppf"(%a)"(list(core_type1ctxt)~sep:"@;*@;")l|Ptyp_constr(li,l)->ppf(* "%a%a@;" *)"%a%a"(funfl->matchlwith|[]->()|[x]->ppf"%a@;"(core_type1ctxt)x|_->list~first:"("~last:")@;"(core_typectxt)~sep:",@;"fl)llongident_locli|Ptyp_variant(l,closed,low)->letfirst_is_inherit=matchlwith|{Parsetree.prf_desc=Rinherit_}::_->true|_->falseinlettype_variant_helperfx=matchx.prf_descwith|Rtag(l,_,ctl)->ppf"@[<2>%a%a@;%a@]"(iter_locstring_quot)l(funfl->matchlwith|[]->()|_->ppf"@;of@;%a"(list(core_typectxt)~sep:"&")ctl)ctl(attributesctxt)x.prf_attributes|Rinheritct->core_typectxtfctinppf"@[<2>[%a%a]@]"(funfl->match(l,closed)with|[],Closed->()|[],Open->ppf">"(* Cf #7200: print [>] correctly *)|_->ppf"%s@;%a"(match(closed,low)with|Closed,None->iffirst_is_inheritthen" |"else""|Closed,Some_->"<"(* FIXME desugar the syntax sugar*)|Open,_->">")(listtype_variant_helper~sep:"@;<1 -2>| ")l)l(funflow->matchlowwith|Some[]|None->()|Somexs->ppf">@ %a"(liststring_quot)xs)low|Ptyp_object(l,o)->letcore_field_typefx=matchx.pof_descwith|Otag(l,ct)->(* Cf #7200 *)ppf"@[<hov2>%s: %a@ %a@ @]"l.txt(core_typectxt)ct(attributesctxt)x.pof_attributes|Oinheritct->ppf"@[<hov2>%a@ @]"(core_typectxt)ctinletfield_varf=function|Asttypes.Closed->()|Asttypes.Open->(matchlwith[]->ppf".."|_->ppf" ;..")inppf"@[<hov2><@ %a%a@ > @]"(listcore_field_type~sep:";")lfield_varo(* Cf #7200 *)|Ptyp_class(li,l)->(*FIXME*)ppf"@[<hov2>%a#%a@]"(list(core_typectxt)~sep:","~first:"("~last:")")llongident_locli|Ptyp_open(li,ct)->ppf"@[<hov2>%a.(%a)@]"longident_locli(core_typectxt)ct|Ptyp_package(lid,cstrs)->(letauxf(s,ct)=ppf"type %a@ =@ %a"longident_locs(core_typectxt)ctinmatchcstrswith|[]->ppf"@[<hov2>(module@ %a)@]"longident_loclid|_->ppf"@[<hov2>(module@ %a@ with@ %a)@]"longident_loclid(listaux~sep:"@ and@ ")cstrs)|Ptyp_extensione->extensionctxtfe|_->parentrue(core_typectxt)fx(********************pattern********************)(* be cautious when use [pattern], [pattern1] is preferred *)andpatternctxtfx=ifx.ppat_attributes<>[]thenppf"((%a)%a)"(patternctxt){xwithppat_attributes=[]}(attributesctxt)x.ppat_attributeselsematchx.ppat_descwith|Ppat_alias(p,s)->ppf"@[<2>%a@;as@;%a@]"(patternctxt)pprotect_idents.txt|_->pattern_orctxtfxandpattern_orctxtfx=letrecleft_associativexacc=matchxwith|{ppat_desc=Ppat_or(p1,p2);ppat_attributes=[]}->left_associativep1(p2::acc)|x->x::accinmatchleft_associativex[]with|[]->assertfalse|[x]->pattern1ctxtfx|orpats->ppf"@[<hov0>%a@]"(list~sep:"@ | "(pattern1ctxt))orpatsandpattern1ctxt(f:Format.formatter)(x:pattern):unit=letrecpattern_list_helperf=function|{ppat_desc=Ppat_construct({txt=Lident"::";_},Some([],{ppat_desc=Ppat_tuple[pat1;pat2];_}));ppat_attributes=[];}->ppf"%a::%a"(simple_patternctxt)pat1pattern_list_helperpat2(*RA*)|p->pattern1ctxtfpinifx.ppat_attributes<>[]thenpatternctxtfxelsematchx.ppat_descwith|Ppat_variant(l,Somep)->ppf"@[<2>`%s@;%a@]"l(simple_patternctxt)p|Ppat_construct({txt=Lident("()"|"[]");_},_)->simple_patternctxtfx|Ppat_construct(({txt;_}asli),po)->(if(* FIXME The third field always false *)txt=Lident"::"thenppf"%a"pattern_list_helperxelsematchpowith|Some([],x)->ppf"%a@;%a"longident_locli(simple_patternctxt)x|Some(vl,x)->ppf"%a@ (type %a)@;%a"longident_locli(list~sep:"@ "string_loc)vl(simple_patternctxt)x|None->ppf"%a"longident_locli)|_->simple_patternctxtfxandsimple_patternctxt(f:Format.formatter)(x:pattern):unit=ifx.ppat_attributes<>[]thenpatternctxtfxelsematchx.ppat_descwith|Ppat_construct({txt=Lident(("()"|"[]")asx);_},None)->ppf"%s"x|Ppat_any->ppf"_"|Ppat_var{txt;_}->protect_identftxt|Ppat_arrayl->ppf"@[<2>[|%a|]@]"(list(pattern1ctxt)~sep:";")l|Ppat_unpack{txt=None}->ppf"(module@ _)@ "|Ppat_unpack{txt=Somes}->ppf"(module@ %s)@ "s|Ppat_typeli->ppf"#%a"longident_locli|Ppat_record(l,closed)->(letlongident_x_patternf(li,p)=match(li,p)with|({txt=Lidents;_},{ppat_desc=Ppat_var{txt;_};ppat_attributes=[];_})whens=txt->ppf"@[<2>%a@]"longident_locli|_->ppf"@[<2>%a@;=@;%a@]"longident_locli(pattern1ctxt)pinmatchclosedwith|Closed->ppf"@[<2>{@;%a@;}@]"(listlongident_x_pattern~sep:";@;")l|_->ppf"@[<2>{@;%a;_}@]"(listlongident_x_pattern~sep:";@;")l)|Ppat_tuplel->ppf"@[<1>(%a)@]"(list~sep:",@;"(pattern1ctxt))l(* level1*)|Ppat_constantc->ppf"%a"constantc|Ppat_interval(c1,c2)->ppf"%a..%a"constantc1constantc2|Ppat_variant(l,None)->ppf"`%s"l|Ppat_constraint(p,ct)->ppf"@[<2>(%a@;:@;%a)@]"(pattern1ctxt)p(core_typectxt)ct|Ppat_lazyp->ppf"@[<2>(lazy@;%a)@]"(simple_patternctxt)p|Ppat_exceptionp->ppf"@[<2>exception@;%a@]"(pattern1ctxt)p|Ppat_extensione->extensionctxtfe|Ppat_open(lid,p)->letwith_paren=matchp.ppat_descwith|Ppat_array_|Ppat_record_|Ppat_construct({txt=Lident("()"|"[]");_},None)->false|_->trueinppf"@[<2>%a.%a @]"longident_loclid(parenwith_paren@@pattern1ctxt)p|_->parentrue(patternctxt)fxandlabel_expctxtf(l,opt,p)=matchlwith|Nolabel->(* single case pattern parens needed here *)ppf"%a@ "(simple_patternctxt)p|Optionalrest->(matchpwith|{ppat_desc=Ppat_var{txt;_};ppat_attributes=[]}whentxt=rest->(matchoptwith|Someo->ppf"?(%s=@;%a)@;"rest(expressionctxt)o|None->ppf"?%s@ "rest)|_->(matchoptwith|Someo->ppf"?%s:(%a=@;%a)@;"rest(pattern1ctxt)p(expressionctxt)o|None->ppf"?%s:%a@;"rest(simple_patternctxt)p))|Labelledl->(matchpwith|{ppat_desc=Ppat_var{txt;_};ppat_attributes=[]}whentxt=l->ppf"~%s@;"l|_->ppf"~%s:%a@;"l(simple_patternctxt)p)andsugar_exprctxtfe=ife.pexp_attributes<>[]thenfalseelsematche.pexp_descwith|Pexp_apply({pexp_desc=Pexp_ident{txt=id;_};pexp_attributes=[];_},args)whenList.for_all(fun(lab,_)->lab=Nolabel)args->(letprint_indexopapath_prefixassignleftseprightprint_indexindicesrem_args=letprint_pathppf=function|None->()|Somem->ppppf".%a"longidentminmatch(assign,rem_args)with|false,[]->ppf"@[%a%a%s%a%s@]"(simple_exprctxt)aprint_pathpath_prefixleft(list~sepprint_index)indicesright;true|true,[v]->ppf"@[%a%a%s%a%s@ <-@;<1 2>%a@]"(simple_exprctxt)aprint_pathpath_prefixleft(list~sepprint_index)indicesright(simple_exprctxt)v;true|_->falseinmatch(id,List.mapsndargs)with|Lident"!",[e]->ppf"@[<hov>!%a@]"(simple_exprctxt)e;true|Ldot(path,(("get"|"set")asfunc)),a::other_args->(letassign=func="set"inletprint=print_indexopaNoneassigninmatch(path,other_args)with|Lident"Array",i::rest->print".("""")"(expressionctxt)[i]rest|Lident"String",i::rest->print".[""""]"(expressionctxt)[i]rest|Ldot(Lident"Bigarray","Array1"),i1::rest->print".{"",""}"(simple_exprctxt)[i1]rest|Ldot(Lident"Bigarray","Array2"),i1::i2::rest->print".{"",""}"(simple_exprctxt)[i1;i2]rest|Ldot(Lident"Bigarray","Array3"),i1::i2::i3::rest->print".{"",""}"(simple_exprctxt)[i1;i2;i3]rest|(Ldot(Lident"Bigarray","Genarray"),{pexp_desc=Pexp_arrayindexes;pexp_attributes=[]}::rest)->print".{"",""}"(simple_exprctxt)indexesrest|_->false)|(Lidents|Ldot(_,s)),a::i::restwhenfirst_is'.'s->(* extract operator:
assignment operators end with [right_bracket ^ "<-"],
access operators end with [right_bracket] directly
*)letmulti_indices=String.containss';'inleti=matchi.pexp_descwith|Pexp_arraylwhenmulti_indices->l|_->[i]inletassign=last_is'-'sinletkind=(* extract the right end bracket *)letn=String.lengthsinifassignthens.[n-3]elses.[n-1]inletleft,right=matchkindwith|')'->('(',")")|']'->('[',"]")|'}'->('{',"}")|_->assertfalseinletpath_prefix=matchidwithLdot(m,_)->Somem|_->Noneinletleft=String.subs0(1+String.indexsleft)inprint_indexopapath_prefixassignleft";"right(ifmulti_indicesthenexpressionctxtelsesimple_exprctxt)irest|_->false)|_->falseandexpressionctxtfx=ifx.pexp_attributes<>[]thenppf"((%a)@,%a)"(expressionctxt){xwithpexp_attributes=[]}(attributesctxt)x.pexp_attributeselsematchx.pexp_descwith|Pexp_function_|Pexp_match_|Pexp_try_|Pexp_sequence_|Pexp_newtype_whenctxt.pipe||ctxt.semi->parentrue(expressionreset_ctxt)fx|(Pexp_ifthenelse_|Pexp_sequence_)whenctxt.ifthenelse->parentrue(expressionreset_ctxt)fx|Pexp_let_|Pexp_letmodule_|Pexp_open_|Pexp_letexception_|Pexp_letop_whenctxt.semi->parentrue(expressionreset_ctxt)fx|Pexp_newtype(lid,e)->ppf"@[<2>fun@;(type@;%s)@;->@;%a@]"lid.txt(expressionctxt)e|Pexp_function(params,c,body)->(match(params,c)with(* Omit [fun] if there are no params. *)|[],None->(* If function cases are a direct body of a function,
the function node should be wrapped in parens so
it doesn't become part of the enclosing function. *)letshould_paren=matchbodywith|Pfunction_cases_->ctxt.functionrhs|Pfunction_body_->falseinletctxt'=ifshould_parenthenreset_ctxtelsectxtinppf"@[<2>%a@]"(parenshould_paren(function_bodyctxt'))body|[],Somec->ppf"@[<2>(%a@;%a)@]"(function_bodyctxt)body(type_constraintctxt)c|_::_,_->ppf"@[<2>fun@;%a@]"(funf()->function_params_then_bodyctxtfparamscbody~delimiter:"->")())|Pexp_match(e,l)->ppf"@[<hv0>@[<hv0>@[<2>match %a@]@ with@]%a@]"(expressionreset_ctxt)e(case_listctxt)l|Pexp_try(e,l)->ppf"@[<0>@[<hv2>try@ %a@]@ @[<0>with%a@]@]"(* "try@;@[<2>%a@]@\nwith@\n%a"*)(expressionreset_ctxt)e(case_listctxt)l|Pexp_let(rf,l,e)->(* pp f "@[<2>let %a%a in@;<1 -2>%a@]"
(*no indentation here, a new line*) *)(* rec_flag rf *)ppf"@[<2>%a in@;<1 -2>%a@]"(bindingsreset_ctxt)(rf,l)(expressionctxt)e|Pexp_apply(e,l)->(ifnot(sugar_exprctxtfx)thenmatchview_fixity_of_expewith|`Infixs->(matchlwith|[((Nolabel,_)asarg1);((Nolabel,_)asarg2)]->(* FIXME associativity label_x_expression_param *)ppf"@[<2>%a@;%s@;%a@]"(label_x_expression_paramreset_ctxt)arg1s(label_x_expression_paramctxt)arg2|_->ppf"@[<2>%a %a@]"(simple_exprctxt)e(list(label_x_expression_paramctxt))l)|`Prefixs->(lets=ifList.mems["~+";"~-";"~+.";"~-."]&&matchlwith(* See #7200: avoid turning (~- 1) into (- 1) which is
parsed as an int literal *)|[(_,{pexp_desc=Pexp_constant_})]->false|_->truethenString.subs1(String.lengths-1)elsesinmatchlwith|[(Nolabel,x)]->ppf"@[<2>%s@;%a@]"s(simple_exprctxt)x|_->ppf"@[<2>%a %a@]"(simple_exprctxt)e(list(label_x_expression_paramctxt))l)|_->ppf"@[<hov2>%a@]"(funf(e,l)->ppf"%a@ %a"(expression2ctxt)e(list(label_x_expression_paramreset_ctxt))l(* reset here only because [function,match,try,sequence]
are lower priority *))(e,l))|Pexp_construct(li,Someeo)whennot(is_simple_construct(view_exprx))->((* Not efficient FIXME*)matchview_exprxwith|`consls->list(simple_exprctxt)fls~sep:"@;::@;"|`normal->ppf"@[<2>%a@;%a@]"longident_locli(simple_exprctxt)eo|_->assertfalse)|Pexp_setfield(e1,li,e2)->ppf"@[<2>%a.%a@ <-@ %a@]"(simple_exprctxt)e1longident_locli(simple_exprctxt)e2|Pexp_ifthenelse(e1,e2,eo)->(* @;@[<2>else@ %a@]@] *)letfmt:(_,_,_)format="@[<hv0>@[<2>if@ %a@]@;@[<2>then@ %a@]%a@]"inletexpression_under_ifthenelse=expression(under_ifthenelsectxt)inppffmtexpression_under_ifthenelsee1expression_under_ifthenelsee2(funfeo->matcheowith|Somex->ppf"@;@[<2>else@;%a@]"(expression(under_semictxt))x|None->()(* pp f "()" *))eo|Pexp_sequence_->letrecsequence_helperacc=function|{pexp_desc=Pexp_sequence(e1,e2);pexp_attributes=[]}->sequence_helper(e1::acc)e2|v->List.rev(v::acc)inletlst=sequence_helper[]xinppf"@[<hv>%a@]"(list(expression(under_semictxt))~sep:";@;")lst|Pexp_newli->ppf"@[<hov2>new@ %a@]"longident_locli|Pexp_setinstvar(s,e)->ppf"@[<hov2>%s@ <-@ %a@]"s.txt(expressionctxt)e|Pexp_overridel->(* FIXME *)letstring_x_expressionf(s,e)=ppf"@[<hov2>%s@ =@ %a@]"s.txt(expressionctxt)einppf"@[<hov2>{<%a>}@]"(liststring_x_expression~sep:";")l|Pexp_letmodule(s,me,e)->ppf"@[<hov2>let@ module@ %s@ =@ %a@ in@ %a@]"(Option.values.txt~default:"_")(module_exprreset_ctxt)me(expressionctxt)e|Pexp_letexception(cd,e)->ppf"@[<hov2>let@ exception@ %a@ in@ %a@]"(extension_constructorctxt)cd(expressionctxt)e|Pexp_asserte->ppf"@[<hov2>assert@ %a@]"(simple_exprctxt)e|Pexp_lazye->ppf"@[<hov2>lazy@ %a@]"(simple_exprctxt)e(* Pexp_poly: impossible but we should print it anyway, rather than
assert false *)|Pexp_poly(e,None)->ppf"@[<hov2>!poly!@ %a@]"(simple_exprctxt)e|Pexp_poly(e,Somect)->ppf"@[<hov2>(!poly!@ %a@ : %a)@]"(simple_exprctxt)e(core_typectxt)ct|Pexp_open(o,e)->ppf"@[<2>let open%s %a in@;%a@]"(overrideo.popen_override)(module_exprctxt)o.popen_expr(expressionctxt)e|Pexp_variant(l,Someeo)->ppf"@[<2>`%s@;%a@]"l(simple_exprctxt)eo|Pexp_letop{let_;ands;body}->ppf"@[<2>@[<v>%a@,%a@] in@;<1 -2>%a@]"(binding_opctxt)let_(list~sep:"@,"(binding_opctxt))ands(expressionctxt)body|Pexp_extensione->extensionctxtfe|Pexp_unreachable->ppf"."|_->expression1ctxtfxandfunction_paramctxtfparam=matchparam.pparam_descwith|Pparam_val(a,b,c)->label_expctxtf(a,b,c)|Pparam_newtypety->ppf"(type %a)@;"protect_identty.txtandfunction_bodyctxtffunction_body=matchfunction_bodywith|Pfunction_bodybody->expressionctxtfbody|Pfunction_cases(cases,_,attrs)->ppf"@[<hv>function%a%a@]"(item_attributesctxt)attrs(case_listctxt)casesandtype_constraintctxtfconstraint_=matchconstraint_with|Pconstraintty->ppf":@;%a"(core_typectxt)ty|Pcoerce(ty1,ty2)->ppf"%a:>@;%a"(option~first:":@;"(core_typectxt))ty1(core_typectxt)ty2andfunction_params_then_bodyctxtfparamsconstraint_body~delimiter=ppf"%a%a%s@;%a"(list(function_paramctxt)~sep:"")params(option(type_constraintctxt))constraint_delimiter(function_body(under_functionrhsctxt))bodyandexpression1ctxtfx=ifx.pexp_attributes<>[]thenexpressionctxtfxelsematchx.pexp_descwith|Pexp_objectcs->ppf"%a"(class_structurectxt)cs|_->expression2ctxtfx(* used in [Pexp_apply] *)andexpression2ctxtfx=ifx.pexp_attributes<>[]thenexpressionctxtfxelsematchx.pexp_descwith|Pexp_field(e,li)->ppf"@[<hov2>%a.%a@]"(simple_exprctxt)elongident_locli|Pexp_send(e,s)->ppf"@[<hov2>%a#%s@]"(simple_exprctxt)es.txt|_->simple_exprctxtfxandsimple_exprctxtfx=ifx.pexp_attributes<>[]thenexpressionctxtfxelsematchx.pexp_descwith|Pexp_construct_whenis_simple_construct(view_exprx)->(matchview_exprxwith|`nil->ppf"[]"|`tuple->ppf"()"|`listxs->ppf"@[<hv0>[%a]@]"(list(expression(under_semictxt))~sep:";@;")xs|`simplex->longidentfx|_->assertfalse)|Pexp_identli->longident_locfli(* (match view_fixity_of_exp x with *)(* |`Normal -> longident_loc f li *)(* | `Prefix _ | `Infix _ -> pp f "( %a )" longident_loc li) *)|Pexp_constantc->constantfc|Pexp_packme->ppf"(module@;%a)"(module_exprctxt)me|Pexp_tuplel->ppf"@[<hov2>(%a)@]"(list(simple_exprctxt)~sep:",@;")l|Pexp_constraint(e,ct)->ppf"(%a : %a)"(expressionctxt)e(core_typectxt)ct|Pexp_coerce(e,cto1,ct)->ppf"(%a%a :> %a)"(expressionctxt)e(option(core_typectxt)~first:" : "~last:" ")cto1(* no sep hint*)(core_typectxt)ct|Pexp_variant(l,None)->ppf"`%s"l|Pexp_record(l,eo)->letlongident_x_expressionf(li,e)=matchewith|{pexp_desc=Pexp_ident{txt;_};pexp_attributes=[];_}whenli.txt=txt->ppf"@[<hov2>%a@]"longident_locli|_->ppf"@[<hov2>%a@;=@;%a@]"longident_locli(simple_exprctxt)einppf"@[<hv0>@[<hv2>{@;%a%a@]@;}@]"(* "@[<hov2>{%a%a}@]" *)(option~last:" with@;"(simple_exprctxt))eo(listlongident_x_expression~sep:";@;")l|Pexp_arrayl->ppf"@[<0>@[<2>[|%a|]@]@]"(list(simple_expr(under_semictxt))~sep:";")l|Pexp_while(e1,e2)->letfmt:(_,_,_)format="@[<2>while@;%a@;do@;%a@;done@]"inppffmt(expressionctxt)e1(expressionctxt)e2|Pexp_for(s,e1,e2,df,e3)->letfmt:(_,_,_)format="@[<hv0>@[<hv2>@[<2>for %a =@;%a@;%a%a@;do@]@;%a@]@;done@]"inletexpression=expressionctxtinppffmt(patternctxt)sexpressione1direction_flagdfexpressione2expressione3|_->parentrue(expressionctxt)fxandattributesctxtfl=List.iter(attributectxtf)landitem_attributesctxtfl=List.iter(item_attributectxtf)landattributectxtfa=ppf"@[<2>[@@%s@ %a]@]"a.attr_name.txt(payloadctxt)a.attr_payloadanditem_attributectxtfa=ppf"@[<2>[@@@@%s@ %a]@]"a.attr_name.txt(payloadctxt)a.attr_payloadandfloating_attributectxtfa=ppf"@[<2>[@@@@@@%s@ %a]@]"a.attr_name.txt(payloadctxt)a.attr_payloadandvalue_descriptionctxtfx=(* note: value_description has an attribute field,
but they're already printed by the callers this method *)ppf"@[<hov2>%a%a@]"(core_typectxt)x.pval_type(funfx->ifx.pval_prim<>[]thenppf"@ =@ %a"(listconstant_string)x.pval_prim)xandextensionctxtf(s,e)=ppf"@[<2>[%%%s@ %a]@]"s.txt(payloadctxt)eanditem_extensionctxtf(s,e)=ppf"@[<2>[%%%%%s@ %a]@]"s.txt(payloadctxt)eandexception_declarationctxtfx=ppf"@[<hov2>exception@ %a@]%a"(extension_constructorctxt)x.ptyexn_constructor(item_attributesctxt)x.ptyexn_attributesandclass_type_fieldctxtfx=matchx.pctf_descwith|Pctf_inheritct->ppf"@[<2>inherit@ %a@]%a"(class_typectxt)ct(item_attributesctxt)x.pctf_attributes|Pctf_val(s,mf,vf,ct)->ppf"@[<2>val @ %a%a%s@ :@ %a@]%a"mutable_flagmfvirtual_flagvfs.txt(core_typectxt)ct(item_attributesctxt)x.pctf_attributes|Pctf_method(s,pf,vf,ct)->ppf"@[<2>method %a %a%s :@;%a@]%a"private_flagpfvirtual_flagvfs.txt(core_typectxt)ct(item_attributesctxt)x.pctf_attributes|Pctf_constraint(ct1,ct2)->ppf"@[<2>constraint@ %a@ =@ %a@]%a"(core_typectxt)ct1(core_typectxt)ct2(item_attributesctxt)x.pctf_attributes|Pctf_attributea->floating_attributectxtfa|Pctf_extensione->item_extensionctxtfe;item_attributesctxtfx.pctf_attributesandclass_signaturectxtf{pcsig_self=ct;pcsig_fields=l;_}=ppf"@[<hv0>@[<hv2>object@[<1>%a@]@ %a@]@ end@]"(funf->function|{ptyp_desc=Ptyp_any;ptyp_attributes=[];_}->()|ct->ppf" (%a)"(core_typectxt)ct)ct(list(class_type_fieldctxt)~sep:"@;")l(* call [class_signature] called by [class_signature] *)andclass_typectxtfx=matchx.pcty_descwith|Pcty_signaturecs->class_signaturectxtfcs;attributesctxtfx.pcty_attributes|Pcty_constr(li,l)->ppf"%a%a%a"(funfl->matchlwith|[]->()|_->ppf"[%a]@ "(list(core_typectxt)~sep:",")l)llongident_locli(attributesctxt)x.pcty_attributes|Pcty_arrow(l,co,cl)->ppf"@[<2>%a@;->@;%a@]"(* FIXME remove parens later *)(type_with_labelctxt)(l,co)(class_typectxt)cl|Pcty_extensione->extensionctxtfe;attributesctxtfx.pcty_attributes|Pcty_open(o,e)->ppf"@[<2>let open%s %a in@;%a@]"(overrideo.popen_override)longident_loco.popen_expr(class_typectxt)e(* [class type a = object end] *)andclass_type_declaration_listctxtfl=letclass_type_declarationkwdfx=let{pci_params=ls;pci_name={txt;_};_}=xinppf"@[<2>%s %a%a%s@ =@ %a@]%a"kwdvirtual_flagx.pci_virt(class_params_defctxt)lstxt(class_typectxt)x.pci_expr(item_attributesctxt)x.pci_attributesinmatchlwith|[]->()|[x]->class_type_declaration"class type"fx|x::xs->ppf"@[<v>%a@,%a@]"(class_type_declaration"class type")x(list~sep:"@,"(class_type_declaration"and"))xsandclass_fieldctxtfx=matchx.pcf_descwith|Pcf_inherit(ovf,ce,so)->ppf"@[<2>inherit@ %s@ %a%a@]%a"(overrideovf)(class_exprctxt)ce(funfso->matchsowithNone->()|Somes->ppf"@ as %s"s.txt)so(item_attributesctxt)x.pcf_attributes|Pcf_val(s,mf,Cfk_concrete(ovf,e))->ppf"@[<2>val%s %a%s =@;%a@]%a"(overrideovf)mutable_flagmfs.txt(expressionctxt)e(item_attributesctxt)x.pcf_attributes|Pcf_method(s,pf,Cfk_virtualct)->ppf"@[<2>method virtual %a %s :@;%a@]%a"private_flagpfs.txt(core_typectxt)ct(item_attributesctxt)x.pcf_attributes|Pcf_val(s,mf,Cfk_virtualct)->ppf"@[<2>val virtual %a%s :@ %a@]%a"mutable_flagmfs.txt(core_typectxt)ct(item_attributesctxt)x.pcf_attributes|Pcf_method(s,pf,Cfk_concrete(ovf,e))->letbinde=bindingctxtf{pvb_pat={ppat_desc=Ppat_vars;ppat_loc=Location.none;ppat_loc_stack=[];ppat_attributes=[];};pvb_expr=e;pvb_attributes=[];pvb_loc=Location.none;pvb_constraint=None;}inppf"@[<2>method%s %a%a@]%a"(overrideovf)private_flagpf(funf->function|{pexp_desc=Pexp_poly(e,Somect);pexp_attributes=[];_}->ppf"%s :@;%a=@;%a"s.txt(core_typectxt)ct(expressionctxt)e|{pexp_desc=Pexp_poly(e,None);pexp_attributes=[];_}->binde|_->binde)e(item_attributesctxt)x.pcf_attributes|Pcf_constraint(ct1,ct2)->ppf"@[<2>constraint %a =@;%a@]%a"(core_typectxt)ct1(core_typectxt)ct2(item_attributesctxt)x.pcf_attributes|Pcf_initializere->ppf"@[<2>initializer@ %a@]%a"(expressionctxt)e(item_attributesctxt)x.pcf_attributes|Pcf_attributea->floating_attributectxtfa|Pcf_extensione->item_extensionctxtfe;item_attributesctxtfx.pcf_attributesandclass_structurectxtf{pcstr_self=p;pcstr_fields=l}=ppf"@[<hv0>@[<hv2>object%a@;%a@]@;end@]"(funfp->matchp.ppat_descwith|Ppat_any->()|Ppat_constraint_->ppf" %a"(patternctxt)p|_->ppf" (%a)"(patternctxt)p)p(list(class_fieldctxt))landclass_exprctxtfx=ifx.pcl_attributes<>[]thenppf"((%a)%a)"(class_exprctxt){xwithpcl_attributes=[]}(attributesctxt)x.pcl_attributeselsematchx.pcl_descwith|Pcl_structurecs->class_structurectxtfcs|Pcl_fun(l,eo,p,e)->ppf"fun@ %a@ ->@ %a"(label_expctxt)(l,eo,p)(class_exprctxt)e|Pcl_let(rf,l,ce)->ppf"%a@ in@ %a"(bindingsctxt)(rf,l)(class_exprctxt)ce|Pcl_apply(ce,l)->ppf"((%a)@ %a)"(* Cf: #7200 *)(class_exprctxt)ce(list(label_x_expression_paramctxt))l|Pcl_constr(li,l)->ppf"%a%a"(funfl->ifl<>[]thenppf"[%a]@ "(list(core_typectxt)~sep:",")l)llongident_locli|Pcl_constraint(ce,ct)->ppf"(%a@ :@ %a)"(class_exprctxt)ce(class_typectxt)ct|Pcl_extensione->extensionctxtfe|Pcl_open(o,e)->ppf"@[<2>let open%s %a in@;%a@]"(overrideo.popen_override)longident_loco.popen_expr(class_exprctxt)eandmodule_typectxtfx=ifx.pmty_attributes<>[]thenppf"((%a)%a)"(module_typectxt){xwithpmty_attributes=[]}(attributesctxt)x.pmty_attributeselsematchx.pmty_descwith|Pmty_functor(Unit,mt2)->ppf"@[<hov2>functor () ->@ %a@]"(module_typectxt)mt2|Pmty_functor(Named(s,mt1),mt2)->(matchs.txtwith|None->ppf"@[<hov2>%a@ ->@ %a@]"(module_type1ctxt)mt1(module_typectxt)mt2|Somename->ppf"@[<hov2>functor@ (%s@ :@ %a)@ ->@ %a@]"name(module_typectxt)mt1(module_typectxt)mt2)|Pmty_with(mt,[])->module_typectxtfmt|Pmty_with(mt,l)->ppf"@[<hov2>%a@ with@ %a@]"(module_type1ctxt)mt(list(with_constraintctxt)~sep:"@ and@ ")l|_->module_type1ctxtfxandwith_constraintctxtf=function|Pwith_type(li,({ptype_params=ls;_}astd))->letls=List.mapfstlsinppf"type@ %a %a =@ %a"(list(core_typectxt)~sep:","~first:"("~last:")")lslongident_locli(type_declarationctxt)td|Pwith_module(li,li2)->ppf"module %a =@ %a"longident_loclilongident_locli2|Pwith_modtype(li,mty)->ppf"module type %a =@ %a"longident_locli(module_typectxt)mty|Pwith_typesubst(li,({ptype_params=ls;_}astd))->letls=List.mapfstlsinppf"type@ %a %a :=@ %a"(list(core_typectxt)~sep:","~first:"("~last:")")lslongident_locli(type_declarationctxt)td|Pwith_modsubst(li,li2)->ppf"module %a :=@ %a"longident_loclilongident_locli2|Pwith_modtypesubst(li,mty)->ppf"module type %a :=@ %a"longident_locli(module_typectxt)mtyandmodule_type1ctxtfx=ifx.pmty_attributes<>[]thenmodule_typectxtfxelsematchx.pmty_descwith|Pmty_identli->ppf"%a"longident_locli|Pmty_aliasli->ppf"(module %a)"longident_locli|Pmty_signatures->ppf"@[<hv0>@[<hv2>sig@ %a@]@ end@]"(* "@[<hov>sig@ %a@ end@]" *)(list(signature_itemctxt))s(* FIXME wrong indentation*)|Pmty_typeofme->ppf"@[<hov2>module@ type@ of@ %a@]"(module_exprctxt)me|Pmty_extensione->extensionctxtfe|_->parentrue(module_typectxt)fxandsignaturectxtfx=list~sep:"@\n"(signature_itemctxt)fxandsignature_itemctxtfx:unit=matchx.psig_descwith|Psig_type(rf,l)->type_def_listctxtf(rf,true,l)|Psig_typesubstl->(* Psig_typesubst is never recursive, but we specify [Recursive] here to
avoid printing a [nonrec] flag, which would be rejected by the parser.
*)type_def_listctxtf(Recursive,false,l)|Psig_valuevd->letintro=ifvd.pval_prim=[]then"val"else"external"inppf"@[<2>%s@ %a@ :@ %a@]%a"introprotect_identvd.pval_name.txt(value_descriptionctxt)vd(item_attributesctxt)vd.pval_attributes|Psig_typextte->type_extensionctxtfte|Psig_exceptioned->exception_declarationctxtfed|Psig_classl->(letclass_descriptionkwdf({pci_params=ls;pci_name={txt;_};_}asx)=ppf"@[<2>%s %a%a%s@;:@;%a@]%a"kwdvirtual_flagx.pci_virt(class_params_defctxt)lstxt(class_typectxt)x.pci_expr(item_attributesctxt)x.pci_attributesinmatchlwith|[]->()|[x]->class_description"class"fx|x::xs->ppf"@[<v>%a@,%a@]"(class_description"class")x(list~sep:"@,"(class_description"and"))xs)|Psig_module({pmd_type={pmty_desc=Pmty_aliasalias;pmty_attributes=[];_};_;}aspmd)->ppf"@[<hov>module@ %s@ =@ %a@]%a"(Option.valuepmd.pmd_name.txt~default:"_")longident_localias(item_attributesctxt)pmd.pmd_attributes|Psig_modulepmd->ppf"@[<hov>module@ %s@ :@ %a@]%a"(Option.valuepmd.pmd_name.txt~default:"_")(module_typectxt)pmd.pmd_type(item_attributesctxt)pmd.pmd_attributes|Psig_modsubstpms->ppf"@[<hov>module@ %s@ :=@ %a@]%a"pms.pms_name.txtlongident_locpms.pms_manifest(item_attributesctxt)pms.pms_attributes|Psig_openod->ppf"@[<hov2>open%s@ %a@]%a"(overrideod.popen_override)longident_locod.popen_expr(item_attributesctxt)od.popen_attributes|Psig_includeincl->ppf"@[<hov2>include@ %a@]%a"(module_typectxt)incl.pincl_mod(item_attributesctxt)incl.pincl_attributes|Psig_modtype{pmtd_name=s;pmtd_type=md;pmtd_attributes=attrs}->ppf"@[<hov2>module@ type@ %s%a@]%a"s.txt(funfmd->matchmdwith|None->()|Somemt->pp_print_spacef();ppf"@ =@ %a"(module_typectxt)mt)md(item_attributesctxt)attrs|Psig_modtypesubst{pmtd_name=s;pmtd_type=md;pmtd_attributes=attrs}->letmd=matchmdwithNone->assertfalse(* ast invariant *)|Somemt->mtinppf"@[<hov2>module@ type@ %s@ :=@ %a@]%a"s.txt(module_typectxt)md(item_attributesctxt)attrs|Psig_class_typel->class_type_declaration_listctxtfl|Psig_recmoduledecls->letrecstring_x_module_type_listf?(first=true)l=matchlwith|[]->()|pmd::tl->ifnotfirstthenppf"@ @[<hov2>and@ %s:@ %a@]%a"(Option.valuepmd.pmd_name.txt~default:"_")(module_type1ctxt)pmd.pmd_type(item_attributesctxt)pmd.pmd_attributeselseppf"@[<hov2>module@ rec@ %s:@ %a@]%a"(Option.valuepmd.pmd_name.txt~default:"_")(module_type1ctxt)pmd.pmd_type(item_attributesctxt)pmd.pmd_attributes;string_x_module_type_listf~first:falsetlinstring_x_module_type_listfdecls|Psig_attributea->floating_attributectxtfa|Psig_extension(e,a)->item_extensionctxtfe;item_attributesctxtfaandmodule_exprctxtfx=ifx.pmod_attributes<>[]thenppf"((%a)%a)"(module_exprctxt){xwithpmod_attributes=[]}(attributesctxt)x.pmod_attributeselsematchx.pmod_descwith|Pmod_structures->ppf"@[<hv2>struct@;@[<0>%a@]@;<1 -2>end@]"(list(structure_itemctxt)~sep:"@\n")s|Pmod_constraint(me,mt)->ppf"@[<hov2>(%a@ :@ %a)@]"(module_exprctxt)me(module_typectxt)mt|Pmod_identli->ppf"%a"longident_locli|Pmod_functor(Unit,me)->ppf"functor ()@;->@;%a"(module_exprctxt)me|Pmod_functor(Named(s,mt),me)->ppf"functor@ (%s@ :@ %a)@;->@;%a"(Option.values.txt~default:"_")(module_typectxt)mt(module_exprctxt)me|Pmod_apply(me1,me2)->ppf"(%a)(%a)"(module_exprctxt)me1(module_exprctxt)me2(* Cf: #7200 *)|Pmod_apply_unitme1->ppf"(%a)()"(module_exprctxt)me1|Pmod_unpacke->ppf"(val@ %a)"(expressionctxt)e|Pmod_extensione->extensionctxtfeandstructurectxtfx=list~sep:"@\n"(structure_itemctxt)fxandpayloadctxtf=function|PStr[{pstr_desc=Pstr_eval(e,attrs)}]->ppf"@[<2>%a@]%a"(expressionctxt)e(item_attributesctxt)attrs|PStrx->structurectxtfx|PTypx->ppf":@ ";core_typectxtfx|PSigx->ppf":@ ";signaturectxtfx|PPat(x,None)->ppf"?@ ";patternctxtfx|PPat(x,Somee)->ppf"?@ ";patternctxtfx;ppf" when ";expressionctxtfe(* transform [f = fun g h -> ..] to [f g h = ... ] could be improved *)andbindingctxtf{pvb_pat=p;pvb_expr=x;_}=(* .pvb_attributes have already been printed by the caller, #bindings *)letrecpp_print_pexp_functionfx=ifx.pexp_attributes<>[]thenppf"=@;%a"(expressionctxt)xelsematchx.pexp_descwith|Pexp_function(params,c,body)->function_params_then_bodyctxtfparamscbody~delimiter:"="|Pexp_newtype(str,e)->ppf"(type@ %s)@ %a"str.txtpp_print_pexp_functione|_->ppf"=@;%a"(expressionctxt)xinlettyvars_strtyvars=List.map(funv->v.txt)tyvarsinletis_desugared_gadtpe=letgadt_pattern=matchpwith|{ppat_desc=Ppat_constraint(({ppat_desc=Ppat_var_}aspat),{ptyp_desc=Ptyp_poly(args_tyvars,rt)});ppat_attributes=[];}->Some(pat,args_tyvars,rt)|_->Noneinletrecgadt_exptyvarse=matchewith|{pexp_desc=Pexp_newtype(tyvar,e);pexp_attributes=[]}->gadt_exp(tyvar::tyvars)e|{pexp_desc=Pexp_constraint(e,ct);pexp_attributes=[]}->Some(List.revtyvars,e,ct)|_->Noneinletgadt_exp=gadt_exp[]einmatch(gadt_pattern,gadt_exp)with|Some(p,pt_tyvars,pt_ct),Some(e_tyvars,e,e_ct)whentyvars_strpt_tyvars=tyvars_stre_tyvars->letety=varify_type_constructorse_tyvarse_ctinifety=pt_ctthenSome(p,pt_tyvars,e_ct,e)elseNone|_->Noneinifx.pexp_attributes<>[]thenmatchpwith|{ppat_desc=Ppat_constraint(({ppat_desc=Ppat_var_;_}aspat),({ptyp_desc=Ptyp_poly_;_}astyp));ppat_attributes=[];_;}->ppf"%a@;: %a@;=@;%a"(simple_patternctxt)pat(core_typectxt)typ(expressionctxt)x|_->ppf"%a@;=@;%a"(patternctxt)p(expressionctxt)xelsematchis_desugared_gadtpxwith|Some(p,[],ct,e)->ppf"%a@;: %a@;=@;%a"(simple_patternctxt)p(core_typectxt)ct(expressionctxt)e|Some(p,tyvars,ct,e)->ppf"%a@;: type@;%a.@;%a@;=@;%a"(simple_patternctxt)p(listpp_print_string~sep:"@;")(tyvars_strtyvars)(core_typectxt)ct(expressionctxt)e|None->(matchpwith|{ppat_desc=Ppat_constraint(p,ty);ppat_attributes=[]}->((* special case for the first*)matchtywith|{ptyp_desc=Ptyp_poly_;ptyp_attributes=[]}->ppf"%a@;:@;%a@;=@;%a"(simple_patternctxt)p(core_typectxt)ty(expressionctxt)x|_->ppf"(%a@;:@;%a)@;=@;%a"(simple_patternctxt)p(core_typectxt)ty(expressionctxt)x)|{ppat_desc=Ppat_var_;ppat_attributes=[]}->ppf"%a@ %a"(simple_patternctxt)ppp_print_pexp_functionx|_->ppf"%a@;=@;%a"(patternctxt)p(expressionctxt)x)(* [in] is not printed *)andbindingsctxtf(rf,l)=letbindingkwdrffx=ppf"@[<2>%s %a%a@]%a"kwdrec_flagrf(bindingctxt)x(item_attributesctxt)x.pvb_attributesinmatchlwith|[]->()|[x]->binding"let"rffx|x::xs->ppf"@[<v>%a@,%a@]"(binding"let"rf)x(list~sep:"@,"(binding"and"Nonrecursive))xsandbinding_opctxtfx=match(x.pbop_pat,x.pbop_exp)with|({ppat_desc=Ppat_var{txt=pvar;_};ppat_attributes=[];_},{pexp_desc=Pexp_ident{txt=Lidentevar;_};pexp_attributes=[];_;})whenpvar=evar->ppf"@[<2>%s %s@]"x.pbop_op.txtevar|pat,exp->ppf"@[<2>%s %a@;=@;%a@]"x.pbop_op.txt(patternctxt)pat(expressionctxt)expandstructure_itemctxtfx=matchx.pstr_descwith|Pstr_eval(e,attrs)->ppf"@[<hov2>;;%a@]%a"(expressionctxt)e(item_attributesctxt)attrs|Pstr_type(_,[])->assertfalse|Pstr_type(rf,l)->type_def_listctxtf(rf,true,l)|Pstr_value(rf,l)->(* pp f "@[<hov2>let %a%a@]" rec_flag rf bindings l *)ppf"@[<2>%a@]"(bindingsctxt)(rf,l)|Pstr_typextte->type_extensionctxtfte|Pstr_exceptioned->exception_declarationctxtfed|Pstr_modulex->letrecmodule_helper=function|{pmod_desc=Pmod_functor(arg_opt,me');pmod_attributes=[]}->(matcharg_optwith|Unit->ppf"()"|Named(s,mt)->ppf"(%s:%a)"(Option.values.txt~default:"_")(module_typectxt)mt);module_helperme'|me->meinppf"@[<hov2>module %s%a@]%a"(Option.valuex.pmb_name.txt~default:"_")(funfme->letme=module_helpermeinmatchmewith|{pmod_desc=Pmod_constraint(me',({pmty_desc=Pmty_ident_|Pmty_signature_;_}asmt));pmod_attributes=[];}->ppf" :@;%a@;=@;%a@;"(module_typectxt)mt(module_exprctxt)me'|_->ppf" =@ %a"(module_exprctxt)me)x.pmb_expr(item_attributesctxt)x.pmb_attributes|Pstr_openod->ppf"@[<2>open%s@;%a@]%a"(overrideod.popen_override)(module_exprctxt)od.popen_expr(item_attributesctxt)od.popen_attributes|Pstr_modtype{pmtd_name=s;pmtd_type=md;pmtd_attributes=attrs}->ppf"@[<hov2>module@ type@ %s%a@]%a"s.txt(funfmd->matchmdwith|None->()|Somemt->pp_print_spacef();ppf"@ =@ %a"(module_typectxt)mt)md(item_attributesctxt)attrs|Pstr_classl->(letextract_class_argscl=letrecloopacc=function|{pcl_desc=Pcl_fun(l,eo,p,cl');pcl_attributes=[]}->loop((l,eo,p)::acc)cl'|cl->(List.revacc,cl)inletargs,cl=loop[]clinletconstr,cl=matchclwith|{pcl_desc=Pcl_constraint(cl',ct);pcl_attributes=[]}->(Somect,cl')|_->(None,cl)in(args,constr,cl)inletclass_constraintfct=ppf": @[%a@] "(class_typectxt)ctinletclass_declarationkwdf({pci_params=ls;pci_name={txt;_};_}asx)=letargs,constr,cl=extract_class_argsx.pci_exprinppf"@[<2>%s %a%a%s %a%a=@;%a@]%a"kwdvirtual_flagx.pci_virt(class_params_defctxt)lstxt(list(label_expctxt))args(optionclass_constraint)constr(class_exprctxt)cl(item_attributesctxt)x.pci_attributesinmatchlwith|[]->()|[x]->class_declaration"class"fx|x::xs->ppf"@[<v>%a@,%a@]"(class_declaration"class")x(list~sep:"@,"(class_declaration"and"))xs)|Pstr_class_typel->class_type_declaration_listctxtfl|Pstr_primitivevd->ppf"@[<hov2>external@ %a@ :@ %a@]%a"protect_identvd.pval_name.txt(value_descriptionctxt)vd(item_attributesctxt)vd.pval_attributes|Pstr_includeincl->ppf"@[<hov2>include@ %a@]%a"(module_exprctxt)incl.pincl_mod(item_attributesctxt)incl.pincl_attributes|Pstr_recmoduledecls->((* 3.07 *)letauxf=function|{pmb_expr={pmod_desc=Pmod_constraint(expr,typ)}}aspmb->ppf"@[<hov2>@ and@ %s:%a@ =@ %a@]%a"(Option.valuepmb.pmb_name.txt~default:"_")(module_typectxt)typ(module_exprctxt)expr(item_attributesctxt)pmb.pmb_attributes|pmb->ppf"@[<hov2>@ and@ %s@ =@ %a@]%a"(Option.valuepmb.pmb_name.txt~default:"_")(module_exprctxt)pmb.pmb_expr(item_attributesctxt)pmb.pmb_attributesinmatchdeclswith|({pmb_expr={pmod_desc=Pmod_constraint(expr,typ)}}aspmb)::l2->ppf"@[<hv>@[<hov2>module@ rec@ %s:%a@ =@ %a@]%a@ %a@]"(Option.valuepmb.pmb_name.txt~default:"_")(module_typectxt)typ(module_exprctxt)expr(item_attributesctxt)pmb.pmb_attributes(funfl2->List.iter(auxf)l2)l2|pmb::l2->ppf"@[<hv>@[<hov2>module@ rec@ %s@ =@ %a@]%a@ %a@]"(Option.valuepmb.pmb_name.txt~default:"_")(module_exprctxt)pmb.pmb_expr(item_attributesctxt)pmb.pmb_attributes(funfl2->List.iter(auxf)l2)l2|_->assertfalse)|Pstr_attributea->floating_attributectxtfa|Pstr_extension(e,a)->item_extensionctxtfe;item_attributesctxtfaandtype_paramctxtf(ct,(a,b))=ppf"%s%s%a"(type_variancea)(type_injectivityb)(core_typectxt)ctandtype_paramsctxtf=function|[]->()|l->ppf"%a "(list(type_paramctxt)~first:"("~last:")"~sep:",@;")landtype_def_listctxtf(rf,exported,l)=lettype_declkwdrffx=leteq=ifx.ptype_kind=Ptype_abstract&&x.ptype_manifest=Nonethen""elseifexportedthen" ="else" :="inppf"@[<2>%s %a%a%s%s%a@]%a"kwdnonrec_flagrf(type_paramsctxt)x.ptype_paramsx.ptype_name.txteq(type_declarationctxt)x(item_attributesctxt)x.ptype_attributesinmatchlwith|[]->assertfalse|[x]->type_decl"type"rffx|x::xs->ppf"@[<v>%a@,%a@]"(type_decl"type"rf)x(list~sep:"@,"(type_decl"and"Recursive))xsandrecord_declarationctxtflbls=lettype_record_fieldfpld=ppf"@[<2>%a%s:@;%a@;%a@]"mutable_flagpld.pld_mutablepld.pld_name.txt(core_typectxt)pld.pld_type(attributesctxt)pld.pld_attributesinppf"{@\n%a}"(listtype_record_field~sep:";@\n")lblsandtype_declarationctxtfx=(* type_declaration has an attribute field,
but it's been printed by the caller of this method *)letprivf=matchx.ptype_privatewithPublic->()|Private->ppf"@;private"inletmanifestf=matchx.ptype_manifestwith|None->()|Somey->ifx.ptype_kind=Ptype_abstractthenppf"%t@;%a"priv(core_typectxt)yelseppf"@;%a"(core_typectxt)yinletconstructor_declarationfpcd=ppf"|@;";constructor_declarationctxtf(pcd.pcd_name.txt,pcd.pcd_vars,pcd.pcd_args,pcd.pcd_res,pcd.pcd_attributes)inletreprf=letintrof=ifx.ptype_manifest=Nonethen()elseppf"@;="inmatchx.ptype_kindwith|Ptype_variantxs->letvariantsfmtxs=ifxs=[]thenppfmt" |"elseppfmt"@\n%a"(list~sep:"@\n"constructor_declaration)xsinppf"%t%t%a"introprivvariantsxs|Ptype_abstract->()|Ptype_recordl->ppf"%t%t@;%a"intropriv(record_declarationctxt)l|Ptype_open->ppf"%t%t@;.."introprivinletconstraintsf=List.iter(fun(ct1,ct2,_)->ppf"@[<hov2>@ constraint@ %a@ =@ %a@]"(core_typectxt)ct1(core_typectxt)ct2)x.ptype_cstrsinppf"%t%t%t"manifestreprconstraintsandtype_extensionctxtfx=letextension_constructorfx=ppf"@\n|@;%a"(extension_constructorctxt)xinppf"@[<2>type %a%a += %a@ %a@]%a"(funf->function|[]->()|l->ppf"%a@;"(list(type_paramctxt)~first:"("~last:")"~sep:",")l)x.ptyext_paramslongident_locx.ptyext_pathprivate_flagx.ptyext_private(* Cf: #7200 *)(list~sep:""extension_constructor)x.ptyext_constructors(item_attributesctxt)x.ptyext_attributesandconstructor_declarationctxtf(name,vars,args,res,attrs)=letname=matchnamewith"::"->"(::)"|s->sinletpp_varsfvs=matchvswith|[]->()|vs->ppf"%a@;.@;"(listtyvar_loc~sep:"@;")vsinmatchreswith|None->ppf"%s%a@;%a"name(funf->function|Pcstr_tuple[]->()|Pcstr_tuplel->ppf"@;of@;%a"(list(core_type1ctxt)~sep:"@;*@;")l|Pcstr_recordl->ppf"@;of@;%a"(record_declarationctxt)l)args(attributesctxt)attrs|Somer->ppf"%s:@;%a%a@;%a"namepp_varsvars(funf->function|Pcstr_tuple[]->core_type1ctxtfr|Pcstr_tuplel->ppf"%a@;->@;%a"(list(core_type1ctxt)~sep:"@;*@;")l(core_type1ctxt)r|Pcstr_recordl->ppf"%a@;->@;%a"(record_declarationctxt)l(core_type1ctxt)r)args(attributesctxt)attrsandextension_constructorctxtfx=(* Cf: #7200 *)matchx.pext_kindwith|Pext_decl(v,l,r)->constructor_declarationctxtf(x.pext_name.txt,v,l,r,x.pext_attributes)|Pext_rebindli->ppf"%s@;=@;%a%a"x.pext_name.txtlongident_locli(attributesctxt)x.pext_attributesandcase_listctxtfl:unit=letauxf{pc_lhs;pc_guard;pc_rhs}=ppf"@;| @[<2>%a%a@;->@;%a@]"(patternctxt)pc_lhs(option(expressionctxt)~first:"@;when@;")pc_guard(expression(under_pipectxt))pc_rhsinlistauxfl~sep:""andlabel_x_expression_paramctxtf(l,e)=letsimple_name=matchewith|{pexp_desc=Pexp_ident{txt=Lidentl;_};pexp_attributes=[]}->Somel|_->Noneinmatchlwith|Nolabel->expression2ctxtfe(* level 2*)|Optionalstr->ifSomestr=simple_namethenppf"?%s"strelseppf"?%s:%a"str(simple_exprctxt)e|Labelledlbl->ifSomelbl=simple_namethenppf"~%s"lblelseppf"~%s:%a"lbl(simple_exprctxt)eanddirective_argumentfx=matchx.pdira_descwith|Pdir_strings->ppf"@ %S"s|Pdir_int(n,None)->ppf"@ %s"n|Pdir_int(n,Somem)->ppf"@ %s%c"nm|Pdir_identli->ppf"@ %a"longidentli|Pdir_boolb->ppf"@ %s"(string_of_boolb)lettoplevel_phrasefx=matchxwith|Ptop_defs->ppf"@[<hov0>%a@]"(list(structure_itemreset_ctxt))s(* pp_open_hvbox f 0; *)(* pp_print_list structure_item f s ; *)(* pp_close_box f (); *)|Ptop_dir{pdir_name;pdir_arg=None;_}->ppf"@[<hov2>#%s@]"pdir_name.txt|Ptop_dir{pdir_name;pdir_arg=Somepdir_arg;_}->ppf"@[<hov2>#%s@ %a@]"pdir_name.txtdirective_argumentpdir_argletexpressionfx=ppf"@[%a@]"(expressionreset_ctxt)xletstring_of_expressionx=ignore(flush_str_formatter());letf=str_formatterinexpressionfx;flush_str_formatter()letstring_of_structurex=ignore(flush_str_formatter());letf=str_formatterinstructurereset_ctxtfx;flush_str_formatter()lettop_phrasefx=pp_print_newlinef();toplevel_phrasefx;ppf";;";pp_print_newlinef()letcore_type=core_typereset_ctxtletpattern=patternreset_ctxtletsignature=signaturereset_ctxtletstructure=structurereset_ctxtletclass_expr=class_exprreset_ctxtletclass_field=class_fieldreset_ctxtletclass_type=class_typereset_ctxtletclass_signature=class_signaturereset_ctxtletclass_type_field=class_type_fieldreset_ctxtletmodule_expr=module_exprreset_ctxtletmodule_type=module_typereset_ctxtletsignature_item=signature_itemreset_ctxtletstructure_item=structure_itemreset_ctxtlettype_declaration=type_declarationreset_ctxtletbinding=bindingreset_ctxtletpayload=payloadreset_ctxt