123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165openPpxlibmoduleSyntaxes=structlet(let@)=(@@)endmoduleLocCtx=structopenAst_builder.Defaulttype_Effect.t+=Get_loc:locationEffect.tletwith_loc(loc:location)f=letopenEffect.DeepintryflocwitheffectGet_loc,k->continueklocletget_loc()=Effect.performGet_locletwlocx={loc=get_loc();txt=x}(* Override anything we need *)letconstructor_declaration~name~args=constructor_declaration~loc:(get_loc())~name:(wlocname)~argsletestringx=estring~loc:(get_loc())xleteunit()=eunit~loc:(get_loc())letevarx=evar~loc:(get_loc())xletpexp_applyxy=pexp_apply~loc:(get_loc())xyletpexp_constructxy=pexp_construct~loc:(get_loc())xyletpexp_fieldxy=pexp_field~loc:(get_loc())xyletpexp_identx=pexp_ident~loc:(get_loc())xletpexp_matchxy=pexp_match~loc:(get_loc())xyletpexp_recordxy=pexp_record~loc:(get_loc())xyletpexp_tuplex=pexp_tuple~loc:(get_loc())xletpexp_unreachable()=pexp_unreachable~loc:(get_loc())letpmod_identx=pmod_ident~loc:(get_loc())xletppat_any()=ppat_any~loc:(get_loc())letppat_constructxy=ppat_construct~loc:(get_loc())xyletppat_recordxy=ppat_record~loc:(get_loc())xyletppat_tuplepats=matchpatswith|[]->ppat_any()|[pat]->pat|_->ppat_tuple~loc:(get_loc())patsletppat_varx=ppat_var~loc:(get_loc())xletpstr_typexy=pstr_type~loc:(get_loc())xyletptyp_constrxy=ptyp_constr~loc:(get_loc())xyletpvarx=pvar~loc:(get_loc())xlettype_declaration~name~params~cstrs~kind~private_~manifest=type_declaration~loc:(get_loc())~name:(wlocname)~params~cstrs~kind~private_~manifest(* convenience helpers *)letlidents=wloc(Lidents)letliddotbasename=wloc(Ldot(base,name))letliddotsbasepath=wloc@@List.fold_left(funaccname->Ldot(acc,name))basepathletpexp_ident_dotbasename=pexp_ident(liddotbasename)letpexp_ident_dotsbasename=pexp_ident(liddotsbasename)letptyp_constr_dotsymex_modulepathargs=ptyp_constr(liddotsymex_modulepath)argsendmodulePrinters=structletrecpp_longidentfmt=function|Lidents->Format.pp_print_stringfmts|Ldot(base,name)->Format.fprintffmt"%a.%s"pp_longidentbasename|Lapply(f,arg)->Format.fprintffmt"%a(%a)"pp_longidentfpp_longidentargendmoduleAttributes:sigtype'aparservalmust:string->expressionparservalmay:string->expressionoptionparservalpair:'aparser->'bparser->('a*'b)parserval(**):'aparser->'bparser->('a*'b)parservaldeclare_record:name:string->'aparser->(label_declaration,'a)Attribute.tend=struct(** Given a list of fields, returns their bindings in order and all extra
bindings. *)letfind_expr_fieldsbindingsfields=letrecfind_fieldfieldrest=function|[]->(None,rest)|({txt;_},v)::tlwhentxt=Lidentfield->(Somev,rest@tl)|binding::tl->find_fieldfield(rest@[binding])tlinletrecfind_fieldsaccrest=function|[]->(List.revacc,rest)|field::tl->letfound,rest=find_fieldfield[]restinfind_fields(found::acc)resttlinfind_fields[]bindingsfieldstype'aparser={fields:stringlist;parse:name:string->loc:Location.t->expressionoptionlist->'a*expressionoptionlist;}letmustfield={fields=[field];parse=(fun~name~loc->function|Somev::tl->(v,tl)|None::_->Location.raise_errorf~loc"expects [@%s { %s = <expr>; ... }]"namefield|[]->failwith"Impossible");}letmayfield={fields=[field];parse=(fun~name:_~loc:_->function|v::tl->(v,tl)|[]->failwith"Impossible");}letpairlhsrhs={fields=lhs.fields@rhs.fields;parse=(fun~name~locvalues->letlhs_parsed,values=lhs.parse~name~locvaluesinletrhs_parsed,values=rhs.parse~name~locvaluesin((lhs_parsed,rhs_parsed),values));}let(**)=pairletvalidate_attr_field~nameparser~attr_loc:locbindings=letfields=parser.fieldsinmatchfind_expr_fieldsbindingsfieldswith|found,[]->assert(List.compare_lengthsfoundfields=0);letparsed,remaining=parser.parse~name~locfoundinassert(remaining=[]);parsed|_,extra->Location.raise_errorf~loc"unexpected field(s) '%a' in [@%s], expected one of %s"Fmt.(list~sep:(Fmt.any", ")Printers.pp_longident)(List.map(fun(f,_)->f.txt)extra)name(String.concat"; "fields)letdeclare_record~nameparser=Attribute.declare_with_attr_locnameAttribute.Context.label_declarationAst_pattern.(single_expr_payload(pexp_record__drop))(validate_attr_field~nameparser)end