a blE@s ddlmZGdddeZdS))c_astc@s6eZdZdZdddZddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZdddddddddddd d d!d!d"d"d"d#Zd$d%Zd&d'Zd(d)Zd*d+Zdd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Zd@dAZdBdCZdDdEZ dFdGZ!dHdIZ"dJdKZ#dLdMZ$dNdOZ%dPdQZ&dRdSZ'dTdUZ(dVdWZ)dXdYZ*dZd[Z+d\d]Z,d^d_Z-d`daZ.dbdcZ/dddeZ0dfdgZ1dhdiZ2djdkZ3dldmZ4dndoZ5dpdqZ6drdsZ7dtduZ8dvdwZ9dxdyZ:dzd{Z;d|d}ZgdfddZ?ddZ@ddZAddZBdS) CGeneratorz Uses the same visitor pattern as c_ast.NodeVisitor, but modified to return a value from each visit method, using string accumulation in generic_visit. FcCsd|_||_dS)z Constructs C-code generator reduce_parentheses: if True, eliminates needless parentheses on binary operators N) indent_levelreduce_parentheses)selfrr'z+CGenerator.generic_visit..)joinchildren)rrrr r r#szCGenerator.generic_visitcCs|jSr)valuernrrr visit_Constant)szCGenerator.visit_ConstantcCs|jSrnamer!rrr visit_ID,szCGenerator.visit_IDcCsd}|jr|d|j7}|S)Nz#pragmar )string)rr"retrrr visit_Pragma/szCGenerator.visit_PragmacCs$||j}|d||jdS)N[])_parenthesize_unless_simpler%rZ subscript)rr"Zarrrefrrr visit_ArrayRef5s zCGenerator.visit_ArrayRefcCs"||j}||j||jSr)r,r%typerfield)rr"Zsrefrrr visit_StructRef9s zCGenerator.visit_StructRefcCs$||j}|d||jdS)N())r,r%rargs)rr"Zfrefrrr visit_FuncCall=s zCGenerator.visit_FuncCallcCs\|jdkrd||jS||j}|jdkr8d|S|jdkrJd|Sd|j|fSdS)Nsizeofz sizeof(%s)zp++z%s++zp--z%s--z%s%s)oprexprr,)rr"operandrrr visit_UnaryOpAs    zCGenerator.visit_UnaryOprr )z||z&&|^&z==z!=>z>=>z<<+-*/%cs@jfdd}jfdd}d|j|fS)Ncs6|p2jo2t|tjo2j|jjjk Sr_is_simple_noder isinstancerBinaryOpprecedence_mapr6dr"rrr ks z+CGenerator.visit_BinaryOp..cs6|p2jo2t|tjo2j|jjjk SrrLrQrSrr rTws %s %s %s)_parenthesize_ifleftrightr6)rr"Zlval_strrval_strrrSr visit_BinaryOp_s    zCGenerator.visit_BinaryOpcCs*||jdd}d||j|j|fS)NcSs t|tjSr)rNr Assignment)r"rrr rTrz-CGenerator.visit_Assignment..rU)rVZrvaluerZlvaluer6)rr"rYrrr visit_Assignment|s zCGenerator.visit_AssignmentcCs d|jSr )rnamesr!rrr visit_IdentifierTypeszCGenerator.visit_IdentifierTypecCsJt|tjrd||dSt|tjr.)rdeclslenrrr"rgrr r visit_DeclLists  zCGenerator.visit_DeclListcCs2d}|jr|d|jd7}|||j7}|S)Nrr )storager_generate_typer.rnrrr visit_TypedefszCGenerator.visit_TypedefcCs,d|j|jddd}|d||jS)Nr1F emit_declnamer2r )rqZto_typer,r7rnrrr visit_CastszCGenerator.visit_CastcCs*g}|jD]}|||q d|SNriexprsappendrbrrr"Zvisited_subexprsr7rrr visit_ExprLists zCGenerator.visit_ExprListcCs*g}|jD]}|||q d|Srvrwrzrrr visit_InitLists zCGenerator.visit_InitListcCs|j|ddS)Nenumr$_generate_struct_union_enumr!rrr visit_EnumszCGenerator.visit_EnumcCsd||jS)Nz _Alignas({}))formatr alignmentr!rrr visit_AlignasszCGenerator.visit_AlignascCs<|jsdj||jdSdj||j||jdSdS)Nz{indent}{name}, )indentr%z{indent}{name} = {value}, )rr%r )r rrr%rr!rrr visit_Enumerators zCGenerator.visit_Enumeratorcsj|j}d_|j}|jrVdfdd|jD}|d|d|dS|d|dSdS)Nr; c3s|]}|VqdSrr)rpr rr rrz+CGenerator.visit_FuncDef.. )rrkrbodyZ param_declsr)rr"rkrZknrdeclsrr r visit_FuncDefs  zCGenerator.visit_FuncDefcCsbd}|jD]R}t|tjr*|||7}q t|tjrJ|||d7}q |||d7}q |S)Nrrr)extrNrZFuncDefrZPragma)rr"rgrrrr visit_FileASTs   zCGenerator.visit_FileASTcs`d}jd7_|jr>|dfdd|jD7}jd8_|d7}|S)N{ r:rc3s|]}|VqdSr_generate_stmt)rstmtr rr rrz,CGenerator.visit_Compound..z} )rrZ block_itemsrrnrr r visit_Compounds zCGenerator.visit_CompoundcCs$d||jd||jdS)Nr1z){r`)rr.rer!rrr visit_CompoundLiteralsz CGenerator.visit_CompoundLiteralcCsdS)N;rr!rrr visit_EmptyStatementszCGenerator.visit_EmptyStatementcsdfdd|jDS)Nric3s|]}|VqdSrr)rparamr rr rrz-CGenerator.visit_ParamList..)rparamsr!rr r visit_ParamListszCGenerator.visit_ParamListcCs&d}|jr|d||j7}|dS)Nreturnr r)r7rrnrrr visit_ReturnszCGenerator.visit_ReturncCsdS)Nzbreak;rr!rrr visit_BreakszCGenerator.visit_BreakcCsdS)Nz continue;rr!rrr visit_ContinueszCGenerator.visit_ContinuecCsHd||jd}|d||jd7}|d||jd7}|S)Nr1z) ? z) : r2)rbcondiftrueiffalsernrrr visit_TernaryOpszCGenerator.visit_TernaryOpcCsdd}|jr|||j7}|d7}||j|jdd7}|jr`||d7}||j|jdd7}|S)Nzif () T add_indentzelse )rrrrrrrnrrr visit_IfszCGenerator.visit_IfcCs~d}|jr|||j7}|d7}|jr<|d||j7}|d7}|jr^|d||j7}|d7}||j|jdd7}|S)Nzfor (rr rTr)rerrnextrrrnrrr visit_For szCGenerator.visit_ForcCs:d}|jr|||j7}|d7}||j|jdd7}|S)Nwhile (rTr)rrrrrnrrr visit_Whiles zCGenerator.visit_WhilecCsJd}||j|jdd7}||d7}|jr>|||j7}|d7}|S)Nzdo Trrz);)rrrrrrnrrr visit_DoWhiles zCGenerator.visit_DoWhilecCs>d}|||j7}|jr2|d7}|||j7}|d7}|S)Nz_Static_assert(,r2)rrmessagernrrr visit_StaticAssert$szCGenerator.visit_StaticAssertcCs,d||jd}||j|jdd7}|S)Nzswitch (rTr)rrrrrnrrr visit_Switch-szCGenerator.visit_SwitchcCs6d||jd}|jD]}||j|dd7}q|S)Nzcase : Tr)rr7stmtsrrr"rgrrrr visit_Case2s zCGenerator.visit_CasecCs&d}|jD]}||j|dd7}q |S)Nz default: Tr)rrrrrr visit_Default8s zCGenerator.visit_DefaultcCs|jd||jS)Nr)r%rrr!rrr visit_Label>szCGenerator.visit_LabelcCsd|jdS)Nzgoto rr$r!rrr visit_GotoAszCGenerator.visit_GotocCsdS)Nz...rr!rrr visit_EllipsisParamDszCGenerator.visit_EllipsisParamcCs ||dS)Nstructr~r!rrr visit_StructGszCGenerator.visit_StructcCs ||jSr)rqr.r!rrr visit_TypenameJszCGenerator.visit_TypenamecCs ||dS)Nunionr~r!rrr visit_UnionMszCGenerator.visit_UnioncCsZd}|jD]6}t|tjr*|d|j7}q |d||d7}q |d||j7}|S)Nr.r*r+rc)r%rNrIDrrbr7)rr"rgr%rrr visit_NamedInitializerPs  z!CGenerator.visit_NamedInitializercCs ||Srrqr!rrr visit_FuncDeclZszCGenerator.visit_FuncDeclcCs|j|ddSNFrsrr!rrr visit_ArrayDecl]szCGenerator.visit_ArrayDeclcCs|j|ddSrrr!rrr visit_TypeDecl`szCGenerator.visit_TypeDeclcCs|j|ddSrrr!rrr visit_PtrDeclcszCGenerator.visit_PtrDeclcCs|dvr|j}|j}n(|dks"J|jdur0dn|jj}|j}|d|jpLd}|dur|d7}||7}|jd7_|d7}|||7}|jd8_||d 7}|S) zq Generates code for structs, unions, and enums. name should be 'struct', 'union', or 'enum'. )rrr}Nr rrr:rr`)rl_generate_struct_union_bodyvaluesZ enumerators_generate_enum_bodyr%rr)rr"r%membersZ body_functionrgrrr rfs    z&CGenerator._generate_struct_union_enumcsdfdd|DS)Nrc3s|]}|VqdSrrrjr rr rrz9CGenerator._generate_struct_union_body..rrrrr r r~sz&CGenerator._generate_struct_union_bodycs$dfdd|DdddS)Nrc3s|]}|VqdSrr)rr r rr rrz1CGenerator._generate_enum_body..rrrrr r rszCGenerator._generate_enum_bodycCst|}|r|jd7_|}|r4|jd8_|tjtjtjtjtjtj tj tj tj tj tjtjtjf vr|||dS|tjfvr||S|tjfvr|||S|||dSdS)z Generation from a statement node. This method exists as a wrapper for individual visit_* methods to handle different treatment of some statements in this context. r:rrN)r.rrrDeclr[ZCastUnaryOprOZ TernaryOpFuncCallArrayRef StructRefConstantrZTypedefrarZCompoundIf)rr"rtyprrrr rs    zCGenerator._generate_stmtcCsfd}|jrd|jd}|jr4|d|jd7}|jrR|||jdd7}|||j7}|S)z& Generation from a Decl node. rr r)Zfuncspecrrpalignrrqr.rnrrr rds zCGenerator._generate_declTc Cs t|}|tjkrd}|jr2|d|jd7}|||j7}|jrR|rR|jnd}t|D]\}}t|tj r|dkrt||dtj rd|d}|d7}|j r|d|j d7}|||j d7}q^t|tj r(|dkrt||dtj rd|d}|d||jd7}q^t|tj r^|jr`d d|j|rVd|ndf}q^d |}q^|r||d|7}|S|tjkr||jS|tjkr|j|j|d S|tjkrd|jdS|tj tj tj fvr|j|j||g|d S||Sd S) z Recursive generation from a type node. n is the type node. modifiers collects the PtrDecl, ArrayDecl and FuncDecl modifiers encountered on the way down to a TypeDecl, to allow proper generation from it. rr rrr1r2r*r+z* %s%srIrsN)r.rZTypeDeclZqualsrrZdeclname enumeraterNZ ArrayDeclZPtrDeclZ dim_qualsdimZFuncDeclr3rrdZTypenamerqZIdentifierTyper]) rr" modifiersrtrrgZnstrimodifierrrr rqsR            zCGenerator._generate_typecCs&||}||rd|dS|SdS)z Visits 'n' and returns its string representation, parenthesized if the condition function applied to the node returns True. r1r2N)rb)rr" conditionrgrrr rVs  zCGenerator._parenthesize_ifcs|fddS)z. Common use case for _parenthesize_if cs | Sr)rMrQr rr rTrz8CGenerator._parenthesize_unless_simple..)rVr!rr r r,sz&CGenerator._parenthesize_unless_simplecCst|tjtjtjtjtjfS)z~ Returns True for nodes that are "simple" - i.e. nodes that always have higher precedence than operators. )rNrrrrrrr!rrr rMszCGenerator._is_simple_nodeN)F)F)F)Cr __module__ __qualname____doc__r rrrr#r&r)r-r0r4r9rPrZr\r^rbrhrorrrur{r|rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrdrqrVr,rMrrrr r s            5 rN)rrobjectrrrrr  s