123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390(* 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.
*)openCommonmoduleG=Ast_genericopenCst_cppopenAst_c(*****************************************************************************)(* Prelude *)(*****************************************************************************)(* Ast_c to Ast_generic.
*
* See ast_generic.ml for more information.
*)(*****************************************************************************)(* Helpers *)(*****************************************************************************)letid=funx->xletoption=Common.map_optletlist=List.mapleteitherfgx=matchxwith|Leftx->Left(fx)|Rightx->Right(gx)letstring=idletfake_info()=Parse_info.fake_info"FAKE"(*****************************************************************************)(* Entry point *)(*****************************************************************************)letinfox=xletwrap=fun_of_a(v1,v2)->letv1=_of_av1andv2=infov2in(v1,v2)letnamev=wrapstringvletrecunaryOp(a,tok)=matchawith|GetRef->(fune->G.Refe)|DeRef->(fune->G.DeRefe)|UnPlus->(fune->G.Call(G.IdSpecial(G.ArithOpG.Plus,tok),[G.Arge]))|UnMinus->(fune->G.Call(G.IdSpecial(G.ArithOpG.Minus,tok),[G.Arge]))|Tilde->(fune->G.Call(G.IdSpecial(G.ArithOpG.BitNot,tok),[G.Arge]))|Not->(fune->G.Call(G.IdSpecial(G.ArithOpG.Not,tok),[G.Arge]))|GetRefLabel->(fune->G.OtherExpr(G.OE_GetRefLabel,[G.Ee]))andassignOp=function|SimpleAssign->None|OpAssignv1->letv1=arithOpv1inSomev1andfixOp=function|Dec->G.Decr|Inc->G.IncrandbinaryOp=function|Arithv1->letv1=arithOpv1inv1|Logicalv1->letv1=logicalOpv1inv1andarithOp=function|Plus->G.Plus|Minus->G.Minus|Mul->G.Mult|Div->G.Div|Mod->G.Mod|DecLeft->G.LSL|DecRight->G.LSR|And->G.BitAnd|Or->G.BitOr|Xor->G.BitXorandlogicalOp=function|Inf->G.Lt|Sup->G.Gt|InfEq->G.LtE|SupEq->G.GtE|Eq->G.Eq|NotEq->G.NotEq|AndLog->G.And|OrLog->G.Orletrectype_=function|TBasev1->letv1=namev1inG.TyBuiltinv1|TPointerv1->letv1=type_v1inG.TyPointerv1|TArray((v1,v2))->letv1=optionconst_exprv1andv2=type_v2inG.TyArray(v1,v2)|TFunctionv1->let(ret,params)=function_typev1in(* dropping the optional name *)letparams=params|>List.mapfstinG.TyFun(params,ret)|TStructName((v1,v2))->letv1=struct_kindv1andv2=namev2inG.OtherType(v1,[G.Idv2])|TEnumNamev1->letv1=namev1inG.OtherType(G.OT_EnumName,[G.Idv1])|TTypeNamev1->letv1=namev1inG.TyApply((v1,G.empty_name_info),[])andfunction_type(v1,v2)=letv1=type_v1andv2=listparameterv2inv1,v2andparameter{p_type=p_type;p_name=p_name}=letarg1=type_p_typeinletarg2=optionnamep_namein(arg1,arg2)andstruct_kind=function|Struct->G.OT_StructName|Union->G.OT_UnionNameandexpr=function|Intv1->letv1=wrapstringv1inG.L(G.Intv1)|Floatv1->letv1=wrapstringv1inG.L(G.Floatv1)|Stringv1->letv1=wrapstringv1inG.L(G.Stringv1)|Charv1->letv1=wrapstringv1inG.L(G.Charv1)|Idv1->letv1=namev1inG.Name((v1,G.empty_name_info),G.empty_id_info())|Ellipsesv1->letv1=infov1inG.Ellipses(v1)|Call((v1,v2))->letv1=exprv1andv2=listargumentv2inG.Call(v1,v2)|Assign((v1,v2,v3))->letv1=wrapassignOpv1andv2=exprv2andv3=exprv3in(matchv1with|None,_->G.Assign(v2,v3)|Someop,tok->G.AssignOp(v2,(op,tok),v3))|ArrayAccess((v1,v2))->letv1=exprv1andv2=exprv2inG.ArrayAccess(v1,v2)|RecordPtAccess((v1,v2))->letv1=exprv1andv2=namev2inG.ObjAccess(G.DeRefv1,v2)|Cast((v1,v2))->letv1=type_v1andv2=exprv2inG.Cast(v1,v2)|Postfix((v1,(v2,v3)))->letv1=exprv1andv2=fixOpv2inG.Call(G.IdSpecial(G.IncrDecr(v2,G.Postfix),v3),[G.Argv1])|Infix((v1,(v2,v3)))->letv1=exprv1andv2=fixOpv2inG.Call(G.IdSpecial(G.IncrDecr(v2,G.Prefix),v3),[G.Argv1])|Unary((v1,v2))->letv1=exprv1andv2=unaryOpv2inv2v1|Binary((v1,(v2,tok),v3))->letv1=exprv1andv2=binaryOpv2andv3=exprv3inG.Call(G.IdSpecial(G.ArithOpv2,tok),[G.Argv1;G.Argv3])|CondExpr((v1,v2,v3))->letv1=exprv1andv2=exprv2andv3=exprv3inG.Conditional(v1,v2,v3)|Sequence((v1,v2))->letv1=exprv1andv2=exprv2inG.Seq[v1;v2]|SizeOfv1->letv1=eitherexprtype_v1inG.Call(G.IdSpecial(G.Sizeof,fake_info()),(matchv1with|Lefte->[G.Arge]|Rightt->[G.ArgTypet]))|ArrayInitv1->letv1=list(fun(v1,v2)->letv1=optionexprv1andv2=exprv2in(matchv1with|None->v2|Somee->G.OtherExpr(G.OE_ArrayInitDesignator,[G.Ee;G.Ev2])))v1inG.Container(G.Array,v1)|RecordInitv1->letv1=list(fun(v1,v2)->letv1=namev1andv2=exprv2inletentity=G.basic_entityv1[]inletvdef={G.vinit=Somev2;vtype=None}inG.FieldVar(entity,vdef))v1inG.Recordv1|GccConstructor((v1,v2))->letv1=type_v1andv2=exprv2inG.OtherExpr(G.OE_GccConstructor,[G.Tv1;G.Ev2])andargumentv=letv=exprvinG.Argvandconst_exprv=exprvletrecstmt=function|ExprStv1->letv1=exprv1inG.ExprStmtv1|Blockv1->letv1=liststmtv1inG.Blockv1|If((v1,v2,v3))->letv1=exprv1andv2=stmtv2andv3=stmtv3inG.If(v1,v2,v3)|Switch((v1,v2))->letv1=exprv1andv2=listcasev2inG.Switch(v1,v2)|While((v1,v2))->letv1=exprv1andv2=stmtv2inG.While(v1,v2)|DoWhile((v1,v2))->letv1=stmtv1andv2=exprv2inG.DoWhile(v1,v2)|For((v1,v2,v3,v4))->letv1=optionexprv1andv2=optionexprv2andv3=optionexprv3andv4=stmtv4inletheader=G.ForClassic([G.ForInitExpr(G.opt_to_nopv1)],G.opt_to_nopv2,G.opt_to_nopv3)inG.For(header,v4)|Returnv1->letv1=optionexprv1inG.Return(G.opt_to_nopv1)|Continue->G.ContinueNone|Break->G.BreakNone|Label((v1,v2))->letv1=namev1andv2=stmtv2inG.Label(v1,v2)|Gotov1->letv1=namev1inG.Gotov1|Varsv1->letv1=listvar_declv1inG.stmt1(v1|>List.map(funv->G.DefStmtv))|Asmv1->letv1=listexprv1inG.OtherStmt(G.OS_Asm,v1|>List.map(fune->G.Ee))andcase=function|Case((v1,v2))->letv1=exprv1andv2=liststmtv2in[G.Casev1],G.stmt1v2|Defaultv1->letv1=liststmtv1in[G.Default],G.stmt1v1andvar_decl{v_name=xname;v_type=xtype;v_storage=xstorage;v_init=init}=letv1=namexnameinletv2=type_xtypeinletv3=storagexstorageinletv4=optioninitialiserinitinletentity=G.basic_entityv1v3inentity,G.VarDef{G.vinit=v4;vtype=Somev2}andinitialiserv=exprvandstorage=function|Extern->[G.Extern]|Static->[G.Static]|DefaultStorage->[]letfunc_def{f_name=f_name;f_type=f_type;f_body=f_body;f_static=f_static}=letv1=namef_nameinlet(ret,params)=function_typef_typeinletv3=liststmtf_bodyinletv4=iff_staticthen[G.Static]else[]inletentity=G.basic_entityv1v4inentity,G.FuncDef{G.fparams=params|>List.map(fun(t,nameopt)->G.ParamClassic{(G.basic_param(nameopt|>G.opt_to_name))withG.ptype=Somet;});frettype=Someret;fbody=G.stmt1v3;}letrecstruct_def{s_name=s_name;s_kind=s_kind;s_flds=s_flds}=letv1=names_nameinletv3=listfield_defs_fldsinletentity=G.basic_entityv1[]in(matchs_kindwith|Struct->letfields=v3|>List.map(fun(n,t)->G.basic_fieldn(Somet))inentity,G.TypeDef({G.tbody=G.AndTypefields})|Union->letctors=v3|>List.map(fun(n,t)->G.OrUnion(n,t))inentity,G.TypeDef({G.tbody=G.OrTypectors}))andfield_def{fld_name=fld_name;fld_type=fld_type}=letv1=optionnamefld_nameinletv2=type_fld_typeinG.opt_to_namev1,v2letenum_def(v1,v2)=letv1=namev1andv2=list(fun(v1,v2)->letv1=namev1andv2=optionconst_exprv2inv1,v2)v2inletentity=G.basic_entityv1[]inletors=v2|>List.map(fun(n,eopt)->G.OrEnum(n,G.opt_to_nopeopt))inentity,G.TypeDef({G.tbody=G.OrTypeors})lettype_def(v1,v2)=letv1=namev1andv2=type_v2inletentity=G.basic_entityv1[]inentity,G.TypeDef({G.tbody=G.AliasTypev2})letdefine_body=function|CppExprv1->letv1=exprv1inG.Ev1|CppStmtv1->letv1=stmtv1inG.Sv1lettoplevel=function|Includev1->letv1=wrapstringv1inG.IDir(G.ImportAs(G.FileNamev1,None))|Define((v1,v2))->letv1=namev1andv2=define_bodyv2inletent=G.basic_entityv1[]inG.IDef(ent,G.MacroDef{G.macroparams=[];G.macrobody=[v2]})|Macro((v1,v2,v3))->letv1=namev1andv2=listnamev2andv3=define_bodyv3inletent=G.basic_entityv1[]inG.IDef(ent,G.MacroDef{G.macroparams=v2;G.macrobody=[v3]})|StructDefv1->letv1=struct_defv1inG.IDefv1|TypeDefv1->letv1=type_defv1inG.IDefv1|EnumDefv1->letv1=enum_defv1inG.IDefv1|FuncDefv1->letv1=func_defv1inG.IDefv1|Globalv1->letv1=var_declv1inG.IDefv1|Prototypev1->letv1=func_defv1inG.IDefv1letprogramv=listtoplevelvletany=function|Exprv1->letv1=exprv1inG.Ev1|Stmtv1->letv1=stmtv1inG.Sv1|Stmtsv1->letv1=liststmtv1inG.Ssv1|Typev1->letv1=type_v1inG.Tv1|Toplevelv1->letv1=toplevelv1inG.Iv1|Programv1->letv1=programv1inG.Prv1