123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435(* elpi: embedded lambda prolog interpreter *)(* license: GNU Lesser General Public License Version 2.1 or later *)(* ------------------------------------------------------------------------- *)openElpi_utilopenUtilmoduleLoc=LocmoduleFunc=structmoduleSelf=structtypet=stringletcompare=String.compare(* Hash consing *)letfrom_string=leth=Hashtbl.create37inletrecaux=function|"nil"->aux"[]"|"cons"->aux"::"|"&"->aux","(* legacy parser *)|x->tryHashtbl.findhxwithNot_found->Hashtbl.addhxx;xinauxletppfmts=Format.fprintffmt"%s"sletshowx=xletequalxy=x==y||x=y(* Resilient to unmarshaling *)lettruef=from_string"true"letandf=from_string","letorf=from_string";"letimplf=from_string"=>"letimplbangf=from_string"=!=>"letrimplf=from_string":-"letcutf=from_string"!"letpif=from_string"pi"letsigmaf=from_string"sigma"leteqf=from_string"="letisf=from_string"is"letasf=from_string"as"letconsf=from_string"::"letnilf=from_string"[]"letarrowf=from_string"->"letsequentf=from_string"?-"letctypef=from_string"ctype"letpropf=from_string"prop"lettypef=from_string"type"letmainf=from_string"main"letdummyname=from_string"%dummy"letspillf=from_string"%spill"letdeclare_constraintf=from_string"declare_constraint"letfindall_solutionsf=from_string"findall_solutions"letpmf=from_string"pattern_match"endletis_uvar_names=letc=s.[0]in('A'<=c&&c<='Z')includeSelfmoduleMap=Map.Make(Self)moduleSet=Set.Make(Self)endmoduleMode:Modewithtypet=Mode.t=Modetyperaw_attribute=|Ifofstring|Nameofstring|Afterofstring|Beforeofstring|Replaceofstring|Removeofstring|Externalofstringoption|Indexofintlist*stringoption|Functional|Untyped|NoOC[@@derivingshow,ord]moduleTypeExpression=structtype'attributet_=|TConstofFunc.t|TAppofFunc.t*'attributet*'attributetlist|TPredof'attribute*(Mode.t*'attributet)list*bool(* true = variadic *)|TArrof'attributet*'attributetand'at={tit:'at_;tloc:Loc.t}[@@derivingshow,ord]endmoduleTerm=structtypetyp=raw_attributelistTypeExpression.t[@@derivingshow,ord]typet_=|ConstofFunc.t|Appoft*tlist|LamofFunc.t*Loc.t*typoption*t|CDataofCData.t|Quotedofquote|Castoft*typ|Parensoftandt={it:t_;loc:Loc.t}andquote={qloc:Loc.t;data:string;kind:stringoption}[@@derivingshow,ord]exceptionNotInPrologofLoc.t*stringletmkClocx={loc;it=CDatax}letmkLamlocxxloctyt={loc;it=Lam(Func.from_stringx,xloc,ty,t)}letmkNilloc={loc;it=ConstFunc.nilf}letmkParensloct={loc;it=Parenst}letmkQuotedlocpads=letstripnmloc={locwithLoc.source_start=loc.Loc.source_start+n;Loc.source_stop=loc.Loc.source_stop-m;}in(* Printf.eprintf "mkQuoted '%s'\n" s; *)letfind_dataipad=matchs.[i]with(* | '{' -> assert false; find_data (i+1) (pad+1) *)|':'->letlen=String.lengthsinletrecfind_spacei=ifi>=lenthenraise(NotInProlog(loc,"syntax error: bad named quotation: {{"^s^"}}.\nDid you separate the name from the data with a space as in {{:name data}} ?."));matchs.[i]with|' '->i|'\n'->i|_->find_space(i+1)inletspace_after=find_space0in(* Printf.eprintf "mkQuoted space_after '%d'\n" space_after; *)letkind=String.subs1(space_after-1)inletdata=String.subs(space_after+1)(String.lengths-space_after-1)inletqloc=strip(space_after+1+pad)padlocin(* Printf.eprintf "mkQuoted data '%s'\n" data;
Printf.eprintf "mkQuoted kind '%s'\n" kind;
Printf.eprintf "mkQuoted qloc '%s'\n" (Loc.show qloc); *){qloc;data;kind=Somekind}|_->letqloc=strippadpadlocin(* Printf.eprintf "mkQuoted qloc '%s'\n" (Loc.show qloc); *){qloc;data=String.subsi(String.lengths-i-i);kind=None}in{loc;it=Quoted(find_data0pad)}letmkSeq?loc(l:tlist)=letrecaux=function[]->assertfalse|[e]->e|{it=Parensit}::tl->aux(it::tl)|hd::tl->lettl=auxtlin{loc=Loc.mergehd.loctl.loc;it=App({it=ConstFunc.consf;loc=hd.loc},[hd;tl])}inletl=auxlinmatchlocwithNone->l|Someloc->{lwithloc}letmkCastloctty={loc;it=Cast(t,ty)}letrecbest_effort_pp=function|Lam(x,_,_,t)->"x\\"^best_effort_ppt.it|CDatac->CData.showc|Quoted_->"{{ .. }}"|Cast_->"(.. : ..)"|_->".."letmkApploc=function(* FG: for convenience, we accept an empty list of arguments *)|[{it=(App_|Const_|Quoted_)}asc]->c|{it=App(c,l1)}::l2->{loc;it=App(c,l1@l2)}|{it=(Const_|Quoted_)}asc::l2->{loc;it=App(c,l2)}|[]->anomaly~loc"empty application"|x::_->raise(NotInProlog(loc,"syntax error: the head of an application must be a constant or a variable, got: "^best_effort_ppx.it))letmkAppFloc(cloc,c)l=ifl=[]thenanomaly~loc"empty application";ifc=","then{loc;it=App({it=Constc;loc=cloc},List.concat_map(function|{loc;it=Parens{it=App({it=Const","},l)}}->l|{loc;it=App({it=Const","},l)}->l|x->[x])l)}else{loc;it=App({it=Constc;loc=cloc},l)}letlast_warn_impl=ref(Loc.initial"(dummy)")letwarn_impl{it;loc}=matchitwith|App({it=Const"=>"},_)->if!last_warn_impl<>locthenwarn~loc~id:ImplicationPrecedence{|The standard λProlog infix operator for implication => has higher precedence
than conjunction. This means that 'A => B, C' reads '(A => B), C'.
This is a common mistake since it makes A only available to B (and not to C
as many newcomers may expect).
If this is really what you want write '(A => B), C' to silence this warning.
Otherwise write 'A => (B, C)', or use the alternative implication operator ==>.
Infix ==> has lower precedence than conjunction, hence
'A ==> B, C' reads 'A ==> (B, C)' and means the same as 'A => (B, C)'.|};last_warn_impl:=loc|_->()letwarn_impl_conj_precedence=function|App({it=Const","},args)->beginmatchList.revargswith|{it=Const"!"}::args_but_last->()|_::args_but_last->List.iterwarn_implargs_but_last|_->()end|_->()letmkAppFloc(cloc,c)l=lett=mkAppFloc(cloc,c)linwarn_impl_conj_precedencet.it;tletfresh_uv_names=ref(-1);;letmkFreshUVarloc=incrfresh_uv_names;{loc;it=Const(Func.from_string("_"^string_of_int!fresh_uv_names))}letfresh_names=ref(-1);;letmkFreshNameloc=incrfresh_names;{loc;it=Const(Func.from_string("__"^string_of_int!fresh_names))}letmkConlocc={loc;it=Const(Func.from_stringc)}letmkConstlocc={loc;it=Constc}endmoduleClause=structtype('term,'attributes,'spill,'deterministic)t={loc:Loc.t;attributes:'attributes;body:'term;needs_spilling:'spill;}[@@derivingshow,ord]endmoduleChr=structtype'termsequent={eigen:'term;context:'term;conclusion:'term}and('attribute,'term)t={to_match:'termsequentlist;to_remove:'termsequentlist;guard:'termoption;new_goal:'termsequentoption;attributes:'attribute;loc:Loc.t;}[@@derivingshow,ord]endmoduleMacro=structtype('name,'term)t={loc:Loc.t;name:'name;body:'term}[@@derivingshow,ord]endmoduleType=structtype('attribute,'inner_attribute)t={loc:Loc.t;attributes:'attribute;name:Func.t;ty:'inner_attributeTypeExpression.t;}[@@derivingshow,ord]endmoduleTypeAbbreviation=structtype'tyclosedTypeexpression=|LamofFunc.t*Loc.t*'tyclosedTypeexpression|Tyof'ty[@@derivingshow,ord]type('name,'ty)t={name:'name;value:'tyclosedTypeexpression;nparams:int;loc:Loc.t}[@@derivingshow,ord]endmoduleProgram=structtypedecl=(* Blocks *)|BeginofLoc.t|NamespaceofLoc.t*Func.t|ConstraintofLoc.t*Func.tlist*Func.tlist|ShortenofLoc.t*(Func.t*Func.t)list(* prefix suffix *)|EndofLoc.t|AccumulatedofLoc.t*parser_outputlist(* data *)|Clauseof(Term.t,raw_attributelist,unit,unit)Clause.t|Chrof(raw_attributelist,Term.t)Chr.t|Macroof(Func.t,Term.t)Macro.t|Kindof(raw_attributelist,raw_attributelist)Type.tlist|Typeof(raw_attributelist,raw_attributelist)Type.tlist|Predof(raw_attributelist,raw_attributelist)Type.t|TypeAbbreviationof(Func.t,raw_attributelistTypeExpression.t)TypeAbbreviation.t|IgnoredofLoc.tandparser_output={file_name:string;digest:Digest.t;ast:decllist}[@@derivingshow]typet=decllist[@@derivingshow]endmoduleGoal=structtypet=Term.tletppfmtt=Term.ppfmttletshowx=Format.asprintf"%a"ppxendmoduleFmt=Formatletcfloat=CData.(declare{data_name="float";data_pp=(funfx->Fmt.fprintff"%f"x);data_compare=Float.compare;data_hash=Hashtbl.hash;data_hconsed=false;})letcint=CData.(declare{data_name="int";data_pp=(funfx->Fmt.fprintff"%d"x);data_compare=Int.compare;data_hash=Hashtbl.hash;data_hconsed=false;})letcstring=CData.(declare{data_name="string";data_pp=(funfx->Fmt.fprintff"%s"x);data_compare=String.compare;data_hash=Hashtbl.hash;data_hconsed=true;})letcloc=CData.(declare{data_name="loc";data_pp=Util.Loc.pp;data_compare=Stdlib.compare;data_hash=Hashtbl.hash;data_hconsed=false;})moduleStructured=structtypeprovenance=|Core(* baked into the elpi runtime *)|Builtinof{variant:int}(* builtin or host declared *)|FileofLoc.t[@@derivingshow,ord]typeprogram={macros:(Func.t,Term.t)Macro.tlist;kinds:(unit,unit)Type.tlist;types:(symbol_attribute,functionality)Type.tlist;type_abbrevs:(Func.t,functionalityTypeExpression.t)TypeAbbreviation.tlist;body:blocklist;}andcattribute={cid:string;cifexpr:stringoption}and('func,'term)block_constraint={loc:Loc.t;clique:'funclist;ctx_filter:'funclist;rules:(cattribute,'term)Chr.tlist}andblock=|Clausesof(Term.t,attribute,unit,unit)Clause.tlist|NamespaceofFunc.t*program|ShortenofFunc.tshorthandlist*program|Constraintsof(Func.t,Term.t)block_constraint*program|Accumulatedofprogramandattribute={insertion:insertionoption;id:stringoption;ifexpr:stringoption;typecheck:bool;occur_check:bool;}andinsertion=Insertofinsertion_place|Replaceofstring|Removeofstringandinsertion_place=Beforeofstring|Afterofstringandsymbol_attribute={availability:symbol_availability;index:predicate_indexingoption;occur_check_pred:bool;}andpredicate_indexing=|Indexofintlist*tindexoption|MaximizeForFunctionalandsymbol_availability=Elpi|OCamlofprovenanceandtindex=Map|HashMap|DiscriminationTreeand'ashorthand={iloc:Loc.t;full_name:'a;short_name:'a;}andfunctionality=Function|Relationandvariadic=Variadic|NotVariadic[@@derivingshow,ord]end