12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423(* Yoann Padioleau
*
* Copyright (C) 2019 r2c
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation, with the
* special exception on linking described in file license.txt.
*
* 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
* license.txt for more details.
*)openCommon(*****************************************************************************)(* Prelude *)(*****************************************************************************)(*
* This module provides a big functor, GENERIC_VS_GENERIC, which can be used
* to match some AST elements against other AST elements in
* a flexible way.
*
* Most of the boilerplate code was generated by
*
* pfff/meta/gen_code -matcher_gen_all
*
* using OCaml pad-style reflection (see commons/ocaml.ml) on
* h_program-lang/ast_generic.ml.
*
* See pfff/matcher/fuzzy_vs_fuzzy.ml for another approach.
*
* I then hardcoded a few isomorphisms by abusing some existing constructs,
* for instance constants starting with a big $X are considered metavars
* for expression.
*
* C-s "iso" or any comment
*
*)(* A is the pattern, and B the concrete source code. For now
* we both use the same module but they may differ later
* as the expressivity of the pattern language grows.
*
* subtle: use 'b' for to report errors, 'a' is the sgrep pattern and it
* has no file information usually.
*)moduleA=Ast_genericmoduleB=Ast_genericmoduleMV=Metavars_generic(*****************************************************************************)(* Globals *)(*****************************************************************************)(*****************************************************************************)(* Helpers *)(*****************************************************************************)(*****************************************************************************)(* Functor parameter combinators *)(*****************************************************************************)(* This is the interface of the structure that will be passed to the
* functor below.
*)moduletypePARAM=sig(* tin is for 'type in' and tout for 'type out' *)typetintype'xtout(* A matcher is something taking an element A and an element B
* (for GENERIC_VS_GENERIC below, A will be the AST of the pattern and B
* the AST of the program we want to match over), then some environment
* information tin, and it will return something (tout) that will
* encapsulate the possible matched element A and B.
*
* If you just want to do a simple matcher that just returns
* a boolean, then instantiate the PARAM struct with
* type tin = unit (* no environment information *)
* type ('a * 'b) tout = ('a * 'b) option
* and if the toplevel matching returns a None, then you know
* A didn't match B.
*)type('a,'b)matcher='a->'b->tin->('a*'b)tout(* The >>= combinator below allow you to configure the matching process
* anyway you want. Essentially this combinator takes a matcher,
* another matcher, and returns a matcher that combine the 2
* matcher arguments.
*
* In the case of a simple boolean matcher, you just need to write:
*
* let (>>=) m1 m2 = fun tin ->
* match m1 tin with
* | None -> None
* | Some (a,b) ->
* m2 (a, b) tin
*)val(>>=):(tin->('a*'b)tout)->('a*'b->(tin->('c*'d)tout))->(tin->('c*'d)tout)(* the disjunctive combinator *)val(>||>):(tin->'xtout)->(tin->'xtout)->(tin->'xtout)(* The classical monad combinators *)valreturn:('a*'b)->tin->('a*'b)toutvalfail:tin->('a*'b)toutvaltokenf:(A.tok,B.tok)matchervalenvf:(MV.mvarA.wrap,A.any)matcher(* ugly hack for the "A" string metavariables *)valenvf2:(MV.mvarA.wrap,A.any*A.any)matcherend(*****************************************************************************)(* Functor code, "JS vs JS" *)(*****************************************************************************)moduleGENERIC_VS_GENERIC=functor(X:PARAM)->structtype('a,'b)matcher='a->'b->X.tin->('a*'b)X.toutlet(>>=)=X.(>>=)let(>||>)=X.(>||>)letreturn=X.returnletfail()=X.failletfail2s=pr2(spf"JS_VS_JS: TODO for %s"s);X.fail(* ---------------------------------------------------------------------- *)(* stdlib: option, list, ref, either, bool *)(* ---------------------------------------------------------------------- *)let(m_option:('a,'b)matcher->('aoption,'boption)matcher)=funfab->matcha,bwith|None,None->return(None,None)|Somexa,Somexb->fxaxb>>=(fun(xa,xb)->return(Somexa,Somexb))|None,_|Some_,_->fail()let(m_ref:('a,'b)matcher->('aref,'bref)matcher)=funfab->matcha,bwith{contents=xa},{contents=xb}->fxaxb>>=(fun(xa,xb)->return({contents=xa},{contents=xb}))letrecm_listfab=matcha,bwith|[],[]->return([],[])|xa::aas,xb::bbs->fxaxb>>=(fun(xa,xb)->m_listfaasbbs>>=(fun(aas,bbs)->return(xa::aas,xb::bbs)))|[],_|_::_,_->fail()letm_eitherfgab=matcha,bwith|Lefta,Leftb->fab>>=(fun(a,b)->return(Lefta,Leftb))|Righta,Rightb->gab>>=(fun(a,b)->return(Righta,Rightb))|Left_,Right_|Right_,Left_->fail()letm_boolab=ifa=bthenreturn(a,b)elsefail()(* ---------------------------------------------------------------------- *)(* m_string *)(* ---------------------------------------------------------------------- *)letm_stringab=ifa=$=bthenreturn(a,b)elsefail()(* ---------------------------------------------------------------------- *)(* Token *)(* ---------------------------------------------------------------------- *)(* we dont care about position, space/indent/comment isomorphism
* so we could just do 'return (a, b)'
* but we need to propagate transformation at least.
*)letm_infoab=X.tokenfabletm_tokab=m_infoabletm_wrapfab=matcha,bwith((xaa,ainfo),(xbb,binfo))->fxaaxbb>>=(fun(xaa,xbb)->m_infoainfobinfo>>=(fun(ainfo,binfo)->return((xaa,ainfo),(xbb,binfo))))(* ---------------------------------------------------------------------- *)(* Name *)(* ---------------------------------------------------------------------- *)letm_nameab=(* iso on name *)matcha,bwith|(str,tok),bwhenMV.is_metavar_namestr->X.envf(str,tok)(B.Nb)>>=(function|((str,tok),B.N(b))->return((str,tok),b)|_->raiseImpossible)(* general case *)|(a,b)->(m_wrapm_string)abletm_dotted_nameab=matcha,bwith(* TODO: [$X] should match any list *)(a,b)->(m_listm_name)abletm_qualified_nameab=matcha,bwith(a,b)->m_dotted_nameabletm_module_nameab=matcha,bwith|A.FileName(a1),B.FileName(b1)->(m_wrapm_string)a1b1>>=(fun(a1,b1)->return(A.FileName(a1),B.FileName(b1)))|A.DottedName(a1),B.DottedName(b1)->m_dotted_namea1b1>>=(fun(a1,b1)->return(A.DottedName(a1),B.DottedName(b1)))|A.FileName_,_|A.DottedName_,_->fail()letm_resolved_nameab=matcha,bwith|A.Local,B.Local->return(A.Local,B.Local)|A.Param,B.Param->return(A.Param,B.Param)|A.Global(a1),B.Global(b1)->m_qualified_namea1b1>>=(fun(a1,b1)->return(A.Global(a1),B.Global(b1)))|A.NotResolved,B.NotResolved->return(A.NotResolved,B.NotResolved)|A.Macro,B.Macro->return(A.Macro,B.Macro)|A.EnumConstant,B.EnumConstant->return(A.EnumConstant,B.EnumConstant)|A.ImportedModule,B.ImportedModule->return(A.ImportedModule,B.ImportedModule)|A.Local,_|A.Param,_|A.Global_,_|A.NotResolved,_|A.Macro,_|A.EnumConstant,_|A.ImportedModule,_->fail()(* start of recursive need *)(* ------------------------------------------------------------------------- *)(* Expression *)(* ------------------------------------------------------------------------- *)letrecm_exprab=matcha,bwith(* special case, metavars !! *)|A.Id((str,tok),id_info),e2whenMV.is_metavar_namestr->X.envf(str,tok)(B.E(e2))>>=(function|((str,tok),B.E(e2))->return((A.Id((str,tok),id_info)),e2)|_->raiseImpossible)|A.L(a1),B.L(b1)->m_literala1b1>>=(fun(a1,b1)->return(A.L(a1),B.L(b1)))|A.Container(a1,a2),B.Container(b1,b2)->m_container_operatora1b1>>=(fun(a1,b1)->(m_listm_expr)a2b2>>=(fun(a2,b2)->return(A.Container(a1,a2),B.Container(b1,b2))))|A.Tuple(a1),B.Tuple(b1)->(m_listm_expr)a1b1>>=(fun(a1,b1)->return(A.Tuple(a1),B.Tuple(b1)))|A.Record(a1),B.Record(b1)->(m_listm_field)a1b1>>=(fun(a1,b1)->return(A.Record(a1),B.Record(b1)))|A.Constructor(a1,a2),B.Constructor(b1,b2)->m_namea1b1>>=(fun(a1,b1)->(m_listm_expr)a2b2>>=(fun(a2,b2)->return(A.Constructor(a1,a2),B.Constructor(b1,b2))))|A.Lambda(a1,a2),B.Lambda(b1,b2)->m_parametersa1b1>>=(fun(a1,b1)->m_stmta2b2>>=(fun(a2,b2)->return(A.Lambda(a1,a2),B.Lambda(b1,b2))))|A.Nop,B.Nop->return(A.Nop,B.Nop)|A.Id(a1,a2),B.Id(b1,b2)->m_namea1b1>>=(fun(a1,b1)->m_id_infoa2b2>>=(fun(a2,b2)->return(A.Id(a1,a2),B.Id(b1,b2))))|A.IdSpecial(a1),B.IdSpecial(b1)->m_speciala1b1>>=(fun(a1,b1)->return(A.IdSpecial(a1),B.IdSpecial(b1)))|A.Call(a1,a2),B.Call(b1,b2)->m_expra1b1>>=(fun(a1,b1)->m_argumentsa2b2>>=(fun(a2,b2)->return(A.Call(a1,a2),B.Call(b1,b2))))|A.Assign(a1,a2),B.Assign(b1,b2)->m_expra1b1>>=(fun(a1,b1)->m_expra2b2>>=(fun(a2,b2)->return(A.Assign(a1,a2),B.Assign(b1,b2))))|A.AssignOp(a1,a2,a3),B.AssignOp(b1,b2,b3)->m_expra1b1>>=(fun(a1,b1)->m_arithmetic_operatora2b2>>=(fun(a2,b2)->m_expra3b3>>=(fun(a3,b3)->return(A.AssignOp(a1,a2,a3),B.AssignOp(b1,b2,b3)))))|A.LetPattern(a1,a2),B.LetPattern(b1,b2)->m_patterna1b1>>=(fun(a1,b1)->m_expra2b2>>=(fun(a2,b2)->return(A.LetPattern(a1,a2),B.LetPattern(b1,b2))))|A.ObjAccess(a1,a2),B.ObjAccess(b1,b2)->m_expra1b1>>=(fun(a1,b1)->m_namea2b2>>=(fun(a2,b2)->return(A.ObjAccess(a1,a2),B.ObjAccess(b1,b2))))|A.ArrayAccess(a1,a2),B.ArrayAccess(b1,b2)->m_expra1b1>>=(fun(a1,b1)->m_expra2b2>>=(fun(a2,b2)->return(A.ArrayAccess(a1,a2),B.ArrayAccess(b1,b2))))|A.Conditional(a1,a2,a3),B.Conditional(b1,b2,b3)->m_expra1b1>>=(fun(a1,b1)->m_expra2b2>>=(fun(a2,b2)->m_expra3b3>>=(fun(a3,b3)->return(A.Conditional(a1,a2,a3),B.Conditional(b1,b2,b3)))))|A.MatchPattern(a1,a2),B.MatchPattern(b1,b2)->m_expra1b1>>=(fun(a1,b1)->(m_listm_action)a2b2>>=(fun(a2,b2)->return(A.MatchPattern(a1,a2),B.MatchPattern(b1,b2))))|A.Yield(a1),B.Yield(b1)->m_expra1b1>>=(fun(a1,b1)->return(A.Yield(a1),B.Yield(b1)))|A.Await(a1),B.Await(b1)->m_expra1b1>>=(fun(a1,b1)->return(A.Await(a1),B.Await(b1)))|A.Cast(a1,a2),B.Cast(b1,b2)->m_type_a1b1>>=(fun(a1,b1)->m_expra2b2>>=(fun(a2,b2)->return(A.Cast(a1,a2),B.Cast(b1,b2))))|A.Seq(a1),B.Seq(b1)->(m_listm_expr)a1b1>>=(fun(a1,b1)->return(A.Seq(a1),B.Seq(b1)))|A.Ref(a1),B.Ref(b1)->m_expra1b1>>=(fun(a1,b1)->return(A.Ref(a1),B.Ref(b1)))|A.DeRef(a1),B.DeRef(b1)->m_expra1b1>>=(fun(a1,b1)->return(A.DeRef(a1),B.DeRef(b1)))|A.Ellipses(a1),B.Ellipses(b1)->m_toka1b1>>=(fun(a1,b1)->return(A.Ellipses(a1),B.Ellipses(b1)))|A.OtherExpr(a1,a2),B.OtherExpr(b1,b2)->m_other_expr_operatora1b1>>=(fun(a1,b1)->(m_listm_any)a2b2>>=(fun(a2,b2)->return(A.OtherExpr(a1,a2),B.OtherExpr(b1,b2))))|A.L_,_|A.Container_,_|A.Tuple_,_|A.Record_,_|A.Constructor_,_|A.Lambda_,_|A.Nop,_|A.Id_,_|A.IdSpecial_,_|A.Call_,_|A.Assign_,_|A.AssignOp_,_|A.LetPattern_,_|A.ObjAccess_,_|A.ArrayAccess_,_|A.Conditional_,_|A.MatchPattern_,_|A.Yield_,_|A.Await_,_|A.Cast_,_|A.Seq_,_|A.Ref_,_|A.DeRef_,_|A.Ellipses_,_|A.OtherExpr_,_->fail()andm_literalab=matcha,bwith(* iso on string *)|A.String("...",a),B.String(s,b)->m_infoab>>=(fun(a,b)->return(A.String("...",a),B.String(s,b)))(* iso allowing regexp *)|A.String(name,info_name),B.String(sb,info_sb)whenname=~"^=~/\\(.*\\)/$"->lets=Common.matched1namein(* TODO
let rex = Pcre.regexp s in
if Pcre.pmatch ~rex sb
*)ifsb=~sthenm_infoinfo_nameinfo_sb>>=(fun(info_name,info_sb)->return(A.String(name,info_name),B.String(sb,info_sb)))elsefail()|A.String(a1),B.String(b1)->(m_wrapm_string)a1b1>>=(fun(a1,b1)->return(A.String(a1),B.String(b1)))|A.Unit(a1),B.Unit(b1)->m_toka1b1>>=(fun(a1,b1)->return(A.Unit(a1),B.Unit(b1)))|A.Bool(a1),B.Bool(b1)->(m_wrapm_bool)a1b1>>=(fun(a1,b1)->return(A.Bool(a1),B.Bool(b1)))|A.Int(a1),B.Int(b1)->(m_wrapm_string)a1b1>>=(fun(a1,b1)->return(A.Int(a1),B.Int(b1)))|A.Float(a1),B.Float(b1)->(m_wrapm_string)a1b1>>=(fun(a1,b1)->return(A.Float(a1),B.Float(b1)))|A.Char(a1),B.Char(b1)->(m_wrapm_string)a1b1>>=(fun(a1,b1)->return(A.Char(a1),B.Char(b1)))|A.Regexp(a1),B.Regexp(b1)->(m_wrapm_string)a1b1>>=(fun(a1,b1)->return(A.Regexp(a1),B.Regexp(b1)))|A.Null(a1),B.Null(b1)->m_toka1b1>>=(fun(a1,b1)->return(A.Null(a1),B.Null(b1)))|A.Undefined(a1),B.Undefined(b1)->m_toka1b1>>=(fun(a1,b1)->return(A.Undefined(a1),B.Undefined(b1)))|A.Unit_,_|A.Bool_,_|A.Int_,_|A.Float_,_|A.Char_,_|A.String_,_|A.Regexp_,_|A.Null_,_|A.Undefined_,_->fail()andm_actionab=matcha,bwith|(a1,a2),(b1,b2)->m_patterna1b1>>=(fun(a1,b1)->m_expra2b2>>=(fun(a2,b2)->return((a1,a2),(b1,b2))))andm_arithmetic_operatorab=matcha,bwith|A.Plus,B.Plus->return(A.Plus,B.Plus)|A.Minus,B.Minus->return(A.Minus,B.Minus)|A.Mult,B.Mult->return(A.Mult,B.Mult)|A.Div,B.Div->return(A.Div,B.Div)|A.Mod,B.Mod->return(A.Mod,B.Mod)|A.Pow,B.Pow->return(A.Pow,B.Pow)|A.FloorDiv,B.FloorDiv->return(A.FloorDiv,B.FloorDiv)|A.LSL,B.LSL->return(A.LSL,B.LSL)|A.LSR,B.LSR->return(A.LSR,B.LSR)|A.ASR,B.ASR->return(A.ASR,B.ASR)|A.BitOr,B.BitOr->return(A.BitOr,B.BitOr)|A.BitXor,B.BitXor->return(A.BitXor,B.BitXor)|A.BitAnd,B.BitAnd->return(A.BitAnd,B.BitAnd)|A.BitNot,B.BitNot->return(A.BitNot,B.BitNot)|A.And,B.And->return(A.And,B.And)|A.Or,B.Or->return(A.Or,B.Or)|A.Not,B.Not->return(A.Not,B.Not)|A.Eq,B.Eq->return(A.Eq,B.Eq)|A.NotEq,B.NotEq->return(A.NotEq,B.NotEq)|A.PhysEq,B.PhysEq->return(A.PhysEq,B.PhysEq)|A.NotPhysEq,B.NotPhysEq->return(A.NotPhysEq,B.NotPhysEq)|A.Lt,B.Lt->return(A.Lt,B.Lt)|A.LtE,B.LtE->return(A.LtE,B.LtE)|A.Gt,B.Gt->return(A.Gt,B.Gt)|A.GtE,B.GtE->return(A.GtE,B.GtE)|A.Plus,_|A.Minus,_|A.Mult,_|A.Div,_|A.Mod,_|A.Pow,_|A.FloorDiv,_|A.LSL,_|A.LSR,_|A.ASR,_|A.BitOr,_|A.BitXor,_|A.BitAnd,_|A.BitNot,_|A.And,_|A.Or,_|A.Not,_|A.Eq,_|A.NotEq,_|A.PhysEq,_|A.NotPhysEq,_|A.Lt,_|A.LtE,_|A.Gt,_|A.GtE,_->fail()andm_specialab=matcha,bwith|A.This,B.This->return(A.This,B.This)|A.Super,B.Super->return(A.Super,B.Super)|A.Self,B.Self->return(A.Self,B.Self)|A.Parent,B.Parent->return(A.Parent,B.Parent)|A.Eval,B.Eval->return(A.Eval,B.Eval)|A.Typeof,B.Typeof->return(A.Typeof,B.Typeof)|A.Instanceof,B.Instanceof->return(A.Instanceof,B.Instanceof)|A.Sizeof,B.Sizeof->return(A.Sizeof,B.Sizeof)|A.New,B.New->return(A.New,B.New)|A.Concat,B.Concat->return(A.Concat,B.Concat)|A.Spread,B.Spread->return(A.Spread,B.Spread)|A.ArithOp(a1),B.ArithOp(b1)->m_arithmetic_operatora1b1>>=(fun(a1,b1)->return(A.ArithOp(a1),B.ArithOp(b1)))|A.IncrDecr(a1,a2),B.IncrDecr(b1,b2)->m_boola1b1>>=(fun(a1,b1)->m_boola2b2>>=(fun(a2,b2)->return(A.IncrDecr(a1,a2),B.IncrDecr(b1,b2))))|A.This,_|A.Super,_|A.Self,_|A.Parent,_|A.Eval,_|A.Typeof,_|A.Instanceof,_|A.Sizeof,_|A.New,_|A.Concat,_|A.Spread,_|A.ArithOp_,_|A.IncrDecr_,_->fail()andm_id_infoab=matcha,bwith{A.id_qualifier=a1;id_typeargs=a2;id_resolved=a3;id_type=a4;},{B.id_qualifier=b1;id_typeargs=b2;id_resolved=b3;id_type=b4;}->(m_optionm_dotted_name)a1b1>>=(fun(a1,b1)->(m_optionm_type_arguments)a2b2>>=(fun(a2,b2)->(m_refm_resolved_name)a3b3>>=(fun(a3,b3)->(m_ref(m_optionm_type_))a4b4>>=(fun(a4,b4)->return({A.id_qualifier=a1;id_typeargs=a2;id_resolved=a3;id_type=a4;},{B.id_qualifier=b1;id_typeargs=b2;id_resolved=b3;id_type=b4;})))))andm_container_operatorab=matcha,bwith|A.Array,B.Array->return(A.Array,B.Array)|A.List,B.List->return(A.List,B.List)|A.Set,B.Set->return(A.Set,B.Set)|A.Dict,B.Dict->return(A.Dict,B.Dict)|A.Array,_|A.List,_|A.Set,_|A.Dict,_->fail()andm_other_expr_operatorab=matcha,bwith|a,bwhena=*=b->return(a,b)|_->fail()(*---------------------------------------------------------------------------*)(* Arguments list iso *)(*---------------------------------------------------------------------------*)andm_argumentsab=matcha,bwith(a,b)->(m_list__m_argument)abandm_list__m_argument(xsa:A.argumentlist)(xsb:A.argumentlist)=matchxsa,xsbwith|[],[]->return([],[])(* iso '...', it can also match no argument *)|[A.Arg(A.Ellipses_i)],[]->return(xsa,xsb)(* iso on ... *)|[A.Arg(A.Ellipses_i)],_bbs->return(xsa,xsb)(* TODO
(* spread metavariable to match any arity *)
| [A.Apply(A.IdSpecial (A.Spread, info_spread_TODO),
[A.Id((name, info_name), aref)])],
bbs
when MV.is_metavar_name name ->
X.envf (name, info_name) (B.Expr (B.Apply (B.Nop, bbs))) >>= (function
| ((name, info_name), (B.Expr (B.Apply (B.Nop, bbs)))) ->
return (
[A.Apply(A.IdSpecial (A.Spread, info_spread_TODO),
[A.Id((name, info_name), aref)])],
bbs
)
| _ -> raise Impossible
)
*)(* the general case *)|xa::aas,xb::bbs->m_argumentxaxb>>=(fun(xa,xb)->m_list__m_argumentaasbbs>>=(fun(aas,bbs)->return(xa::aas,xb::bbs)))|[],_|_::_,_->fail()andm_argumentab=matcha,bwith|A.Arg(a1),B.Arg(b1)->m_expra1b1>>=(fun(a1,b1)->return(A.Arg(a1),B.Arg(b1)))(* TODO: iso on keyword argument, keyword is optional in pattern *)|A.ArgKwd(a1,a2),B.ArgKwd(b1,b2)->m_namea1b1>>=(fun(a1,b1)->m_expra2b2>>=(fun(a2,b2)->return(A.ArgKwd(a1,a2),B.ArgKwd(b1,b2))))|A.ArgOther(a1,a2),B.ArgOther(b1,b2)->m_other_argument_operatora1b1>>=(fun(a1,b1)->(m_listm_any)a2b2>>=(fun(a2,b2)->return(A.ArgOther(a1,a2),B.ArgOther(b1,b2))))|A.Arg_,_|A.ArgKwd_,_|A.ArgOther_,_->fail()andm_other_argument_operatorab=matcha,bwith|(a,b)whena=*=b->return(a,b)|_->fail()(* ------------------------------------------------------------------------- *)(* Type *)(* ------------------------------------------------------------------------- *)andm_type_ab=matcha,bwith|A.TyBuiltin(a1),B.TyBuiltin(b1)->(m_wrapm_string)a1b1>>=(fun(a1,b1)->return(A.TyBuiltin(a1),B.TyBuiltin(b1)))|A.TyFun(a1,a2),B.TyFun(b1,b2)->(m_listm_type_)a1b1>>=(fun(a1,b1)->m_type_a2b2>>=(fun(a2,b2)->return(A.TyFun(a1,a2),B.TyFun(b1,b2))))|A.TyApply(a1,a2),B.TyApply(b1,b2)->m_namea1b1>>=(fun(a1,b1)->m_type_argumentsa2b2>>=(fun(a2,b2)->return(A.TyApply(a1,a2),B.TyApply(b1,b2))))|A.TyVar(a1),B.TyVar(b1)->m_namea1b1>>=(fun(a1,b1)->return(A.TyVar(a1),B.TyVar(b1)))|A.TyArray(a1,a2),B.TyArray(b1,b2)->(m_optionm_expr)a1b1>>=(fun(a1,b1)->m_type_a2b2>>=(fun(a2,b2)->return(A.TyArray(a1,a2),B.TyArray(b1,b2))))|A.TyPointer(a1),B.TyPointer(b1)->m_type_a1b1>>=(fun(a1,b1)->return(A.TyPointer(a1),B.TyPointer(b1)))|A.TyTuple(a1),B.TyTuple(b1)->(m_listm_type_)a1b1>>=(fun(a1,b1)->return(A.TyTuple(a1),B.TyTuple(b1)))|A.TyQuestion(a1),B.TyQuestion(b1)->m_type_a1b1>>=(fun(a1,b1)->return(A.TyQuestion(a1),B.TyQuestion(b1)))|A.OtherType(a1,a2),B.OtherType(b1,b2)->m_other_type_operatora1b1>>=(fun(a1,b1)->(m_listm_any)a2b2>>=(fun(a2,b2)->return(A.OtherType(a1,a2),B.OtherType(b1,b2))))|A.TyBuiltin_,_|A.TyFun_,_|A.TyApply_,_|A.TyVar_,_|A.TyArray_,_|A.TyPointer_,_|A.TyTuple_,_|A.TyQuestion_,_|A.OtherType_,_->fail()andm_type_argumentsab=matcha,bwith(a,b)->(m_listm_type_argument)abandm_type_argumentab=matcha,bwith|A.TypeArg(a1),B.TypeArg(b1)->m_type_a1b1>>=(fun(a1,b1)->return(A.TypeArg(a1),B.TypeArg(b1)))|A.OtherTypeArg(a1,a2),B.OtherTypeArg(b1,b2)->m_other_type_argument_operatora1b1>>=(fun(a1,b1)->(m_listm_any)a2b2>>=(fun(a2,b2)->return(A.OtherTypeArg(a1,a2),B.OtherTypeArg(b1,b2))))|A.TypeArg_,_|A.OtherTypeArg_,_->fail()andm_other_type_operatorab=matcha,bwith|a,bwhena=*=b->return(a,b)|_->fail()andm_other_type_argument_operatorab=matcha,bwith|A.OTA_Question,B.OTA_Question->return(A.OTA_Question,B.OTA_Question)(* ------------------------------------------------------------------------- *)(* Attribute *)(* ------------------------------------------------------------------------- *)(* TODO: should sort attributes and allow subset *)andm_attributeab=matcha,bwith|A.Static,B.Static->return(A.Static,B.Static)|A.Volatile,B.Volatile->return(A.Volatile,B.Volatile)|A.Extern,B.Extern->return(A.Extern,B.Extern)|A.Public,B.Public->return(A.Public,B.Public)|A.Private,B.Private->return(A.Private,B.Private)|A.Protected,B.Protected->return(A.Protected,B.Protected)|A.Abstract,B.Abstract->return(A.Abstract,B.Abstract)|A.Final,B.Final->return(A.Final,B.Final)|A.Var,B.Var->return(A.Var,B.Var)|A.Let,B.Let->return(A.Let,B.Let)|A.Const,B.Const->return(A.Const,B.Const)|A.Generator,B.Generator->return(A.Generator,B.Generator)|A.Async,B.Async->return(A.Async,B.Async)|A.Ctor,B.Ctor->return(A.Ctor,B.Ctor)|A.Dtor,B.Dtor->return(A.Dtor,B.Dtor)|A.Getter,B.Getter->return(A.Getter,B.Getter)|A.Setter,B.Setter->return(A.Setter,B.Setter)|A.Variadic,B.Variadic->return(A.Variadic,B.Variadic)|A.NamedAttr(a1,a2),B.NamedAttr(b1,b2)->m_namea1b1>>=(fun(a1,b1)->(m_listm_any)a2b2>>=(fun(a2,b2)->return(A.NamedAttr(a1,a2),B.NamedAttr(b1,b2))))|A.OtherAttribute(a1,a2),B.OtherAttribute(b1,b2)->m_other_attribute_operatora1b1>>=(fun(a1,b1)->(m_listm_any)a2b2>>=(fun(a2,b2)->return(A.OtherAttribute(a1,a2),B.OtherAttribute(b1,b2))))|A.Static,_|A.Volatile,_|A.Extern,_|A.Public,_|A.Private,_|A.Protected,_|A.Abstract,_|A.Final,_|A.Var,_|A.Let,_|A.Const,_|A.Generator,_|A.Async,_|A.Ctor,_|A.Dtor,_|A.Getter,_|A.Setter,_|A.Variadic,_|A.NamedAttr_,_|A.OtherAttribute_,_->fail()andm_other_attribute_operatorab=matcha,bwith|(a,b)whena=*=b->return(a,b)|_->fail()(* ------------------------------------------------------------------------- *)(* Statement *)(* ------------------------------------------------------------------------- *)andm_stmtab=matcha,bwith(* special case metavar! *)|A.ExprStmt(A.Id((str,tok),id_info)),bwhenMV.is_metavar_namestr->X.envf(str,tok)(B.Sb)>>=(function|((str,tok),B.S(b))->return(A.ExprStmt((A.Id((str,tok),id_info))),b)|_->raiseImpossible)(* iso on ..., allow to match any statememt *)|A.ExprStmt(A.Ellipses_i),b->return(a,b)|A.ExprStmt(a1),B.ExprStmt(b1)->m_expra1b1>>=(fun(a1,b1)->return(A.ExprStmt(a1),B.ExprStmt(b1)))|A.LocalDef(a1),B.LocalDef(b1)->m_definitiona1b1>>=(fun(a1,b1)->return(A.LocalDef(a1),B.LocalDef(b1)))|A.LocalDirective(a1),B.LocalDirective(b1)->m_directivea1b1>>=(fun(a1,b1)->return(A.LocalDirective(a1),B.LocalDirective(b1)))(* TODO: ... should also allow a subset of stmts *)|A.Block(a1),B.Block(b1)->(m_listm_stmt)a1b1>>=(fun(a1,b1)->return(A.Block(a1),B.Block(b1)))|A.If(a1,a2,a3),B.If(b1,b2,b3)->m_expra1b1>>=(fun(a1,b1)->m_stmta2b2>>=(fun(a2,b2)->m_stmta3b3>>=(fun(a3,b3)->return(A.If(a1,a2,a3),B.If(b1,b2,b3)))))|A.While(a1,a2),B.While(b1,b2)->m_expra1b1>>=(fun(a1,b1)->m_stmta2b2>>=(fun(a2,b2)->return(A.While(a1,a2),B.While(b1,b2))))|A.DoWhile(a1,a2),B.DoWhile(b1,b2)->m_stmta1b1>>=(fun(a1,b1)->m_expra2b2>>=(fun(a2,b2)->return(A.DoWhile(a1,a2),B.DoWhile(b1,b2))))|A.For(a1,a2),B.For(b1,b2)->m_for_headera1b1>>=(fun(a1,b1)->m_stmta2b2>>=(fun(a2,b2)->return(A.For(a1,a2),B.For(b1,b2))))|A.Switch(a1,a2),B.Switch(b1,b2)->m_expra1b1>>=(fun(a1,b1)->(m_listm_case_and_body)a2b2>>=(fun(a2,b2)->return(A.Switch(a1,a2),B.Switch(b1,b2))))|A.Return(a1),B.Return(b1)->m_expra1b1>>=(fun(a1,b1)->return(A.Return(a1),B.Return(b1)))|A.Continue(a1),B.Continue(b1)->(m_optionm_expr)a1b1>>=(fun(a1,b1)->return(A.Continue(a1),B.Continue(b1)))|A.Break(a1),B.Break(b1)->(m_optionm_expr)a1b1>>=(fun(a1,b1)->return(A.Break(a1),B.Break(b1)))|A.Label(a1,a2),B.Label(b1,b2)->m_labela1b1>>=(fun(a1,b1)->m_stmta2b2>>=(fun(a2,b2)->return(A.Label(a1,a2),B.Label(b1,b2))))|A.Goto(a1),B.Goto(b1)->m_labela1b1>>=(fun(a1,b1)->return(A.Goto(a1),B.Goto(b1)))|A.Throw(a1),B.Throw(b1)->m_expra1b1>>=(fun(a1,b1)->return(A.Throw(a1),B.Throw(b1)))|A.Try(a1,a2,a3),B.Try(b1,b2,b3)->m_stmta1b1>>=(fun(a1,b1)->(m_listm_catch)a2b2>>=(fun(a2,b2)->(m_optionm_finally)a3b3>>=(fun(a3,b3)->return(A.Try(a1,a2,a3),B.Try(b1,b2,b3)))))|A.Assert(a1,a2),B.Assert(b1,b2)->m_expra1b1>>=(fun(a1,b1)->(m_optionm_expr)a2b2>>=(fun(a2,b2)->return(A.Assert(a1,a2),B.Assert(b1,b2))))|A.OtherStmt(a1,a2),B.OtherStmt(b1,b2)->m_other_stmt_operatora1b1>>=(fun(a1,b1)->(m_listm_any)a2b2>>=(fun(a2,b2)->return(A.OtherStmt(a1,a2),B.OtherStmt(b1,b2))))|A.ExprStmt_,_|A.LocalDef_,_|A.LocalDirective_,_|A.Block_,_|A.If_,_|A.While_,_|A.DoWhile_,_|A.For_,_|A.Switch_,_|A.Return_,_|A.Continue_,_|A.Break_,_|A.Label_,_|A.Goto_,_|A.Throw_,_|A.Try_,_|A.Assert_,_|A.OtherStmt_,_->fail()andm_for_headerab=matcha,bwith|A.ForClassic(a1,a2,a3),B.ForClassic(b1,b2,b3)->(m_listm_for_var_or_expr)a1b1>>=(fun(a1,b1)->m_expra2b2>>=(fun(a2,b2)->m_expra3b3>>=(fun(a3,b3)->return(A.ForClassic(a1,a2,a3),B.ForClassic(b1,b2,b3)))))|A.ForEach(a1,a2),B.ForEach(b1,b2)->m_patterna1b1>>=(fun(a1,b1)->m_expra2b2>>=(fun(a2,b2)->return(A.ForEach(a1,a2),B.ForEach(b1,b2))))|A.ForClassic_,_|A.ForEach_,_->fail()andm_for_var_or_exprab=matcha,bwith|A.ForInitVar(a1,a2),B.ForInitVar(b1,b2)->m_entitya1b1>>=(fun(a1,b1)->m_variable_definitiona2b2>>=(fun(a2,b2)->return(A.ForInitVar(a1,a2),B.ForInitVar(b1,b2))))|A.ForInitExpr(a1),B.ForInitExpr(b1)->m_expra1b1>>=(fun(a1,b1)->return(A.ForInitExpr(a1),B.ForInitExpr(b1)))|A.ForInitVar_,_|A.ForInitExpr_,_->fail()andm_labelab=matcha,bwith(a,b)->m_nameabandm_catchab=matcha,bwith|(a1,a2),(b1,b2)->m_patterna1b1>>=(fun(a1,b1)->m_stmta2b2>>=(fun(a2,b2)->return((a1,a2),(b1,b2))))andm_finallyab=matcha,bwith(a,b)->m_stmtabandm_case_and_bodyab=matcha,bwith|(a1,a2),(b1,b2)->(m_listm_case)a1b1>>=(fun(a1,b1)->m_stmta2b2>>=(fun(a2,b2)->return((a1,a2),(b1,b2))))andm_caseab=matcha,bwith|A.Case(a1),B.Case(b1)->m_expra1b1>>=(fun(a1,b1)->return(A.Case(a1),B.Case(b1)))|A.Default,B.Default->return(A.Default,B.Default)|A.Case_,_|A.Default,_->fail()andm_other_stmt_operatorab=matcha,bwith|a,bwhena=*=b->return(a,b)|_->fail()(* ------------------------------------------------------------------------- *)(* Pattern *)(* ------------------------------------------------------------------------- *)andm_patternab=matcha,bwith|A.PatVar(a1),B.PatVar(b1)->m_namea1b1>>=(fun(a1,b1)->return(A.PatVar(a1),B.PatVar(b1)))|A.PatLiteral(a1),B.PatLiteral(b1)->m_literala1b1>>=(fun(a1,b1)->return(A.PatLiteral(a1),B.PatLiteral(b1)))|A.PatConstructor(a1,a2),B.PatConstructor(b1,b2)->m_namea1b1>>=(fun(a1,b1)->(m_listm_pattern)a2b2>>=(fun(a2,b2)->return(A.PatConstructor(a1,a2),B.PatConstructor(b1,b2))))|A.PatTuple(a1),B.PatTuple(b1)->(m_listm_pattern)a1b1>>=(fun(a1,b1)->return(A.PatTuple(a1),B.PatTuple(b1)))|A.PatList(a1),B.PatList(b1)->(m_listm_pattern)a1b1>>=(fun(a1,b1)->return(A.PatList(a1),B.PatList(b1)))|A.PatKeyVal(a1,a2),B.PatKeyVal(b1,b2)->m_patterna1b1>>=(fun(a1,b1)->m_patterna2b2>>=(fun(a2,b2)->return(A.PatKeyVal(a1,a2),B.PatKeyVal(b1,b2))))|A.PatUnderscore(a1),B.PatUnderscore(b1)->m_toka1b1>>=(fun(a1,b1)->return(A.PatUnderscore(a1),B.PatUnderscore(b1)))|A.PatDisj(a1,a2),B.PatDisj(b1,b2)->m_patterna1b1>>=(fun(a1,b1)->m_patterna2b2>>=(fun(a2,b2)->return(A.PatDisj(a1,a2),B.PatDisj(b1,b2))))|A.PatTyped(a1,a2),B.PatTyped(b1,b2)->m_patterna1b1>>=(fun(a1,b1)->m_type_a2b2>>=(fun(a2,b2)->return(A.PatTyped(a1,a2),B.PatTyped(b1,b2))))|A.OtherPat(a1,a2),B.OtherPat(b1,b2)->m_other_pattern_operatora1b1>>=(fun(a1,b1)->(m_listm_any)a2b2>>=(fun(a2,b2)->return(A.OtherPat(a1,a2),B.OtherPat(b1,b2))))|A.PatVar_,_|A.PatLiteral_,_|A.PatConstructor_,_|A.PatTuple_,_|A.PatList_,_|A.PatKeyVal_,_|A.PatUnderscore_,_|A.PatDisj_,_|A.PatTyped_,_|A.OtherPat_,_->fail()andm_other_pattern_operatorab=matcha,bwith|A.OP_Expr,B.OP_Expr->return(A.OP_Expr,B.OP_Expr)|A.OP_Var,B.OP_Var->return(A.OP_Var,B.OP_Var)|A.OP_Expr,_|A.OP_Var,_->fail()(* ------------------------------------------------------------------------- *)(* Definitions *)(* ------------------------------------------------------------------------- *)andm_definitionab=matcha,bwith|(a1,a2),(b1,b2)->m_entitya1b1>>=(fun(a1,b1)->m_definition_kinda2b2>>=(fun(a2,b2)->return((a1,a2),(b1,b2))))andm_entityab=matcha,bwith{A.name=a1;attrs=a2;type_=a3;tparams=a4;},{B.name=b1;attrs=b2;type_=b3;tparams=b4;}->m_namea1b1>>=(fun(a1,b1)->(m_listm_attribute)a2b2>>=(fun(a2,b2)->(m_optionm_type_)a3b3>>=(fun(a3,b3)->(m_listm_type_parameter)a4b4>>=(fun(a4,b4)->return({A.name=a1;attrs=a2;type_=a3;tparams=a4;},{B.name=b1;attrs=b2;type_=b3;tparams=b4;})))))andm_definition_kindab=matcha,bwith|A.FuncDef(a1),B.FuncDef(b1)->m_function_definitiona1b1>>=(fun(a1,b1)->return(A.FuncDef(a1),B.FuncDef(b1)))|A.VarDef(a1),B.VarDef(b1)->m_variable_definitiona1b1>>=(fun(a1,b1)->return(A.VarDef(a1),B.VarDef(b1)))|A.ClassDef(a1),B.ClassDef(b1)->m_class_definitiona1b1>>=(fun(a1,b1)->return(A.ClassDef(a1),B.ClassDef(b1)))|A.TypeDef(a1),B.TypeDef(b1)->m_type_definitiona1b1>>=(fun(a1,b1)->return(A.TypeDef(a1),B.TypeDef(b1)))|A.FuncDef_,_|A.VarDef_,_|A.ClassDef_,_|A.TypeDef_,_->fail()andm_type_parameter_constraintab=matcha,bwith|A.Extends(a1),B.Extends(b1)->m_type_a1b1>>=(fun(a1,b1)->return(A.Extends(a1),B.Extends(b1)))andm_type_parameter_constraintsab=matcha,bwith(a,b)->(m_listm_type_parameter_constraint)abandm_type_parameterab=matcha,bwith|(a1,a2),(b1,b2)->m_namea1b1>>=(fun(a1,b1)->m_type_parameter_constraintsa2b2>>=(fun(a2,b2)->return((a1,a2),(b1,b2))))(* ------------------------------------------------------------------------- *)(* Function (or method) definition *)(* ------------------------------------------------------------------------- *)andm_function_definitionab=matcha,bwith{A.fparams=a1;frettype=a2;fbody=a3;},{B.fparams=b1;frettype=b2;fbody=b3;}->m_parametersa1b1>>=(fun(a1,b1)->(m_optionm_type_)a2b2>>=(fun(a2,b2)->m_stmta3b3>>=(fun(a3,b3)->return({A.fparams=a1;frettype=a2;fbody=a3;},{B.fparams=b1;frettype=b2;fbody=b3;}))))andm_parametersab=matcha,bwith(a,b)->(m_listm_parameter)abandm_parameterab=matcha,bwith|A.ParamClassic(a1),B.ParamClassic(b1)->m_parameter_classica1b1>>=(fun(a1,b1)->return(A.ParamClassic(a1),B.ParamClassic(b1)))|A.ParamPattern(a1),B.ParamPattern(b1)->m_patterna1b1>>=(fun(a1,b1)->return(A.ParamPattern(a1),B.ParamPattern(b1)))|A.OtherParam(a1,a2),B.OtherParam(b1,b2)->m_other_parameter_operatora1b1>>=(fun(a1,b1)->(m_listm_any)a2b2>>=(fun(a2,b2)->return(A.OtherParam(a1,a2),B.OtherParam(b1,b2))))|A.ParamClassic_,_|A.ParamPattern_,_|A.OtherParam_,_->fail()andm_parameter_classicab=matcha,bwith{A.pname=a1;pdefault=a2;ptype=a3;pattrs=a4;},{B.pname=b1;pdefault=b2;ptype=b3;pattrs=b4;}->m_namea1b1>>=(fun(a1,b1)->(m_optionm_expr)a2b2>>=(fun(a2,b2)->(m_optionm_type_)a3b3>>=(fun(a3,b3)->(m_listm_attribute)a4b4>>=(fun(a4,b4)->return({A.pname=a1;pdefault=a2;ptype=a3;pattrs=a4;},{B.pname=b1;pdefault=b2;ptype=b3;pattrs=b4;})))))andm_other_parameter_operatorab=matcha,bwith|A.OPO_KwdParam,B.OPO_KwdParam->return(A.OPO_KwdParam,B.OPO_KwdParam)|A.OPO_Ref,B.OPO_Ref->return(A.OPO_Ref,B.OPO_Ref)|A.OPO_KwdParam,_|A.OPO_Ref,_->fail()(* ------------------------------------------------------------------------- *)(* Variable definition *)(* ------------------------------------------------------------------------- *)andm_variable_definitionab=matcha,bwith{A.vinit=a1;vtype=a2;},{B.vinit=b1;vtype=b2;}->(m_optionm_expr)a1b1>>=(fun(a1,b1)->(m_optionm_type_)a2b2>>=(fun(a2,b2)->return({A.vinit=a1;vtype=a2;},{B.vinit=b1;vtype=b2;})))(* ------------------------------------------------------------------------- *)(* Field definition and use *)(* ------------------------------------------------------------------------- *)andm_fieldab=matcha,bwith|A.FieldVar(a1,a2),B.FieldVar(b1,b2)->m_entitya1b1>>=(fun(a1,b1)->m_variable_definitiona2b2>>=(fun(a2,b2)->return(A.FieldVar(a1,a2),B.FieldVar(b1,b2))))|A.FieldMethod(a1,a2),B.FieldMethod(b1,b2)->m_entitya1b1>>=(fun(a1,b1)->m_function_definitiona2b2>>=(fun(a2,b2)->return(A.FieldMethod(a1,a2),B.FieldMethod(b1,b2))))|A.FieldDynamic(a1,a2,a3),B.FieldDynamic(b1,b2,b3)->m_expra1b1>>=(fun(a1,b1)->(m_listm_attribute)a2b2>>=(fun(a2,b2)->m_expra3b3>>=(fun(a3,b3)->return(A.FieldDynamic(a1,a2,a3),B.FieldDynamic(b1,b2,b3)))))|A.FieldSpread(a1),B.FieldSpread(b1)->m_expra1b1>>=(fun(a1,b1)->return(A.FieldSpread(a1),B.FieldSpread(b1)))|A.FieldStmt(a1),B.FieldStmt(b1)->m_stmta1b1>>=(fun(a1,b1)->return(A.FieldStmt(a1),B.FieldStmt(b1)))|A.FieldVar_,_|A.FieldMethod_,_|A.FieldDynamic_,_|A.FieldSpread_,_|A.FieldStmt_,_->fail()(* ------------------------------------------------------------------------- *)(* Type definition *)(* ------------------------------------------------------------------------- *)andm_type_definitionab=matcha,bwith|A.OrType(a1),B.OrType(b1)->(m_listm_or_type)a1b1>>=(fun(a1,b1)->return(A.OrType(a1),B.OrType(b1)))|A.AndType(a1),B.AndType(b1)->(m_listm_field)a1b1>>=(fun(a1,b1)->return(A.AndType(a1),B.AndType(b1)))|A.AliasType(a1),B.AliasType(b1)->m_type_a1b1>>=(fun(a1,b1)->return(A.AliasType(a1),B.AliasType(b1)))|A.OtherTypeKind(a1,a2),B.OtherTypeKind(b1,b2)->m_other_type_kind_operatora1b1>>=(fun(a1,b1)->(m_listm_any)a2b2>>=(fun(a2,b2)->return(A.OtherTypeKind(a1,a2),B.OtherTypeKind(b1,b2))))|A.OrType_,_|A.AndType_,_|A.AliasType_,_|A.OtherTypeKind_,_->fail()andm_or_typeab=matcha,bwith|A.OrConstructor(a1,a2),B.OrConstructor(b1,b2)->(m_name)a1b1>>=(fun(a1,b1)->(m_listm_type_)a2b2>>=(fun(a2,b2)->return(A.OrConstructor(a1,a2),B.OrConstructor(b1,b2))))|A.OrEnum(a1,a2),B.OrEnum(b1,b2)->m_namea1b1>>=(fun(a1,b1)->(m_expr)a2b2>>=(fun(a2,b2)->return(A.OrEnum(a1,a2),B.OrEnum(b1,b2))))|A.OrUnion(a1,a2),B.OrUnion(b1,b2)->m_namea1b1>>=(fun(a1,b1)->(m_type_)a2b2>>=(fun(a2,b2)->return(A.OrUnion(a1,a2),B.OrUnion(b1,b2))))|A.OrConstructor_,_|A.OrEnum_,_|A.OrUnion_,_->fail()andm_other_type_kind_operatorab=matcha,bwith|A.OTKO_EnumWithValue,B.OTKO_EnumWithValue->return(A.OTKO_EnumWithValue,B.OTKO_EnumWithValue)(* ------------------------------------------------------------------------- *)(* Class definition *)(* ------------------------------------------------------------------------- *)andm_class_definitionab=matcha,bwith{A.ckind=a1;cextends=a2;cimplements=a3;cbody=a4;},{B.ckind=b1;cextends=b2;cimplements=b3;cbody=b4;}->m_class_kinda1b1>>=(fun(a1,b1)->(m_listm_type_)a2b2>>=(fun(a2,b2)->(m_listm_type_)a3b3>>=(fun(a3,b3)->(m_listm_field)a4b4>>=(fun(a4,b4)->return({A.ckind=a1;cextends=a2;cimplements=a3;cbody=a4;},{B.ckind=b1;cextends=b2;cimplements=b3;cbody=b4;})))))andm_class_kindab=matcha,bwith|A.Class,B.Class->return(A.Class,B.Class)|A.Interface,B.Interface->return(A.Interface,B.Interface)|A.Trait,B.Trait->return(A.Trait,B.Trait)|A.Class,_|A.Interface,_|A.Trait,_->fail()(* ------------------------------------------------------------------------- *)(* Directives (Module import/export, macros) *)(* ------------------------------------------------------------------------- *)andm_directiveab=matcha,bwith|A.Import(a1,a2),B.Import(b1,b2)->m_module_namea1b1>>=(fun(a1,b1)->(m_listm_alias)a2b2>>=(fun(a2,b2)->return(A.Import(a1,a2),B.Import(b1,b2))))|A.ImportAll(a1,a2),B.ImportAll(b1,b2)->m_module_namea1b1>>=(fun(a1,b1)->(m_optionm_name)a2b2>>=(fun(a2,b2)->return(A.ImportAll(a1,a2),B.ImportAll(b1,b2))))|A.OtherDirective(a1,a2),B.OtherDirective(b1,b2)->m_other_directive_operatora1b1>>=(fun(a1,b1)->(m_listm_any)a2b2>>=(fun(a2,b2)->return(A.OtherDirective(a1,a2),B.OtherDirective(b1,b2))))|A.Import_,_|A.ImportAll_,_|A.OtherDirective_,_->fail()andm_aliasab=matcha,bwith|(a1,a2),(b1,b2)->m_namea1b1>>=(fun(a1,b1)->(m_optionm_name)a2b2>>=(fun(a2,b2)->return((a1,a2),(b1,b2))))andm_other_directive_operatorab=matcha,bwith|a,bwhena=*=b->return(a,b)|_->fail()(* ------------------------------------------------------------------------- *)(* Toplevel *)(* ------------------------------------------------------------------------- *)andm_itemab=matcha,bwith|A.IStmt(a1),B.IStmt(b1)->m_stmta1b1>>=(fun(a1,b1)->return(A.IStmt(a1),B.IStmt(b1)))|A.IDef(a1),B.IDef(b1)->m_definitiona1b1>>=(fun(a1,b1)->return(A.IDef(a1),B.IDef(b1)))|A.IDir(a1),B.IDir(b1)->m_directivea1b1>>=(fun(a1,b1)->return(A.IDir(a1),B.IDir(b1)))|A.IStmt_,_|A.IDef_,_|A.IDir_,_->fail()andm_programab=matcha,bwith(a,b)->(m_listm_item)ab(* ------------------------------------------------------------------------- *)(* Any *)(* ------------------------------------------------------------------------- *)andm_anyab=matcha,bwith|A.N(a1),B.N(b1)->m_namea1b1>>=(fun(a1,b1)->return(A.N(a1),B.N(b1)))|A.Dn(a1),B.Dn(b1)->m_dotted_namea1b1>>=(fun(a1,b1)->return(A.Dn(a1),B.Dn(b1)))|A.En(a1),B.En(b1)->m_entitya1b1>>=(fun(a1,b1)->return(A.En(a1),B.En(b1)))|A.E(a1),B.E(b1)->m_expra1b1>>=(fun(a1,b1)->return(A.E(a1),B.E(b1)))|A.S(a1),B.S(b1)->m_stmta1b1>>=(fun(a1,b1)->return(A.S(a1),B.S(b1)))|A.T(a1),B.T(b1)->m_type_a1b1>>=(fun(a1,b1)->return(A.T(a1),B.T(b1)))|A.P(a1),B.P(b1)->m_patterna1b1>>=(fun(a1,b1)->return(A.P(a1),B.P(b1)))|A.D(a1),B.D(b1)->m_definitiona1b1>>=(fun(a1,b1)->return(A.D(a1),B.D(b1)))|A.Di(a1),B.Di(b1)->m_directivea1b1>>=(fun(a1,b1)->return(A.Di(a1),B.Di(b1)))|A.I(a1),B.I(b1)->m_itema1b1>>=(fun(a1,b1)->return(A.I(a1),B.I(b1)))|A.Pa(a1),B.Pa(b1)->m_parametera1b1>>=(fun(a1,b1)->return(A.Pa(a1),B.Pa(b1)))|A.Ar(a1),B.Ar(b1)->m_argumenta1b1>>=(fun(a1,b1)->return(A.Ar(a1),B.Ar(b1)))|A.At(a1),B.At(b1)->m_attributea1b1>>=(fun(a1,b1)->return(A.At(a1),B.At(b1)))|A.Dk(a1),B.Dk(b1)->m_definition_kinda1b1>>=(fun(a1,b1)->return(A.Dk(a1),B.Dk(b1)))|A.Pr(a1),B.Pr(b1)->m_programa1b1>>=(fun(a1,b1)->return(A.Pr(a1),B.Pr(b1)))|A.N_,_|A.Dn_,_|A.En_,_|A.E_,_|A.S_,_|A.T_,_|A.P_,_|A.D_,_|A.Di_,_|A.I_,_|A.Pa_,_|A.Ar_,_|A.At_,_|A.Dk_,_|A.Pr_,_->fail()end