123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539(* 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.
*)openCommonopenAst_pythonmoduleG=Ast_generic(*****************************************************************************)(* Prelude *)(*****************************************************************************)(* Ast_python to Ast_generic.
*
* See ast_generic.ml for more information.
*)(*****************************************************************************)(* Helpers *)(*****************************************************************************)letid=funx->xletoption=Common.map_optletlist=List.mapletvreffx=ref(f!x)letstring=idletbool=idletfake_info()=Parse_info.fake_info"FAKE"(*****************************************************************************)(* Entry point *)(*****************************************************************************)letinfox=xletwrap=fun_of_a(v1,v2)->letv1=_of_av1andv2=infov2in(v1,v2)letnamev=wrapstringvletdotted_namev=listnamevletgensym_TODO=-1letresolved_namename=function|LocalVar->Some(G.Localgensym_TODO)|Parameter->Some(G.Paramgensym_TODO)|GlobalVar->Some(G.Global[name])|ClassField->None|ImportedModulexs->Some(G.ImportedModulexs)|ImportedEntityxs->Some(G.Globalxs)|NotResolved->Noneletexpr_context=function|Load->()|Store->()|Del->()|AugLoad->()|AugStore->()|Param->()letrecexpr(x:expr)=matchxwith|Boolv1->letv1=wrapboolv1inG.L(G.Boolv1)|None_x->letx=infoxinG.L(G.Nullx)|Ellipsesx->letx=infoxinG.Ellipsesx|Numv1->letv1=numberv1in(matchv1with|Leftx->G.Lx|Rightx->x)|Str(v1)->letv1=wrapstringv1inG.L(G.String(v1))|InterpolatedStringxs->G.Call(G.IdSpecial(G.Concat,fake_info()),xs|>List.map(funx->letx=exprxinG.Arg(x)))|TypedExpr(v1,v2)->letv1=exprv1inletv2=type_v2inG.Cast(v2,v1)|ExprStarv1->letv1=exprv1inG.Call(G.IdSpecial(G.Spread,fake_info()),[G.expr_to_argv1])|Name((v1,v2,v3))->letv1=namev1and_v2TODO=expr_contextv2andv3=vref(resolved_namev1)v3inG.Name((v1,G.empty_name_info),{G.id_type=refNone;id_resolved=v3})|Tuple((CompListv1,v2))->letv1=listexprv1and_v2TODO=expr_contextv2inG.Tuplev1|Tuple((CompForIf(v1,v2),v3))->lete1=comprehensionexprv1v2inlet_v4TODO=expr_contextv3inG.Tuplee1|List((CompListv1,v2))->letv1=listexprv1and_v2TODO=expr_contextv2inG.Container(G.List,v1)|List((CompForIf(v1,v2),v3))->lete1=comprehensionexprv1v2inlet_v3TODO=expr_contextv3inG.Container(G.List,e1)|Subscript((v1,v2,v3))->letv1=exprv1andv2=listslicev2and_v3TODO=expr_contextv3in(matchv2with|[G.OE_SliceIndex,e]->G.ArrayAccess(v1,e)|xs->G.OtherExpr(G.OE_Slice,xs|>List.map(fun(other,e)->G.E(G.OtherExpr(other,[G.Ee])))))|Attribute((v1,v2,v3))->letv1=exprv1andv2=namev2and_v3TODO=expr_contextv3inG.ObjAccess(v1,v2)|DictOrSet(CompListv)->letv=listdictorset_eltvin(* less: could be a Set if alls are Key *)G.Container(G.Dict,v)|DictOrSet(CompForIf(v1,v2))->lete1=comprehension2dictorset_eltv1v2inG.Container(G.Dict,e1)|BoolOp(((v1,tok),v2))->letv1=boolopv1andv2=listexprv2inG.Call(G.IdSpecial(G.ArithOpv1,tok),v2|>List.mapG.expr_to_arg)|BinOp((v1,(v2,tok),v3))->letv1=exprv1andv2=operatorv2andv3=exprv3inG.Call(G.IdSpecial(G.ArithOpv2,tok),[v1;v3]|>List.mapG.expr_to_arg)|UnaryOp(((v1,tok),v2))->letv1=unaryopv1andv2=exprv2in(matchv1with|Leftop->G.Call(G.IdSpecial(G.ArithOpop,tok),[v2]|>List.mapG.expr_to_arg)|Rightoe->G.OtherExpr(oe,[G.Ev2]))|Compare((v1,v2,v3))->letv1=exprv1andv2=listcmpopv2andv3=listexprv3in(matchv2,v3with|[Leftop,tok],[e]->G.Call(G.IdSpecial(G.ArithOpop,tok),[v1;e]|>List.mapG.expr_to_arg)|[Rightoe,_tok],[e]->G.OtherExpr(oe,[G.Ev1;G.Ee])|_->letanyops=v2|>List.map(function|Leftarith,tok->G.E(G.IdSpecial(G.ArithOparith,tok))|Rightother,_tok->G.E(G.OtherExpr(other,[])))inletany=anyops@(v3|>List.map(fune->G.Ee))inG.OtherExpr(G.OE_CmpOps,any))|Call(v1,v2)->letv1=exprv1inletv2=listargumentv2inG.Call(v1,v2)|Lambda((v1,v2))->letv1=parametersv1andv2=exprv2inG.Lambda({G.fparams=v1;fbody=G.ExprStmtv2;frettype=None})|IfExp((v1,v2,v3))->letv1=exprv1andv2=exprv2andv3=exprv3inG.Conditional(v1,v2,v3)|Yieldv1->letv1=optionexprv1inG.Yield(G.opt_to_nopv1)|Awaitv1->letv1=exprv1inG.Awaitv1|Reprv1->letv1=exprv1inG.OtherExpr(G.OE_Repr,[G.Ev1])andargument=function|Arge->lete=expreinG.Arge|ArgStare->lete=expreinG.Arg(G.Call(G.IdSpecial(G.Spread,fake_info()),[G.expr_to_arge]))|ArgPowe->lete=expreinG.ArgOther(G.OA_ArgPow,[G.Ee])|ArgKwd(n,e)->letn=nameninlete=expreinG.ArgKwd(n,e)|ArgComp(e,xs)->lete=expreinG.ArgOther(G.OA_ArgComp,(G.Ee)::listfor_ifxs)andfor_if=function|CompFor(e1,e2)->lete1=expre1inlete2=expre2inG.E(G.OtherExpr(G.OE_CompFor,[G.Ee1;G.Ee2]))|CompIf(e1)->lete1=expre1inG.E(G.OtherExpr(G.OE_CompIf,[G.Ee1]))anddictorset_elt=function|KeyVal(v1,v2)->letv1=exprv1inletv2=exprv2inG.Tuple[v1;v2]|Key(v1)->letv1=exprv1inv1|PowInline(v1)->letv1=exprv1inG.Call(G.IdSpecial(G.Spread,fake_info()),[G.expr_to_argv1])andnumber=function|Intv1->letv1=wrapidv1inLeft(G.Intv1)|LongIntv1->letv1=wrapidv1inLeft(G.Intv1)|Floatv1->letv1=wrapidv1inLeft(G.Floatv1)|Imagv1->letv1=wrapstringv1inRight(G.OtherExpr(G.OE_Imag,[G.E(G.L(G.Intv1))]))andboolop=function|And->G.And|Or->G.Orandoperator=function|Add->G.Plus|Sub->G.Minus|Mult->G.Mult|Div->G.Div|Mod->G.Mod|Pow->G.Pow|FloorDiv->G.FloorDiv|LShift->G.LSL|RShift->G.LSR|BitOr->G.BitOr|BitXor->G.BitXor|BitAnd->G.BitAndandunaryop=function|Invert->RightG.OE_Invert|Not->LeftG.Not|UAdd->LeftG.Plus|USub->LeftG.Minusandcmpop(a,b)=matchawith|Eq->LeftG.Eq,b|NotEq->LeftG.NotEq,b|Lt->LeftG.Lt,b|LtE->LeftG.LtE,b|Gt->LeftG.Gt,b|GtE->LeftG.GtE,b|Is->RightG.OE_Is,b|IsNot->RightG.OE_IsNot,b|In->RightG.OE_In,b|NotIn->RightG.OE_NotIn,bandcomprehensionfv1v2=letv1=fv1inletv2=listfor_ifv2in[G.OtherExpr(G.OE_CompForIf,(G.Ev1)::v2)]andcomprehension2fv1v2=letv1=fv1inletv2=listfor_ifv2in[G.OtherExpr(G.OE_CompForIf,(G.Ev1)::v2)]andslice=function|Indexv1->letv1=exprv1inG.OE_SliceIndex,v1|Slice((v1,v2,v3))->letv1=optionexprv1andv2=optionexprv2andv3=optionexprv3inlettuple=G.Tuple([v1;v2;v3]|>List.mapG.opt_to_nop)inG.OE_SliceRange,tupleandparametersxs=xs|>List.map(function|ParamClassic((n,topt),eopt)->letn=nameninlettopt=optiontype_toptinleteopt=optionexpreoptinG.ParamClassic{(G.basic_paramn)withG.ptype=topt;pdefault=eopt;}|ParamStar(n,topt)->letn=nameninlettopt=optiontype_toptinG.ParamClassic{(G.basic_paramn)withG.ptype=topt;pattrs=[G.Variadic];}|ParamPow(n,topt)->letn=nameninlettopt=optiontype_toptinG.OtherParam(G.OPO_KwdParam,[G.Idn]@(matchtoptwithNone->[]|Somet->[G.Tt])))andtype_v=letv=exprvinG.OtherType(G.OT_Expr,[G.Ev])andtype_parentv=letv=argumentvinG.OtherType(G.OT_Arg,[G.Arv])andlist_stmt1xs=match(liststmtxs)with|[e]->e|xs->G.Blockxsandstmtx=matchxwith|FunctionDef((v1,v2,v3,v4,v5))->letv1=namev1andv2=parametersv2andv3=optiontype_v3andv4=list_stmt1v4andv5=listdecoratorv5inletent=G.basic_entityv1v5inletdef={G.fparams=v2;frettype=v3;fbody=v4;}in(* will be lift up to a IDef later *)G.DefStmt(ent,G.FuncDefdef)|ClassDef((v1,v2,v3,v4))->letv1=namev1andv2=listtype_parentv2andv3=liststmtv3andv4=listdecoratorv4inletent=G.basic_entityv1v4inletdef={G.ckind=G.Class;cextends=v2;cimplements=[];cbody=List.mapG.stmt_to_fieldv3;}in(* will be lift up to a IDef later *)G.DefStmt(ent,G.ClassDefdef)(* TODO: should turn some of those in G.LocalDef (G.VarDef ! ) *)|Assign((v1,v2))->letv1=listexprv1andv2=exprv2in(matchv1with|[]->raiseImpossible|[a]->G.ExprStmt(G.Assign(a,v2))|xs->G.ExprStmt(G.Assign(G.Tuplexs,v2)))|AugAssign((v1,(v2,tok),v3))->letv1=exprv1andv2=operatorv2andv3=exprv3inG.ExprStmt(G.AssignOp(v1,(v2,tok),v3))|Returnv1->letv1=optionexprv1inG.Return(G.opt_to_nopv1)|Deletev1->letv1=listexprv1inG.OtherStmt(G.OS_Delete,v1|>List.map(funx->G.Ex))|If((v1,v2,v3))->letv1=exprv1andv2=list_stmt1v2andv3=list_stmt1v3inG.If(v1,v2,v3)|While((v1,v2,v3))->letv1=exprv1andv2=list_stmt1v2andv3=liststmtv3in(matchv3with|[]->G.While(v1,v2)|_->G.Block[G.While(v1,v2);G.OtherStmt(G.OS_WhileOrElse,v3|>List.map(funx->G.Sx))])|For((v1,v2,v3,v4))->letforeach=exprv1andins=exprv2andbody=list_stmt1v3andorelse=liststmtv4inletheader=G.ForEach(G.OtherPat(G.OP_Expr,[G.Eforeach]),ins)in(matchorelsewith|[]->G.For(header,body)|_->G.Block[G.For(header,body);G.OtherStmt(G.OS_ForOrElse,orelse|>List.map(funx->G.Sx))])|With((v1,v2,v3))->letv1=exprv1andv2=optionexprv2andv3=list_stmt1v3inlete=matchv2with|None->v1|Somee2->G.LetPattern(G.OtherPat(G.OP_Expr,[G.Ee2]),v1)inG.OtherStmtWithStmt(G.OSWS_With,e,v3)|Raise(v1)->(matchv1with|Some(e,None)->lete=expreinG.Throwe|Some(e,Somefrom)->lete=expreinletfrom=exprfrominletst=G.ThroweinG.OtherStmt(G.OS_ThrowFrom,[G.Efrom;G.Sst])|None->G.OtherStmt(G.OS_ThrowNothing,[]))|TryExcept((v1,v2,v3))->letv1=list_stmt1v1andv2=listexcepthandlerv2andorelse=liststmtv3in(matchorelsewith|[]->G.Try(v1,v2,None)|_->G.Block[G.Try(v1,v2,None);G.OtherStmt(G.OS_TryOrElse,orelse|>List.map(funx->G.Sx))])|TryFinally((v1,v2))->letv1=list_stmt1v1andv2=list_stmt1v2in(* could lift down the Try in v1 *)G.Try(v1,[],Somev2)|Assert((v1,v2))->letv1=exprv1andv2=optionexprv2inG.Assert(v1,v2)|Importv1->letv1=listalias2v1inG.Block(v1|>List.map(fun(dotted,nopt)->G.DirectiveStmt(G.ImportAs(G.DottedNamedotted,nopt))))|ImportFrom((v1,v2,v3))->letv1=dotted_namev1andv2=listaliasv2and_v3Dotlevel=(*option int v3 *)v3in(* will be lift up to IDef later *)G.DirectiveStmt(G.ImportFrom(G.DottedNamev1,v2))|Globalv1->letv1=listnamev1inG.OtherStmt(G.OS_Global,v1|>List.map(funx->G.Idx))|NonLocalv1->letv1=listnamev1inG.OtherStmt(G.OS_NonLocal,v1|>List.map(funx->G.Idx))|ExprStmtv1->letv1=exprv1inG.ExprStmtv1|Asyncx->letx=stmtxin(matchxwith|G.DefStmt(ent,func)->G.DefStmt({entwithG.attrs=G.Async::ent.G.attrs},func)|_->G.OtherStmt(G.OS_Async,[G.Sx]))|Pass->G.OtherStmt(G.OS_Pass,[])|Break->G.Break(None)|Continue->G.Continue(None)andexcepthandler=function|ExceptHandler((v1,v2,v3))->letv1=optionexprv1andv2=optionexprv2andv3=list_stmt1v3in(matchv1,v2with|Somee,None->letpat=G.OtherPat(G.OP_Expr,[G.Ee])inpat,v3|_->lete1=G.opt_to_nopv1inlete2=G.opt_to_nopv2inletpat=G.OtherPat(G.OP_Expr,[G.Ee1;G.Ee2])inpat,v3)anddecoratorv=letv=exprvinG.OtherAttribute(G.OA_Expr,[G.Ev])andalias(v1,v2)=letv1=namev1andv2=optionnamev2inv1,v2andalias2(v1,v2)=letv1=dotted_namev1andv2=optionnamev2inv1,v2letprogramv=letv=liststmtvinv|>List.mapG.stmt_to_itemletany=function|Exprv1->letv1=exprv1inG.Ev1|Stmtv1->letv1=stmtv1inG.Sv1|Stmtsv1->letv1=liststmtv1inG.S(G.Blockv1)|Programv1->letv1=programv1inG.Prv1|DictElemv1->letv1=dictorset_eltv1inG.Ev1