// Copyright (c) 2014 Dropbox, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef PYSTON_CORE_AST_H #define PYSTON_CORE_AST_H #include <cassert> #include <cstdlib> #include <stdint.h> #include <vector> #include <string> namespace pyston { namespace AST_TYPE { // These are in a pretty random order (started off alphabetical but then I had to add more). // These can be changed freely as long as parse_ast.py is also updated enum AST_TYPE { alias = 1, arguments = 2, Assert = 3, Assign = 4, Attribute = 5, AugAssign = 6, BinOp = 7, BoolOp = 8, Call = 9, ClassDef = 10, Compare = 11, comprehension = 12, Delete = 13, Dict = 14, Exec = 16, ExceptHandler = 17, ExtSlice = 18, Expr = 19, For = 20, FunctionDef = 21, GeneratorExp = 22, Global = 23, If = 24, IfExp = 25, Import = 26, ImportFrom = 27, Index = 28, keyword = 29, Lambda = 30, List = 31, ListComp = 32, Module = 33, Num = 34, Name = 35, Pass = 37, Pow = 38, Print = 39, Raise = 40, Repr = 41, Return = 42, Slice = 44, Str = 45, Subscript = 46, TryExcept = 47, TryFinally = 48, Tuple = 49, UnaryOp = 50, With = 51, While = 52, Yield = 53, Store = 54, Load = 55, Param = 56, Not = 57, In = 58, Is = 59, IsNot = 60, Or = 61, And = 62, Eq = 63, NotEq = 64, NotIn = 65, GtE = 66, Gt = 67, Mod = 68, Add = 69, Continue = 70, Lt = 71, LtE = 72, Break = 73, Sub = 74, Del = 75, Mult = 76, Div = 77, USub = 78, BitAnd = 79, BitOr = 80, BitXor = 81, RShift = 82, LShift = 83, Invert = 84, UAdd = 85, FloorDiv = 86, DictComp = 15, Set = 43, // Pseudo-nodes that are specific to this compiler: Branch = 200, Jump = 201, ClsAttribute = 202, AugBinOp = 203, }; }; class ASTVisitor; class ExprVisitor; class StmtVisitor; class AST_keyword; class AST { public: const AST_TYPE::AST_TYPE type; uint32_t lineno, col_offset; virtual void accept(ASTVisitor *v) = 0; AST(AST_TYPE::AST_TYPE type) : type(type) {} }; class AST_expr : public AST { public: virtual void* accept_expr(ExprVisitor *v) = 0; AST_expr(AST_TYPE::AST_TYPE type) : AST(type) {} }; class AST_stmt : public AST { public: virtual void accept_stmt(StmtVisitor *v) = 0; AST_stmt(AST_TYPE::AST_TYPE type) : AST(type) {} }; class AST_alias : public AST { public: std::string name, asname; virtual void accept(ASTVisitor *v); AST_alias() : AST(AST_TYPE::alias) {} }; class AST_arguments : public AST { public: // no lineno, col_offset attributes std::vector<AST_expr*> args, defaults; AST_expr *kwarg; std::string vararg; virtual void accept(ASTVisitor *v); AST_arguments() : AST(AST_TYPE::arguments) {} }; class AST_Assign : public AST_stmt { public: std::vector<AST_expr*> targets; AST_expr* value; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_Assign() : AST_stmt(AST_TYPE::Assign) {} }; class AST_AugAssign : public AST_stmt { public: AST_expr* value; AST_expr* target; AST_TYPE::AST_TYPE op_type; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_AugAssign() : AST_stmt(AST_TYPE::AugAssign) {} }; class AST_AugBinOp : public AST_expr { public: AST_TYPE::AST_TYPE op_type; AST_expr *left, *right; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_AugBinOp() : AST_expr(AST_TYPE::AugBinOp) {} }; class AST_Attribute : public AST_expr { public: AST_expr* value; AST_TYPE::AST_TYPE ctx_type; std::string attr; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_Attribute() : AST_expr(AST_TYPE::Attribute) {} }; class AST_BinOp : public AST_expr { public: AST_TYPE::AST_TYPE op_type; AST_expr *left, *right; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_BinOp() : AST_expr(AST_TYPE::BinOp) {} }; class AST_BoolOp : public AST_expr { public: AST_TYPE::AST_TYPE op_type; std::vector<AST_expr*> values; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_BoolOp() : AST_expr(AST_TYPE::BoolOp) {} }; class AST_Break : public AST_stmt { public: virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_Break() : AST_stmt(AST_TYPE::Break) {} }; class AST_Call : public AST_expr { public: AST_expr *starargs, *kwargs, *func; std::vector<AST_expr*> args; std::vector<AST_keyword*> keywords; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_Call() : AST_expr(AST_TYPE::Call) {} static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Call; }; class AST_Compare : public AST_expr { public: std::vector<AST_TYPE::AST_TYPE> ops; std::vector<AST_expr*> comparators; AST_expr* left; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_Compare() : AST_expr(AST_TYPE::Compare) {} }; class AST_comprehension : public AST { public: AST_expr* target; AST_expr* iter; std::vector<AST_expr*> ifs; virtual void accept(ASTVisitor *v); AST_comprehension() : AST(AST_TYPE::comprehension) {} static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::comprehension; }; class AST_ClassDef : public AST_stmt { public: virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); std::vector<AST_expr*> bases, decorator_list; std::vector<AST_stmt*> body; std::string name; AST_ClassDef() : AST_stmt(AST_TYPE::ClassDef) {} }; class AST_Continue : public AST_stmt { public: virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_Continue() : AST_stmt(AST_TYPE::Continue) {} }; class AST_Dict : public AST_expr { public: std::vector<AST_expr*> keys, values; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_Dict() : AST_expr(AST_TYPE::Dict) {} }; class AST_Expr : public AST_stmt { public: AST_expr* value; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_Expr() : AST_stmt(AST_TYPE::Expr) {} }; class AST_For : public AST_stmt { public: const static int TYPE = AST_TYPE::For; std::vector<AST_stmt*> body, orelse; AST_expr *target, *iter; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_For() : AST_stmt(AST_TYPE::For) {} }; class AST_FunctionDef : public AST_stmt { public: const static int TYPE = AST_TYPE::FunctionDef; std::vector<AST_stmt*> body; std::vector<AST_expr*> decorator_list; std::string name; AST_arguments *args; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_FunctionDef() : AST_stmt(AST_TYPE::FunctionDef) {} }; class AST_Global : public AST_stmt { public: std::vector<std::string> names; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_Global() : AST_stmt(AST_TYPE::Global) {} }; class AST_If : public AST_stmt { public: std::vector<AST_stmt*> body, orelse; AST_expr* test; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_If() : AST_stmt(AST_TYPE::If) {} }; class AST_IfExp : public AST_expr { public: const static AST_TYPE::AST_TYPE TYPE = AST_TYPE::IfExp; AST_expr *body, *test, *orelse; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_IfExp() : AST_expr(AST_TYPE::IfExp) {} }; class AST_Import : public AST_stmt { public: std::vector<AST_alias*> names; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_Import() : AST_stmt(AST_TYPE::Import) {} }; class AST_Index : public AST_expr { public: const static AST_TYPE::AST_TYPE TYPE = AST_TYPE::Index; AST_expr *value; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_Index() : AST_expr(AST_TYPE::Index) {} }; class AST_keyword : public AST { public: // no lineno, col_offset attributes AST_expr *value; std::string arg; virtual void accept(ASTVisitor *v); AST_keyword() : AST(AST_TYPE::keyword) {} static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::keyword; }; class AST_List : public AST_expr { public: const static AST_TYPE::AST_TYPE TYPE = AST_TYPE::List; std::vector<AST_expr*> elts; AST_TYPE::AST_TYPE ctx_type; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_List() : AST_expr(AST_TYPE::List) {} }; class AST_ListComp : public AST_expr { public: const static AST_TYPE::AST_TYPE TYPE = AST_TYPE::ListComp; std::vector<AST_comprehension*> generators; AST_expr* elt; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_ListComp() : AST_expr(AST_TYPE::ListComp) {} }; class AST_Module : public AST { public: // no lineno, col_offset attributes const static AST_TYPE::AST_TYPE TYPE = AST_TYPE::Module; std::vector<AST_stmt*> body; virtual void accept(ASTVisitor *v); AST_Module() : AST(AST_TYPE::Module) {} }; class AST_Name : public AST_expr { public: const static AST_TYPE::AST_TYPE TYPE = AST_TYPE::Name; AST_TYPE::AST_TYPE ctx_type; std::string id; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_Name() : AST_expr(AST_TYPE::Name) {} }; class AST_Num : public AST_expr { public: enum NumType { // These values must correspond to the values in parse_ast.py INT = 0x10, FLOAT = 0x20, } num_type; union { int64_t n_int; double n_float; }; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_Num() : AST_expr(AST_TYPE::Num) {} }; class AST_Pass : public AST_stmt { public: virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_Pass() : AST_stmt(AST_TYPE::Pass) {} }; class AST_Print : public AST_stmt { public: AST_expr* dest; bool nl; std::vector<AST_expr*> values; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_Print() : AST_stmt(AST_TYPE::Print) {} }; class AST_Return : public AST_stmt { public: AST_expr* value; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_Return() : AST_stmt(AST_TYPE::Return) {} }; class AST_Slice : public AST_expr { public: AST_expr *lower, *upper, *step; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_Slice() : AST_expr(AST_TYPE::Slice) {} }; class AST_Str : public AST_expr { public: std::string s; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_Str() : AST_expr(AST_TYPE::Str) {} }; class AST_Subscript : public AST_expr { public: AST_expr *value, *slice; AST_TYPE::AST_TYPE ctx_type; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_Subscript() : AST_expr(AST_TYPE::Subscript) {} }; class AST_Tuple : public AST_expr { public: std::vector<AST_expr*> elts; AST_TYPE::AST_TYPE ctx_type; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_Tuple() : AST_expr(AST_TYPE::Tuple) {} }; class AST_UnaryOp : public AST_expr { public: AST_expr *operand; AST_TYPE::AST_TYPE op_type; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_UnaryOp() : AST_expr(AST_TYPE::UnaryOp) {} }; class AST_While : public AST_stmt { public: AST_expr *test; std::vector<AST_stmt*> body, orelse; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_While() : AST_stmt(AST_TYPE::While) {} }; class AST_With : public AST_stmt { public: AST_expr *optional_vars, *context_expr; std::vector<AST_stmt*> body; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_With() : AST_stmt(AST_TYPE::With) {} }; // AST pseudo-nodes that will get added during CFG-construction. These don't exist in the input AST, but adding them in // lets us avoid creating a completely new IR for this phase class CFGBlock; class AST_Branch : public AST_stmt { public: AST_expr *test; CFGBlock *iftrue, *iffalse; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_Branch() : AST_stmt(AST_TYPE::Branch) {} }; class AST_Jump : public AST_stmt { public: CFGBlock *target; virtual void accept(ASTVisitor *v); virtual void accept_stmt(StmtVisitor *v); AST_Jump() : AST_stmt(AST_TYPE::Jump) {} }; class AST_ClsAttribute : public AST_expr { public: AST_expr *value; std::string attr; virtual void accept(ASTVisitor *v); virtual void* accept_expr(ExprVisitor *v); AST_ClsAttribute() : AST_expr(AST_TYPE::ClsAttribute) {} }; class ASTVisitor { protected: public: virtual ~ASTVisitor() {} virtual bool visit_alias(AST_alias *node) { assert(0); abort(); } virtual bool visit_arguments(AST_arguments *node) { assert(0); abort(); } virtual bool visit_assign(AST_Assign *node) { assert(0); abort(); } virtual bool visit_augassign(AST_AugAssign *node) { assert(0); abort(); } virtual bool visit_augbinop(AST_AugBinOp *node) { assert(0); abort(); } virtual bool visit_attribute(AST_Attribute *node) { assert(0); abort(); } virtual bool visit_binop(AST_BinOp *node) { assert(0); abort(); } virtual bool visit_boolop(AST_BoolOp *node) { assert(0); abort(); } virtual bool visit_break(AST_Break *node) { assert(0); abort(); } virtual bool visit_call(AST_Call *node) { assert(0); abort(); } virtual bool visit_clsattribute(AST_ClsAttribute *node) { assert(0); abort(); } virtual bool visit_compare(AST_Compare *node) { assert(0); abort(); } virtual bool visit_comprehension(AST_comprehension *node) { assert(0); abort(); } virtual bool visit_classdef(AST_ClassDef *node) { assert(0); abort(); } virtual bool visit_continue(AST_Continue *node) { assert(0); abort(); } virtual bool visit_dict(AST_Dict *node) { assert(0); abort(); } virtual bool visit_expr(AST_Expr *node) { assert(0); abort(); } virtual bool visit_for(AST_For *node) { assert(0); abort(); } virtual bool visit_functiondef(AST_FunctionDef *node) { assert(0); abort(); } virtual bool visit_global(AST_Global *node) { assert(0); abort(); } virtual bool visit_if(AST_If *node) { assert(0); abort(); } virtual bool visit_ifexp(AST_IfExp *node) { assert(0); abort(); } virtual bool visit_import(AST_Import *node) { assert(0); abort(); } virtual bool visit_index(AST_Index *node) { assert(0); abort(); } virtual bool visit_keyword(AST_keyword *node) { assert(0); abort(); } virtual bool visit_list(AST_List *node) { assert(0); abort(); } virtual bool visit_listcomp(AST_ListComp *node) { assert(0); abort(); } virtual bool visit_module(AST_Module *node) { assert(0); abort(); } virtual bool visit_name(AST_Name *node) { assert(0); abort(); } virtual bool visit_num(AST_Num *node) { assert(0); abort(); } virtual bool visit_pass(AST_Pass *node) { assert(0); abort(); } virtual bool visit_print(AST_Print *node) { assert(0); abort(); } virtual bool visit_return(AST_Return *node) { assert(0); abort(); } virtual bool visit_slice(AST_Slice *node) { assert(0); abort(); } virtual bool visit_str(AST_Str *node) { assert(0); abort(); } virtual bool visit_subscript(AST_Subscript *node) { assert(0); abort(); } virtual bool visit_tuple(AST_Tuple *node) { assert(0); abort(); } virtual bool visit_unaryop(AST_UnaryOp *node) { assert(0); abort(); } virtual bool visit_while(AST_While *node) { assert(0); abort(); } virtual bool visit_with(AST_With *node) { assert(0); abort(); } virtual bool visit_branch(AST_Branch *node) { assert(0); abort(); } virtual bool visit_jump(AST_Jump *node) { assert(0); abort(); } }; class NoopASTVisitor : public ASTVisitor { protected: public: virtual ~NoopASTVisitor() {} virtual bool visit_alias(AST_alias *node) { return false; } virtual bool visit_arguments(AST_arguments *node) { return false; } virtual bool visit_assign(AST_Assign *node) { return false; } virtual bool visit_augassign(AST_AugAssign *node) { return false; } virtual bool visit_augbinop(AST_AugBinOp *node) { return false; } virtual bool visit_attribute(AST_Attribute *node) { return false; } virtual bool visit_binop(AST_BinOp *node) { return false; } virtual bool visit_boolop(AST_BoolOp *node) { return false; } virtual bool visit_break(AST_Break *node) { return false; } virtual bool visit_call(AST_Call *node) { return false; } virtual bool visit_clsattribute(AST_ClsAttribute *node) { return false; } virtual bool visit_compare(AST_Compare *node) { return false; } virtual bool visit_comprehension(AST_comprehension *node) { return false; } virtual bool visit_classdef(AST_ClassDef *node) { return false; } virtual bool visit_continue(AST_Continue *node) { return false; } virtual bool visit_dict(AST_Dict *node) { return false; } virtual bool visit_expr(AST_Expr *node) { return false; } virtual bool visit_for(AST_For *node) { return false; } virtual bool visit_functiondef(AST_FunctionDef *node) { return false; } virtual bool visit_global(AST_Global *node) { return false; } virtual bool visit_if(AST_If *node) { return false; } virtual bool visit_ifexp(AST_IfExp *node) { return false; } virtual bool visit_import(AST_Import *node) { return false; } virtual bool visit_index(AST_Index *node) { return false; } virtual bool visit_keyword(AST_keyword *node) { return false; } virtual bool visit_list(AST_List *node) { return false; } virtual bool visit_listcomp(AST_ListComp *node) { return false; } virtual bool visit_module(AST_Module *node) { return false; } virtual bool visit_name(AST_Name *node) { return false; } virtual bool visit_num(AST_Num *node) { return false; } virtual bool visit_pass(AST_Pass *node) { return false; } virtual bool visit_print(AST_Print *node) { return false; } virtual bool visit_return(AST_Return *node) { return false; } virtual bool visit_slice(AST_Slice *node) { return false; } virtual bool visit_str(AST_Str *node) { return false; } virtual bool visit_subscript(AST_Subscript *node) { return false; } virtual bool visit_tuple(AST_Tuple *node) { return false; } virtual bool visit_unaryop(AST_UnaryOp *node) { return false; } virtual bool visit_while(AST_While *node) { return false; } virtual bool visit_with(AST_With *node) { return false; } virtual bool visit_branch(AST_Branch *node) { return false; } virtual bool visit_jump(AST_Jump *node) { return false; } }; class ExprVisitor { protected: public: virtual ~ExprVisitor() {} virtual void* visit_augbinop(AST_AugBinOp *node) { assert(0); abort(); } virtual void* visit_attribute(AST_Attribute *node) { assert(0); abort(); } virtual void* visit_binop(AST_BinOp *node) { assert(0); abort(); } virtual void* visit_boolop(AST_BoolOp *node) { assert(0); abort(); } virtual void* visit_call(AST_Call *node) { assert(0); abort(); } virtual void* visit_clsattribute(AST_ClsAttribute *node) { assert(0); abort(); } virtual void* visit_compare(AST_Compare *node) { assert(0); abort(); } virtual void* visit_dict(AST_Dict *node) { assert(0); abort(); } virtual void* visit_ifexp(AST_IfExp *node) { assert(0); abort(); } virtual void* visit_index(AST_Index *node) { assert(0); abort(); } virtual void* visit_list(AST_List *node) { assert(0); abort(); } virtual void* visit_listcomp(AST_ListComp *node) { assert(0); abort(); } virtual void* visit_name(AST_Name *node) { assert(0); abort(); } virtual void* visit_num(AST_Num *node) { assert(0); abort(); } virtual void* visit_slice(AST_Slice *node) { assert(0); abort(); } virtual void* visit_str(AST_Str *node) { assert(0); abort(); } virtual void* visit_subscript(AST_Subscript *node) { assert(0); abort(); } virtual void* visit_tuple(AST_Tuple *node) { assert(0); abort(); } virtual void* visit_unaryop(AST_UnaryOp *node) { assert(0); abort(); } }; class StmtVisitor { protected: public: virtual ~StmtVisitor() {} virtual void visit_assign(AST_Assign *node) { assert(0); abort(); } virtual void visit_augassign(AST_AugAssign *node) { assert(0); abort(); } virtual void visit_break(AST_Break *node) { assert(0); abort(); } virtual void visit_classdef(AST_ClassDef *node) { assert(0); abort(); } virtual void visit_continue(AST_Continue *node) { assert(0); abort(); } virtual void visit_expr(AST_Expr *node) { assert(0); abort(); } virtual void visit_for(AST_For *node) { assert(0); abort(); } virtual void visit_functiondef(AST_FunctionDef *node) { assert(0); abort(); } virtual void visit_global(AST_Global *node) { assert(0); abort(); } virtual void visit_if(AST_If *node) { assert(0); abort(); } virtual void visit_import(AST_Import *node) { assert(0); abort(); } virtual void visit_pass(AST_Pass *node) { assert(0); abort(); } virtual void visit_print(AST_Print *node) { assert(0); abort(); } virtual void visit_return(AST_Return *node) { assert(0); abort(); } virtual void visit_while(AST_While *node) { assert(0); abort(); } virtual void visit_with(AST_With *node) { assert(0); abort(); } virtual void visit_branch(AST_Branch *node) { assert(0); abort(); } virtual void visit_jump(AST_Jump *node) { assert(0); abort(); } }; void print_ast(AST *ast); class PrintVisitor : public ASTVisitor { private: int indent; void printIndent(); public: PrintVisitor(int indent=0) : indent(indent) {} virtual ~PrintVisitor() {} virtual bool visit_alias(AST_alias *node); virtual bool visit_arguments(AST_arguments *node); virtual bool visit_assign(AST_Assign *node); virtual bool visit_augassign(AST_AugAssign *node); virtual bool visit_augbinop(AST_AugBinOp *node); virtual bool visit_attribute(AST_Attribute *node); virtual bool visit_binop(AST_BinOp *node); virtual bool visit_boolop(AST_BoolOp *node); virtual bool visit_break(AST_Break *node); virtual bool visit_call(AST_Call *node); virtual bool visit_compare(AST_Compare *node); virtual bool visit_comprehension(AST_comprehension *node); virtual bool visit_classdef(AST_ClassDef *node); virtual bool visit_clsattribute(AST_ClsAttribute *node); virtual bool visit_continue(AST_Continue *node); virtual bool visit_dict(AST_Dict *node); virtual bool visit_expr(AST_Expr *node); virtual bool visit_for(AST_For *node); virtual bool visit_functiondef(AST_FunctionDef *node); virtual bool visit_global(AST_Global *node); virtual bool visit_if(AST_If *node); virtual bool visit_ifexp(AST_IfExp *node); virtual bool visit_import(AST_Import *node); virtual bool visit_index(AST_Index *node); virtual bool visit_keyword(AST_keyword *node); virtual bool visit_list(AST_List *node); virtual bool visit_listcomp(AST_ListComp *node); virtual bool visit_module(AST_Module *node); virtual bool visit_name(AST_Name *node); virtual bool visit_num(AST_Num *node); virtual bool visit_pass(AST_Pass *node); virtual bool visit_print(AST_Print *node); virtual bool visit_return(AST_Return *node); virtual bool visit_slice(AST_Slice *node); virtual bool visit_str(AST_Str *node); virtual bool visit_subscript(AST_Subscript *node); virtual bool visit_tuple(AST_Tuple *node); virtual bool visit_unaryop(AST_UnaryOp *node); virtual bool visit_while(AST_While *node); virtual bool visit_with(AST_With *node); virtual bool visit_branch(AST_Branch *node); virtual bool visit_jump(AST_Jump *node); }; // Given an AST node, return a vector of the node plus all its descendents. // This is useful for analyses that care more about the constituent nodes than the // exact tree structure; ex, finding all "global" directives. std::vector<AST*>* flatten(std::vector<AST_stmt*> &roots, bool expand_scopes); std::vector<AST*>* flatten(AST_expr *root, bool expand_scopes); // Similar to the flatten() function, but filters for a specific type of ast nodes: template <class T, class R> std::vector<T*>* findNodes(const R &roots, bool expand_scopes) { std::vector<T*> *rtn = new std::vector<T*>(); std::vector<AST*> *flattened = flatten(roots, expand_scopes); for (int i = 0; i < flattened->size(); i++) { AST* n = (*flattened)[i]; if (n->type == T::TYPE) rtn->push_back(reinterpret_cast<T*>(n)); } delete flattened; return rtn; } }; #endif