Commit 42a07f21 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Copy ast->bst

And remove some extraneous things from bst
parent 362a327d
......@@ -65,6 +65,7 @@ add_library(PYSTON_OBJECTS OBJECT ${OPTIONAL_SRCS}
codegen/type_recording.cpp
codegen/unwinding.cpp
core/ast.cpp
core/bst.cpp
core/cfg.cpp
core/options.cpp
core/stats.cpp
......
// Copyright (c) 2014-2016 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.
#include "core/bst.h"
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <stdint.h>
#include "Python.h"
#include "core/cfg.h"
#include "runtime/types.h"
namespace pyston {
#ifdef DEBUG_LINE_NUMBERS
int BST::next_lineno = 100000;
BST::BST(BST_TYPE::BST_TYPE type) : type(type), lineno(++next_lineno) {
// if (lineno == 100644)
// raise(SIGTRAP);
}
#endif
template <class T> static void visitVector(const std::vector<T*>& vec, BSTVisitor* v) {
for (int i = 0; i < vec.size(); i++) {
vec[i]->accept(v);
}
}
void BST_alias::accept(BSTVisitor* v) {
bool skip = v->visit_alias(this);
if (skip)
return;
}
void BST_arguments::accept(BSTVisitor* v) {
bool skip = v->visit_arguments(this);
if (skip)
return;
visitVector(defaults, v);
visitVector(args, v);
if (kwarg)
kwarg->accept(v);
if (vararg)
vararg->accept(v);
}
void BST_Assert::accept(BSTVisitor* v) {
bool skip = v->visit_assert(this);
if (skip)
return;
test->accept(v);
if (msg)
msg->accept(v);
}
void BST_Assert::accept_stmt(StmtVisitor* v) {
v->visit_assert(this);
}
void BST_Assign::accept(BSTVisitor* v) {
bool skip = v->visit_assign(this);
if (skip)
return;
value->accept(v);
for (int i = 0; i < targets.size(); i++) {
// Targets are assigned to left-to-right, so this is valid:
// x = x.a = object()
// but this is not:
// x.a = x = object()
targets[i]->accept(v);
}
}
void BST_Assign::accept_stmt(StmtVisitor* v) {
v->visit_assign(this);
}
void BST_AugAssign::accept(BSTVisitor* v) {
bool skip = v->visit_augassign(this);
if (skip)
return;
value->accept(v);
target->accept(v);
}
void BST_AugAssign::accept_stmt(StmtVisitor* v) {
v->visit_augassign(this);
}
void BST_AugBinOp::accept(BSTVisitor* v) {
bool skip = v->visit_augbinop(this);
if (skip)
return;
left->accept(v);
right->accept(v);
}
void* BST_AugBinOp::accept_expr(ExprVisitor* v) {
return v->visit_augbinop(this);
}
void BST_Attribute::accept(BSTVisitor* v) {
bool skip = v->visit_attribute(this);
if (skip)
return;
value->accept(v);
}
void* BST_Attribute::accept_expr(ExprVisitor* v) {
return v->visit_attribute(this);
}
void BST_BinOp::accept(BSTVisitor* v) {
bool skip = v->visit_binop(this);
if (skip)
return;
left->accept(v);
right->accept(v);
}
void* BST_BinOp::accept_expr(ExprVisitor* v) {
return v->visit_binop(this);
}
void BST_BoolOp::accept(BSTVisitor* v) {
bool skip = v->visit_boolop(this);
if (skip)
return;
visitVector(values, v);
}
void* BST_BoolOp::accept_expr(ExprVisitor* v) {
return v->visit_boolop(this);
}
void BST_Break::accept(BSTVisitor* v) {
bool skip = v->visit_break(this);
if (skip)
return;
}
void BST_Break::accept_stmt(StmtVisitor* v) {
v->visit_break(this);
}
void BST_Call::accept(BSTVisitor* v) {
bool skip = v->visit_call(this);
if (skip)
return;
func->accept(v);
visitVector(args, v);
visitVector(keywords, v);
if (starargs)
starargs->accept(v);
if (kwargs)
kwargs->accept(v);
}
void* BST_Call::accept_expr(ExprVisitor* v) {
return v->visit_call(this);
}
void BST_Compare::accept(BSTVisitor* v) {
bool skip = v->visit_compare(this);
if (skip)
return;
left->accept(v);
visitVector(comparators, v);
}
void* BST_Compare::accept_expr(ExprVisitor* v) {
return v->visit_compare(this);
}
void BST_comprehension::accept(BSTVisitor* v) {
bool skip = v->visit_comprehension(this);
if (skip)
return;
target->accept(v);
iter->accept(v);
for (auto if_ : ifs) {
if_->accept(v);
}
}
void BST_ClassDef::accept(BSTVisitor* v) {
bool skip = v->visit_classdef(this);
if (skip)
return;
visitVector(this->bases, v);
visitVector(this->decorator_list, v);
visitVector(this->body, v);
}
void BST_ClassDef::accept_stmt(StmtVisitor* v) {
v->visit_classdef(this);
}
void BST_Continue::accept(BSTVisitor* v) {
bool skip = v->visit_continue(this);
if (skip)
return;
}
void BST_Continue::accept_stmt(StmtVisitor* v) {
v->visit_continue(this);
}
void BST_Delete::accept(BSTVisitor* v) {
bool skip = v->visit_delete(this);
if (skip)
return;
visitVector(this->targets, v);
}
void BST_Delete::accept_stmt(StmtVisitor* v) {
v->visit_delete(this);
}
void BST_Dict::accept(BSTVisitor* v) {
bool skip = v->visit_dict(this);
if (skip)
return;
for (int i = 0; i < keys.size(); i++) {
keys[i]->accept(v);
values[i]->accept(v);
}
}
void* BST_Dict::accept_expr(ExprVisitor* v) {
return v->visit_dict(this);
}
void BST_DictComp::accept(BSTVisitor* v) {
bool skip = v->visit_dictcomp(this);
if (skip)
return;
for (auto c : generators) {
c->accept(v);
}
value->accept(v);
key->accept(v);
}
void* BST_DictComp::accept_expr(ExprVisitor* v) {
return v->visit_dictcomp(this);
}
void BST_Ellipsis::accept(BSTVisitor* v) {
bool skip = v->visit_ellipsis(this);
if (skip)
return;
}
void* BST_Ellipsis::accept_slice(SliceVisitor* v) {
return v->visit_ellipsis(this);
}
void BST_ExceptHandler::accept(BSTVisitor* v) {
bool skip = v->visit_excepthandler(this);
if (skip)
return;
if (type)
type->accept(v);
if (name)
name->accept(v);
visitVector(body, v);
}
void BST_Exec::accept(BSTVisitor* v) {
bool skip = v->visit_exec(this);
if (skip)
return;
if (body)
body->accept(v);
if (globals)
globals->accept(v);
if (locals)
locals->accept(v);
}
void BST_Exec::accept_stmt(StmtVisitor* v) {
v->visit_exec(this);
}
void BST_Expr::accept(BSTVisitor* v) {
bool skip = v->visit_expr(this);
if (skip)
return;
value->accept(v);
}
void BST_Expr::accept_stmt(StmtVisitor* v) {
v->visit_expr(this);
}
void BST_ExtSlice::accept(BSTVisitor* v) {
bool skip = v->visit_extslice(this);
if (skip)
return;
visitVector(dims, v);
}
void* BST_ExtSlice::accept_slice(SliceVisitor* v) {
return v->visit_extslice(this);
}
void BST_For::accept(BSTVisitor* v) {
bool skip = v->visit_for(this);
if (skip)
return;
iter->accept(v);
target->accept(v);
visitVector(body, v);
visitVector(orelse, v);
}
void BST_For::accept_stmt(StmtVisitor* v) {
v->visit_for(this);
}
void BST_FunctionDef::accept(BSTVisitor* v) {
bool skip = v->visit_functiondef(this);
if (skip)
return;
visitVector(decorator_list, v);
args->accept(v);
visitVector(body, v);
}
void BST_FunctionDef::accept_stmt(StmtVisitor* v) {
v->visit_functiondef(this);
}
void BST_GeneratorExp::accept(BSTVisitor* v) {
bool skip = v->visit_generatorexp(this);
if (skip)
return;
for (auto c : generators) {
c->accept(v);
}
elt->accept(v);
}
void* BST_GeneratorExp::accept_expr(ExprVisitor* v) {
return v->visit_generatorexp(this);
}
void BST_Global::accept(BSTVisitor* v) {
bool skip = v->visit_global(this);
if (skip)
return;
}
void BST_Global::accept_stmt(StmtVisitor* v) {
v->visit_global(this);
}
void BST_If::accept(BSTVisitor* v) {
bool skip = v->visit_if(this);
if (skip)
return;
test->accept(v);
visitVector(body, v);
visitVector(orelse, v);
}
void BST_If::accept_stmt(StmtVisitor* v) {
v->visit_if(this);
}
void BST_IfExp::accept(BSTVisitor* v) {
bool skip = v->visit_ifexp(this);
if (skip)
return;
this->test->accept(v);
this->body->accept(v);
this->orelse->accept(v);
}
void* BST_IfExp::accept_expr(ExprVisitor* v) {
return v->visit_ifexp(this);
}
void BST_Import::accept(BSTVisitor* v) {
bool skip = v->visit_import(this);
if (skip)
return;
visitVector(names, v);
}
void BST_Import::accept_stmt(StmtVisitor* v) {
v->visit_import(this);
}
void BST_ImportFrom::accept(BSTVisitor* v) {
bool skip = v->visit_importfrom(this);
if (skip)
return;
visitVector(names, v);
}
void BST_ImportFrom::accept_stmt(StmtVisitor* v) {
v->visit_importfrom(this);
}
void BST_Index::accept(BSTVisitor* v) {
bool skip = v->visit_index(this);
if (skip)
return;
this->value->accept(v);
}
void* BST_Index::accept_slice(SliceVisitor* v) {
return v->visit_index(this);
}
void BST_Invoke::accept(BSTVisitor* v) {
bool skip = v->visit_invoke(this);
if (skip)
return;
this->stmt->accept(v);
}
void BST_Invoke::accept_stmt(StmtVisitor* v) {
return v->visit_invoke(this);
}
void BST_keyword::accept(BSTVisitor* v) {
bool skip = v->visit_keyword(this);
if (skip)
return;
value->accept(v);
}
void BST_Lambda::accept(BSTVisitor* v) {
bool skip = v->visit_lambda(this);
if (skip)
return;
args->accept(v);
body->accept(v);
}
void* BST_Lambda::accept_expr(ExprVisitor* v) {
return v->visit_lambda(this);
}
void BST_LangPrimitive::accept(BSTVisitor* v) {
bool skip = v->visit_langprimitive(this);
if (skip)
return;
visitVector(args, v);
}
void* BST_LangPrimitive::accept_expr(ExprVisitor* v) {
return v->visit_langprimitive(this);
}
void BST_List::accept(BSTVisitor* v) {
bool skip = v->visit_list(this);
if (skip)
return;
visitVector(elts, v);
}
void* BST_List::accept_expr(ExprVisitor* v) {
return v->visit_list(this);
}
void BST_ListComp::accept(BSTVisitor* v) {
bool skip = v->visit_listcomp(this);
if (skip)
return;
for (auto c : generators) {
c->accept(v);
}
elt->accept(v);
}
void* BST_ListComp::accept_expr(ExprVisitor* v) {
return v->visit_listcomp(this);
}
void BST_Module::accept(BSTVisitor* v) {
bool skip = v->visit_module(this);
if (skip)
return;
visitVector(body, v);
}
void BST_Expression::accept(BSTVisitor* v) {
bool skip = v->visit_expression(this);
if (skip)
return;
body->accept(v);
}
void BST_Suite::accept(BSTVisitor* v) {
bool skip = v->visit_suite(this);
if (skip)
return;
visitVector(body, v);
}
void BST_Name::accept(BSTVisitor* v) {
bool skip = v->visit_name(this);
}
void* BST_Name::accept_expr(ExprVisitor* v) {
return v->visit_name(this);
}
void BST_Num::accept(BSTVisitor* v) {
bool skip = v->visit_num(this);
}
void* BST_Num::accept_expr(ExprVisitor* v) {
return v->visit_num(this);
}
void BST_Pass::accept(BSTVisitor* v) {
bool skip = v->visit_pass(this);
}
void BST_Pass::accept_stmt(StmtVisitor* v) {
v->visit_pass(this);
}
void BST_Print::accept(BSTVisitor* v) {
bool skip = v->visit_print(this);
if (skip)
return;
if (dest)
dest->accept(v);
visitVector(values, v);
}
void BST_Print::accept_stmt(StmtVisitor* v) {
v->visit_print(this);
}
void BST_Raise::accept(BSTVisitor* v) {
bool skip = v->visit_raise(this);
if (skip)
return;
if (arg0)
arg0->accept(v);
if (arg1)
arg1->accept(v);
if (arg2)
arg2->accept(v);
}
void BST_Raise::accept_stmt(StmtVisitor* v) {
v->visit_raise(this);
}
void BST_Repr::accept(BSTVisitor* v) {
bool skip = v->visit_repr(this);
if (skip)
return;
value->accept(v);
}
void* BST_Repr::accept_expr(ExprVisitor* v) {
return v->visit_repr(this);
}
void BST_Return::accept(BSTVisitor* v) {
bool skip = v->visit_return(this);
if (skip)
return;
if (value)
value->accept(v);
}
void BST_Return::accept_stmt(StmtVisitor* v) {
v->visit_return(this);
}
void BST_Set::accept(BSTVisitor* v) {
bool skip = v->visit_set(this);
if (skip)
return;
visitVector(elts, v);
}
void* BST_Set::accept_expr(ExprVisitor* v) {
return v->visit_set(this);
}
void BST_SetComp::accept(BSTVisitor* v) {
bool skip = v->visit_setcomp(this);
if (skip)
return;
for (auto c : generators) {
c->accept(v);
}
elt->accept(v);
}
void* BST_SetComp::accept_expr(ExprVisitor* v) {
return v->visit_setcomp(this);
}
void BST_Slice::accept(BSTVisitor* v) {
bool skip = v->visit_slice(this);
if (skip)
return;
if (lower)
lower->accept(v);
if (upper)
upper->accept(v);
if (step)
step->accept(v);
}
void* BST_Slice::accept_slice(SliceVisitor* v) {
return v->visit_slice(this);
}
void BST_Str::accept(BSTVisitor* v) {
bool skip = v->visit_str(this);
if (skip)
return;
}
void* BST_Str::accept_expr(ExprVisitor* v) {
return v->visit_str(this);
}
void BST_Subscript::accept(BSTVisitor* v) {
bool skip = v->visit_subscript(this);
if (skip)
return;
this->value->accept(v);
this->slice->accept(v);
}
void* BST_Subscript::accept_expr(ExprVisitor* v) {
return v->visit_subscript(this);
}
void BST_TryExcept::accept(BSTVisitor* v) {
bool skip = v->visit_tryexcept(this);
if (skip)
return;
visitVector(body, v);
visitVector(orelse, v);
visitVector(handlers, v);
}
void BST_TryExcept::accept_stmt(StmtVisitor* v) {
v->visit_tryexcept(this);
}
void BST_TryFinally::accept(BSTVisitor* v) {
bool skip = v->visit_tryfinally(this);
if (skip)
return;
visitVector(body, v);
visitVector(finalbody, v);
}
void BST_TryFinally::accept_stmt(StmtVisitor* v) {
v->visit_tryfinally(this);
}
void BST_Tuple::accept(BSTVisitor* v) {
bool skip = v->visit_tuple(this);
if (skip)
return;
visitVector(elts, v);
}
void* BST_Tuple::accept_expr(ExprVisitor* v) {
return v->visit_tuple(this);
}
void BST_UnaryOp::accept(BSTVisitor* v) {
bool skip = v->visit_unaryop(this);
if (skip)
return;
operand->accept(v);
}
void* BST_UnaryOp::accept_expr(ExprVisitor* v) {
return v->visit_unaryop(this);
}
void BST_While::accept(BSTVisitor* v) {
bool skip = v->visit_while(this);
if (skip)
return;
test->accept(v);
visitVector(body, v);
visitVector(orelse, v);
}
void BST_While::accept_stmt(StmtVisitor* v) {
v->visit_while(this);
}
void BST_With::accept(BSTVisitor* v) {
bool skip = v->visit_with(this);
if (skip)
return;
context_expr->accept(v);
if (optional_vars)
optional_vars->accept(v);
visitVector(body, v);
}
void BST_With::accept_stmt(StmtVisitor* v) {
v->visit_with(this);
}
void BST_Yield::accept(BSTVisitor* v) {
bool skip = v->visit_yield(this);
if (skip)
return;
if (value)
value->accept(v);
}
void* BST_Yield::accept_expr(ExprVisitor* v) {
return v->visit_yield(this);
}
void BST_Branch::accept(BSTVisitor* v) {
bool skip = v->visit_branch(this);
if (skip)
return;
test->accept(v);
}
void BST_Branch::accept_stmt(StmtVisitor* v) {
v->visit_branch(this);
}
void BST_Jump::accept(BSTVisitor* v) {
bool skip = v->visit_jump(this);
if (skip)
return;
}
void BST_Jump::accept_stmt(StmtVisitor* v) {
v->visit_jump(this);
}
void BST_ClsAttribute::accept(BSTVisitor* v) {
bool skip = v->visit_clsattribute(this);
if (skip)
return;
value->accept(v);
}
void* BST_ClsAttribute::accept_expr(ExprVisitor* v) {
return v->visit_clsattribute(this);
}
void BST_MakeFunction::accept(BSTVisitor* v) {
bool skip = v->visit_makefunction(this);
if (skip)
return;
function_def->accept(v);
}
void* BST_MakeFunction::accept_expr(ExprVisitor* v) {
return v->visit_makefunction(this);
}
void BST_MakeClass::accept(BSTVisitor* v) {
bool skip = v->visit_makeclass(this);
if (skip)
return;
class_def->accept(v);
}
void* BST_MakeClass::accept_expr(ExprVisitor* v) {
return v->visit_makeclass(this);
}
void print_bst(BST* bst) {
PrintVisitor v;
bst->accept(&v);
v.flush();
}
void PrintVisitor::printIndent() {
for (int i = 0; i < indent; i++) {
stream << ' ';
}
}
bool PrintVisitor::visit_alias(BST_alias* node) {
stream << node->name.s();
if (node->asname.s().size())
stream << " as " << node->asname.s();
return true;
}
bool PrintVisitor::visit_arguments(BST_arguments* node) {
int nargs = node->args.size();
int ndefault = node->defaults.size();
for (int i = 0; i < nargs; i++) {
if (i > 0)
stream << ", ";
node->args[i]->accept(this);
if (i >= nargs - ndefault) {
stream << "=";
node->defaults[i - (nargs - ndefault)]->accept(this);
}
}
return true;
}
bool PrintVisitor::visit_assert(BST_Assert* node) {
stream << "assert ";
node->test->accept(this);
if (node->msg) {
stream << ", ";
node->msg->accept(this);
}
return true;
}
bool PrintVisitor::visit_assign(BST_Assign* node) {
for (int i = 0; i < node->targets.size(); i++) {
node->targets[i]->accept(this);
stream << " = ";
}
node->value->accept(this);
return true;
}
void PrintVisitor::printOp(BST_TYPE::BST_TYPE op_type) {
switch (op_type) {
case BST_TYPE::Add:
stream << '+';
break;
case BST_TYPE::BitAnd:
stream << '&';
break;
case BST_TYPE::BitOr:
stream << '|';
break;
case BST_TYPE::BitXor:
stream << '^';
break;
case BST_TYPE::Div:
stream << '/';
break;
case BST_TYPE::LShift:
stream << "<<";
break;
case BST_TYPE::RShift:
stream << ">>";
break;
case BST_TYPE::Pow:
stream << "**";
break;
case BST_TYPE::Mod:
stream << '%';
break;
case BST_TYPE::Mult:
stream << '*';
break;
case BST_TYPE::Sub:
stream << '-';
break;
default:
stream << "<" << (int)op_type << ">";
break;
}
}
bool PrintVisitor::visit_augassign(BST_AugAssign* node) {
node->target->accept(this);
printOp(node->op_type);
stream << '=';
node->value->accept(this);
return true;
}
bool PrintVisitor::visit_augbinop(BST_AugBinOp* node) {
node->left->accept(this);
stream << '=';
printOp(node->op_type);
node->right->accept(this);
return true;
}
bool PrintVisitor::visit_attribute(BST_Attribute* node) {
node->value->accept(this);
stream << '.';
stream << node->attr.s();
return true;
}
bool PrintVisitor::visit_binop(BST_BinOp* node) {
node->left->accept(this);
printOp(node->op_type);
node->right->accept(this);
return true;
}
bool PrintVisitor::visit_boolop(BST_BoolOp* node) {
for (int i = 0; i < node->values.size(); i++) {
node->values[i]->accept(this);
if (i == node->values.size() - 1)
continue;
switch (node->op_type) {
case BST_TYPE::And:
stream << " and ";
break;
case BST_TYPE::Or:
stream << " or ";
break;
default:
ASSERT(0, "%d", node->op_type);
break;
}
}
return true;
}
bool PrintVisitor::visit_break(BST_Break* node) {
stream << "break";
return true;
}
bool PrintVisitor::visit_call(BST_Call* node) {
node->func->accept(this);
stream << "(";
bool prevarg = false;
for (int i = 0; i < node->args.size(); i++) {
if (prevarg)
stream << ", ";
node->args[i]->accept(this);
prevarg = true;
}
for (int i = 0; i < node->keywords.size(); i++) {
if (prevarg)
stream << ", ";
node->keywords[i]->accept(this);
prevarg = true;
}
if (node->starargs) {
if (prevarg)
stream << ", ";
node->starargs->accept(this);
prevarg = true;
}
if (node->kwargs) {
if (prevarg)
stream << ", ";
node->kwargs->accept(this);
prevarg = true;
}
stream << ")";
return true;
}
bool PrintVisitor::visit_compare(BST_Compare* node) {
node->left->accept(this);
for (int i = 0; i < node->ops.size(); i++) {
std::string symbol = getOpSymbol(node->ops[i]);
stream << " " << symbol << " ";
node->comparators[i]->accept(this);
}
return true;
}
bool PrintVisitor::visit_comprehension(BST_comprehension* node) {
stream << "for ";
node->target->accept(this);
stream << " in ";
node->iter->accept(this);
for (BST_expr* i : node->ifs) {
stream << " if ";
i->accept(this);
}
return true;
}
bool PrintVisitor::visit_classdef(BST_ClassDef* node) {
for (int i = 0, n = node->decorator_list.size(); i < n; i++) {
stream << "@";
node->decorator_list[i]->accept(this);
stream << "\n";
printIndent();
}
stream << "class " << node->name.s() << "(";
for (int i = 0, n = node->bases.size(); i < n; i++) {
if (i)
stream << ", ";
node->bases[i]->accept(this);
}
stream << ")";
indent += 4;
for (int i = 0, n = node->body.size(); i < n; i++) {
stream << "\n";
printIndent();
node->body[i]->accept(this);
}
indent -= 4;
return true;
}
bool PrintVisitor::visit_continue(BST_Continue* node) {
stream << "continue";
return true;
}
bool PrintVisitor::visit_delete(BST_Delete* node) {
stream << "del ";
for (int i = 0; i < node->targets.size(); i++) {
if (i > 0)
stream << ", ";
node->targets[i]->accept(this);
}
return true;
}
bool PrintVisitor::visit_dict(BST_Dict* node) {
stream << "{";
for (int i = 0; i < node->keys.size(); i++) {
if (i > 0)
stream << ", ";
node->keys[i]->accept(this);
stream << ":";
node->values[i]->accept(this);
}
stream << "}";
return true;
}
bool PrintVisitor::visit_dictcomp(BST_DictComp* node) {
stream << "{";
node->key->accept(this);
stream << ":";
node->value->accept(this);
for (auto c : node->generators) {
stream << " ";
c->accept(this);
}
stream << "}";
return true;
}
bool PrintVisitor::visit_ellipsis(BST_Ellipsis*) {
stream << "...";
return true;
}
bool PrintVisitor::visit_excepthandler(BST_ExceptHandler* node) {
stream << "except";
if (node->type) {
stream << " ";
node->type->accept(this);
}
if (node->name) {
stream << " as ";
node->name->accept(this);
}
stream << ":\n";
indent += 4;
for (BST* subnode : node->body) {
printIndent();
subnode->accept(this);
stream << "\n";
}
indent -= 4;
return true;
}
bool PrintVisitor::visit_exec(BST_Exec* node) {
stream << "exec ";
node->body->accept(this);
if (node->globals) {
stream << " in ";
node->globals->accept(this);
if (node->locals) {
stream << ", ";
node->locals->accept(this);
}
}
stream << "\n";
return true;
}
bool PrintVisitor::visit_expr(BST_Expr* node) {
return false;
}
bool PrintVisitor::visit_extslice(BST_ExtSlice* node) {
for (int i = 0; i < node->dims.size(); ++i) {
if (i > 0)
stream << ", ";
node->dims[i]->accept(this);
}
return true;
}
bool PrintVisitor::visit_for(BST_For* node) {
stream << "<for loop>\n";
return true;
}
bool PrintVisitor::visit_functiondef(BST_FunctionDef* node) {
for (auto d : node->decorator_list) {
stream << "@";
d->accept(this);
stream << "\n";
printIndent();
}
stream << "def ";
if (node->name != InternedString())
stream << node->name.s();
else
stream << "<lambda>";
stream << "(";
node->args->accept(this);
stream << ")";
indent += 4;
for (int i = 0; i < node->body.size(); i++) {
stream << "\n";
printIndent();
node->body[i]->accept(this);
}
indent -= 4;
return true;
}
bool PrintVisitor::visit_generatorexp(BST_GeneratorExp* node) {
stream << "[";
node->elt->accept(this);
for (auto c : node->generators) {
stream << " ";
c->accept(this);
}
stream << "]";
return true;
}
bool PrintVisitor::visit_global(BST_Global* node) {
stream << "global ";
for (int i = 0; i < node->names.size(); i++) {
if (i > 0)
stream << ", ";
stream << node->names[i].s();
}
return true;
}
bool PrintVisitor::visit_if(BST_If* node) {
stream << "if ";
node->test->accept(this);
stream << ":\n";
indent += 4;
for (int i = 0; i < node->body.size(); i++) {
printIndent();
node->body[i]->accept(this);
stream << "\n";
}
indent -= 4;
if (node->orelse.size()) {
printIndent();
bool elif = false;
if (node->orelse.size() == 1 && node->orelse[0]->type == BST_TYPE::If)
elif = true;
if (elif) {
stream << "el";
} else {
stream << "else:\n";
indent += 4;
}
for (int i = 0; i < node->orelse.size(); i++) {
if (i)
stream << "\n";
printIndent();
node->orelse[i]->accept(this);
}
if (!elif)
indent -= 4;
}
return true;
}
bool PrintVisitor::visit_ifexp(BST_IfExp* node) {
node->body->accept(this);
stream << " if ";
node->test->accept(this);
stream << " else ";
node->orelse->accept(this);
return true;
}
bool PrintVisitor::visit_import(BST_Import* node) {
stream << "import ";
for (int i = 0; i < node->names.size(); i++) {
if (i > 0)
stream << ", ";
node->names[i]->accept(this);
}
return true;
}
bool PrintVisitor::visit_importfrom(BST_ImportFrom* node) {
stream << "from " << node->module.s() << " import ";
for (int i = 0; i < node->names.size(); i++) {
if (i > 0)
stream << ", ";
node->names[i]->accept(this);
}
return true;
}
bool PrintVisitor::visit_index(BST_Index* node) {
return false;
}
bool PrintVisitor::visit_invoke(BST_Invoke* node) {
stream << "invoke " << node->normal_dest->idx << " " << node->exc_dest->idx << ": ";
node->stmt->accept(this);
return true;
}
bool PrintVisitor::visit_lambda(BST_Lambda* node) {
stream << "lambda ";
node->args->accept(this);
stream << ": ";
node->body->accept(this);
return true;
}
bool PrintVisitor::visit_langprimitive(BST_LangPrimitive* node) {
stream << ":";
switch (node->opcode) {
case BST_LangPrimitive::CHECK_EXC_MATCH:
stream << "CHECK_EXC_MATCH";
break;
case BST_LangPrimitive::LANDINGPAD:
stream << "LANDINGPAD";
break;
case BST_LangPrimitive::LOCALS:
stream << "LOCALS";
break;
case BST_LangPrimitive::GET_ITER:
stream << "GET_ITER";
break;
case BST_LangPrimitive::IMPORT_FROM:
stream << "IMPORT_FROM";
break;
case BST_LangPrimitive::IMPORT_NAME:
stream << "IMPORT_NAME";
break;
case BST_LangPrimitive::IMPORT_STAR:
stream << "IMPORT_STAR";
break;
case BST_LangPrimitive::NONE:
stream << "NONE";
break;
case BST_LangPrimitive::NONZERO:
stream << "NONZERO";
break;
case BST_LangPrimitive::SET_EXC_INFO:
stream << "SET_EXC_INFO";
break;
case BST_LangPrimitive::UNCACHE_EXC_INFO:
stream << "UNCACHE_EXC_INFO";
break;
case BST_LangPrimitive::HASNEXT:
stream << "HASNEXT";
break;
case BST_LangPrimitive::PRINT_EXPR:
stream << "PRINT_EXPR";
break;
default:
RELEASE_ASSERT(0, "%d", node->opcode);
}
stream << "(";
for (int i = 0, n = node->args.size(); i < n; ++i) {
if (i > 0)
stream << ", ";
node->args[i]->accept(this);
}
stream << ")";
return true;
}
bool PrintVisitor::visit_list(BST_List* node) {
stream << "[";
for (int i = 0, n = node->elts.size(); i < n; ++i) {
if (i > 0)
stream << ", ";
node->elts[i]->accept(this);
}
stream << "]";
return true;
}
bool PrintVisitor::visit_listcomp(BST_ListComp* node) {
stream << "[";
node->elt->accept(this);
for (auto c : node->generators) {
stream << " ";
c->accept(this);
}
stream << "]";
return true;
}
bool PrintVisitor::visit_keyword(BST_keyword* node) {
stream << node->arg.s() << "=";
node->value->accept(this);
return true;
}
bool PrintVisitor::visit_module(BST_Module* node) {
// stream << "<module>\n";
for (int i = 0; i < node->body.size(); i++) {
node->body[i]->accept(this);
stream << "\n";
}
return true;
}
bool PrintVisitor::visit_expression(BST_Expression* node) {
node->body->accept(this);
stream << "\n";
return true;
}
bool PrintVisitor::visit_suite(BST_Suite* node) {
for (int i = 0; i < node->body.size(); i++) {
printIndent();
node->body[i]->accept(this);
stream << "\n";
}
return true;
}
bool PrintVisitor::visit_name(BST_Name* node) {
stream << node->id.s();
#if 0
if (node->lookup_type == ScopeInfo::VarScopeType::UNKNOWN)
stream << "<U>";
else if (node->lookup_type == ScopeInfo::VarScopeType::FBST)
stream << "<F>";
else if (node->lookup_type == ScopeInfo::VarScopeType::DEREF)
stream << "<D>";
else if (node->lookup_type == ScopeInfo::VarScopeType::CLOSURE)
stream << "<C>";
else if (node->lookup_type == ScopeInfo::VarScopeType::GLOBAL)
stream << "<G>";
else
stream << "<?>";
#endif
#if 0
if (node->is_kill) stream << "<k>";
#endif
return false;
}
bool PrintVisitor::visit_num(BST_Num* node) {
if (node->num_type == BST_Num::INT) {
stream << node->n_int;
} else if (node->num_type == BST_Num::LONG) {
stream << node->n_long << "L";
} else if (node->num_type == BST_Num::FLOAT) {
stream << node->n_float;
} else if (node->num_type == BST_Num::COMPLEX) {
stream << node->n_float << "j";
} else {
RELEASE_ASSERT(0, "");
}
return false;
}
bool PrintVisitor::visit_pass(BST_Pass* node) {
stream << "pass";
return true;
}
bool PrintVisitor::visit_print(BST_Print* node) {
stream << "print ";
if (node->dest) {
stream << ">>";
node->dest->accept(this);
stream << ", ";
}
for (int i = 0; i < node->values.size(); i++) {
if (i > 0)
stream << ", ";
node->values[i]->accept(this);
}
if (!node->nl)
stream << ",";
return true;
}
bool PrintVisitor::visit_raise(BST_Raise* node) {
stream << "raise";
if (node->arg0) {
stream << " ";
node->arg0->accept(this);
}
if (node->arg1) {
stream << ", ";
node->arg1->accept(this);
}
if (node->arg2) {
stream << ", ";
node->arg2->accept(this);
}
return true;
}
bool PrintVisitor::visit_repr(BST_Repr* node) {
stream << "`";
node->value->accept(this);
stream << "`";
return true;
}
bool PrintVisitor::visit_return(BST_Return* node) {
stream << "return ";
return false;
}
bool PrintVisitor::visit_set(BST_Set* node) {
// An empty set literal is not writeable in Python (it's a dictionary),
// but we sometimes generate it (ex in set comprehension lowering).
// Just to make it clear when printing, print empty set literals as "SET{}".
if (!node->elts.size())
stream << "SET";
stream << "{";
bool first = true;
for (auto e : node->elts) {
if (!first)
stream << ", ";
first = false;
e->accept(this);
}
stream << "}";
return true;
}
bool PrintVisitor::visit_setcomp(BST_SetComp* node) {
stream << "{";
node->elt->accept(this);
for (auto c : node->generators) {
stream << " ";
c->accept(this);
}
stream << "}";
return true;
}
bool PrintVisitor::visit_slice(BST_Slice* node) {
stream << "<slice>(";
if (node->lower)
node->lower->accept(this);
if (node->upper || node->step)
stream << ':';
if (node->upper)
node->upper->accept(this);
if (node->step) {
stream << ':';
node->step->accept(this);
}
stream << ")";
return true;
}
bool PrintVisitor::visit_str(BST_Str* node) {
if (node->str_type == BST_Str::STR) {
stream << "\"" << node->str_data << "\"";
} else if (node->str_type == BST_Str::UNICODE) {
stream << "<unicode value>";
} else {
RELEASE_ASSERT(0, "%d", node->str_type);
}
return false;
}
bool PrintVisitor::visit_subscript(BST_Subscript* node) {
node->value->accept(this);
stream << "[";
node->slice->accept(this);
stream << "]";
return true;
}
bool PrintVisitor::visit_tryexcept(BST_TryExcept* node) {
stream << "try:\n";
indent += 4;
for (BST* subnode : node->body) {
printIndent();
subnode->accept(this);
stream << "\n";
}
indent -= 4;
for (BST_ExceptHandler* handler : node->handlers) {
printIndent();
handler->accept(this);
}
if (node->orelse.size()) {
printIndent();
stream << "else:\n";
indent += 4;
for (BST* subnode : node->orelse) {
printIndent();
subnode->accept(this);
stream << "\n";
}
indent -= 4;
}
return true;
}
bool PrintVisitor::visit_tryfinally(BST_TryFinally* node) {
if (node->body.size() == 1 && node->body[0]->type == BST_TYPE::TryExcept) {
node->body[0]->accept(this);
printIndent();
stream << "finally:\n";
indent += 4;
for (BST* subnode : node->finalbody) {
printIndent();
subnode->accept(this);
stream << "\n";
}
indent -= 4;
} else {
stream << "try:\n";
indent += 4;
for (BST* subnode : node->body) {
printIndent();
subnode->accept(this);
stream << "\n";
}
indent -= 4;
printIndent();
stream << "finally:\n";
indent += 4;
for (BST* subnode : node->finalbody) {
printIndent();
subnode->accept(this);
stream << "\n";
}
indent -= 4;
}
return true;
}
bool PrintVisitor::visit_tuple(BST_Tuple* node) {
stream << "(";
int n = node->elts.size();
for (int i = 0; i < n; i++) {
if (i)
stream << ", ";
node->elts[i]->accept(this);
}
if (n == 1)
stream << ",";
stream << ")";
return true;
}
bool PrintVisitor::visit_unaryop(BST_UnaryOp* node) {
switch (node->op_type) {
case BST_TYPE::Invert:
stream << "~";
break;
case BST_TYPE::Not:
stream << "not ";
break;
case BST_TYPE::UAdd:
stream << "+";
break;
case BST_TYPE::USub:
stream << "-";
break;
default:
RELEASE_ASSERT(0, "%s", getOpName(node->op_type)->c_str());
break;
}
stream << "(";
node->operand->accept(this);
stream << ")";
return true;
}
bool PrintVisitor::visit_while(BST_While* node) {
stream << "while ";
node->test->accept(this);
stream << "\n";
indent += 4;
for (int i = 0; i < node->body.size(); i++) {
printIndent();
node->body[i]->accept(this);
stream << "\n";
}
indent -= 4;
if (node->orelse.size()) {
printIndent();
stream << "else\n";
indent += 4;
for (int i = 0; i < node->orelse.size(); i++) {
printIndent();
node->orelse[i]->accept(this);
stream << "\n";
}
indent -= 4;
}
return true;
}
bool PrintVisitor::visit_with(BST_With* node) {
stream << "with ";
node->context_expr->accept(this);
if (node->optional_vars) {
stream << " as ";
node->optional_vars->accept(this);
stream << ":\n";
}
indent += 4;
for (int i = 0; i < node->body.size(); i++) {
if (i > 0)
stream << "\n";
printIndent();
node->body[i]->accept(this);
}
indent -= 4;
return true;
}
bool PrintVisitor::visit_yield(BST_Yield* node) {
stream << "yield ";
if (node->value)
node->value->accept(this);
return true;
}
bool PrintVisitor::visit_branch(BST_Branch* node) {
stream << "if ";
node->test->accept(this);
stream << " goto " << node->iftrue->idx << " else goto " << node->iffalse->idx;
return true;
}
bool PrintVisitor::visit_jump(BST_Jump* node) {
stream << "goto " << node->target->idx;
return true;
}
bool PrintVisitor::visit_clsattribute(BST_ClsAttribute* node) {
// printf("getclsattr(");
// node->value->accept(this);
// printf(", '%s')", node->attr.c_str());
node->value->accept(this);
stream << ":" << node->attr.s();
return true;
}
bool PrintVisitor::visit_makefunction(BST_MakeFunction* node) {
stream << "make_";
return false;
}
bool PrintVisitor::visit_makeclass(BST_MakeClass* node) {
stream << "make_";
return false;
}
class FlattenVisitor : public BSTVisitor {
private:
std::vector<BST*>* output;
bool expand_scopes;
public:
FlattenVisitor(std::vector<BST*>* output, bool expand_scopes) : output(output), expand_scopes(expand_scopes) {
assert(expand_scopes && "not sure if this works properly");
}
virtual bool visit_alias(BST_alias* node) {
output->push_back(node);
return false;
}
virtual bool visit_arguments(BST_arguments* node) {
output->push_back(node);
return false;
}
virtual bool visit_assert(BST_Assert* node) {
output->push_back(node);
return false;
}
virtual bool visit_assign(BST_Assign* node) {
output->push_back(node);
return false;
}
virtual bool visit_augassign(BST_AugAssign* node) {
output->push_back(node);
return false;
}
virtual bool visit_augbinop(BST_AugBinOp* node) {
output->push_back(node);
return false;
}
virtual bool visit_attribute(BST_Attribute* node) {
output->push_back(node);
return false;
}
virtual bool visit_binop(BST_BinOp* node) {
output->push_back(node);
return false;
}
virtual bool visit_boolop(BST_BoolOp* node) {
output->push_back(node);
return false;
}
virtual bool visit_break(BST_Break* node) {
output->push_back(node);
return false;
}
virtual bool visit_call(BST_Call* node) {
output->push_back(node);
return false;
}
virtual bool visit_classdef(BST_ClassDef* node) {
output->push_back(node);
return !expand_scopes;
}
virtual bool visit_compare(BST_Compare* node) {
output->push_back(node);
return false;
}
virtual bool visit_comprehension(BST_comprehension* node) {
output->push_back(node);
return false;
}
virtual bool visit_continue(BST_Continue* node) {
output->push_back(node);
return false;
}
virtual bool visit_delete(BST_Delete* node) {
output->push_back(node);
return false;
}
virtual bool visit_dict(BST_Dict* node) {
output->push_back(node);
return false;
}
virtual bool visit_dictcomp(BST_DictComp* node) {
output->push_back(node);
return false;
}
virtual bool visit_ellipsis(BST_Ellipsis* node) {
output->push_back(node);
return false;
}
virtual bool visit_excepthandler(BST_ExceptHandler* node) {
output->push_back(node);
return false;
}
virtual bool visit_exec(BST_Exec* node) {
output->push_back(node);
return false;
}
virtual bool visit_expr(BST_Expr* node) {
output->push_back(node);
return false;
}
virtual bool visit_extslice(BST_ExtSlice* node) {
output->push_back(node);
return false;
}
virtual bool visit_for(BST_For* node) {
output->push_back(node);
return !expand_scopes;
}
virtual bool visit_functiondef(BST_FunctionDef* node) {
output->push_back(node);
return !expand_scopes;
}
virtual bool visit_generatorexp(BST_GeneratorExp* node) {
output->push_back(node);
return !expand_scopes;
}
virtual bool visit_global(BST_Global* node) {
output->push_back(node);
return false;
}
virtual bool visit_if(BST_If* node) {
output->push_back(node);
return false;
}
virtual bool visit_ifexp(BST_IfExp* node) {
output->push_back(node);
return false;
}
virtual bool visit_import(BST_Import* node) {
output->push_back(node);
return false;
}
virtual bool visit_importfrom(BST_ImportFrom* node) {
output->push_back(node);
return false;
}
virtual bool visit_index(BST_Index* node) {
output->push_back(node);
return false;
}
virtual bool visit_invoke(BST_Invoke* node) {
output->push_back(node);
return false;
}
virtual bool visit_keyword(BST_keyword* node) {
output->push_back(node);
return false;
}
virtual bool visit_lambda(BST_Lambda* node) {
output->push_back(node);
return !expand_scopes;
}
virtual bool visit_langprimitive(BST_LangPrimitive* node) {
output->push_back(node);
return false;
}
virtual bool visit_list(BST_List* node) {
output->push_back(node);
return false;
}
virtual bool visit_listcomp(BST_ListComp* node) {
output->push_back(node);
return false;
}
virtual bool visit_module(BST_Module* node) {
output->push_back(node);
return !expand_scopes;
}
virtual bool visit_name(BST_Name* node) {
output->push_back(node);
return false;
}
virtual bool visit_num(BST_Num* node) {
output->push_back(node);
return false;
}
virtual bool visit_pass(BST_Pass* node) {
output->push_back(node);
return false;
}
virtual bool visit_print(BST_Print* node) {
output->push_back(node);
return false;
}
virtual bool visit_raise(BST_Raise* node) {
output->push_back(node);
return false;
}
virtual bool visit_repr(BST_Repr* node) {
output->push_back(node);
return false;
}
virtual bool visit_return(BST_Return* node) {
output->push_back(node);
return false;
}
virtual bool visit_set(BST_Set* node) {
output->push_back(node);
return false;
}
virtual bool visit_setcomp(BST_SetComp* node) {
output->push_back(node);
return false;
}
virtual bool visit_slice(BST_Slice* node) {
output->push_back(node);
return false;
}
virtual bool visit_str(BST_Str* node) {
output->push_back(node);
return false;
}
virtual bool visit_subscript(BST_Subscript* node) {
output->push_back(node);
return false;
}
virtual bool visit_tryexcept(BST_TryExcept* node) {
output->push_back(node);
return false;
}
virtual bool visit_tryfinally(BST_TryFinally* node) {
output->push_back(node);
return false;
}
virtual bool visit_tuple(BST_Tuple* node) {
output->push_back(node);
return false;
}
virtual bool visit_unaryop(BST_UnaryOp* node) {
output->push_back(node);
return false;
}
virtual bool visit_while(BST_While* node) {
output->push_back(node);
return false;
}
virtual bool visit_with(BST_With* node) {
output->push_back(node);
return false;
}
virtual bool visit_yield(BST_Yield* node) {
output->push_back(node);
return false;
}
virtual bool visit_branch(BST_Branch* node) {
output->push_back(node);
return false;
}
virtual bool visit_jump(BST_Jump* node) {
output->push_back(node);
return false;
}
virtual bool visit_clsattribute(BST_ClsAttribute* node) {
output->push_back(node);
return false;
}
virtual bool visit_makeclass(BST_MakeClass* node) {
output->push_back(node);
return false;
}
virtual bool visit_makefunction(BST_MakeFunction* node) {
output->push_back(node);
return false;
}
};
}
// Copyright (c) 2014-2016 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_BST_H
#define PYSTON_CORE_BST_H
#include <cassert>
#include <cstdlib>
#include <map>
#include <stdint.h>
#include <string>
#include <vector>
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
#include "analysis/scoping_analysis.h"
#include "core/common.h"
#include "core/stringpool.h"
namespace pyston {
namespace BST_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
#define FOREACH_TYPE(X) \
X(alias, 1) \
X(arguments, 2) \
X(Assert, 3) \
X(Assign, 4) \
X(Attribute, 5) \
X(AugAssign, 6) \
X(BinOp, 7) \
X(BoolOp, 8) \
X(Call, 9) \
X(ClassDef, 10) \
X(Compare, 11) \
X(comprehension, 12) \
X(Delete, 13) \
X(Dict, 14) \
X(Exec, 16) \
X(ExceptHandler, 17) \
X(ExtSlice, 18) \
X(Expr, 19) \
X(For, 20) \
X(FunctionDef, 21) \
X(GeneratorExp, 22) \
X(Global, 23) \
X(If, 24) \
X(IfExp, 25) \
X(Import, 26) \
X(ImportFrom, 27) \
X(Index, 28) \
X(keyword, 29) \
X(Lambda, 30) \
X(List, 31) \
X(ListComp, 32) \
X(Module, 33) \
X(Num, 34) \
X(Name, 35) \
X(Pass, 37) \
X(Pow, 38) \
X(Print, 39) \
X(Raise, 40) \
X(Repr, 41) \
X(Return, 42) \
X(Slice, 44) \
X(Str, 45) \
X(Subscript, 46) \
X(TryExcept, 47) \
X(TryFinally, 48) \
X(Tuple, 49) \
X(UnaryOp, 50) \
X(With, 51) \
X(While, 52) \
X(Yield, 53) \
X(Store, 54) \
X(Load, 55) \
X(Param, 56) \
X(Not, 57) \
X(In, 58) \
X(Is, 59) \
X(IsNot, 60) \
X(Or, 61) \
X(And, 62) \
X(Eq, 63) \
X(NotEq, 64) \
X(NotIn, 65) \
X(GtE, 66) \
X(Gt, 67) \
X(Mod, 68) \
X(Add, 69) \
X(Continue, 70) \
X(Lt, 71) \
X(LtE, 72) \
X(Break, 73) \
X(Sub, 74) \
X(Del, 75) \
X(Mult, 76) \
X(Div, 77) \
X(USub, 78) \
X(BitAnd, 79) \
X(BitOr, 80) \
X(BitXor, 81) \
X(RShift, 82) \
X(LShift, 83) \
X(Invert, 84) \
X(UAdd, 85) \
X(FloorDiv, 86) \
X(DictComp, 15) \
X(Set, 43) \
X(Ellipsis, 87) \
/* like Module, but used for eval. */ \
X(Expression, 88) \
X(SetComp, 89) \
X(Suite, 90) \
\
/* Pseudo-nodes that are specific to this compiler: */ \
X(Branch, 200) \
X(Jump, 201) \
X(ClsAttribute, 202) \
X(AugBinOp, 203) \
X(Invoke, 204) \
X(LangPrimitive, 205) \
/* wraps a ClassDef to make it an expr */ \
X(MakeClass, 206) \
/* wraps a FunctionDef to make it an expr */ \
X(MakeFunction, 207) \
\
/* These aren't real BST types, but since we use BST types to represent binexp types */ \
/* and divmod+truediv are essentially types of binops, we add them here (at least for now): */ \
X(DivMod, 250) \
X(TrueDiv, 251)
#define GENERATE_ENUM(ENUM, N) ENUM = N,
#define GENERATE_STRING(STRING, N) m[N] = #STRING;
enum BST_TYPE { FOREACH_TYPE(GENERATE_ENUM) };
static const char* stringify(int n) {
static std::map<int, const char*> m;
FOREACH_TYPE(GENERATE_STRING)
return m[n];
}
#undef FOREACH_TYPE
#undef GENERATE_ENUM
#undef GENERATE_STRING
};
class BSTVisitor;
class ExprVisitor;
class StmtVisitor;
class SliceVisitor;
class BST_keyword;
class BST {
public:
virtual ~BST() {}
const BST_TYPE::BST_TYPE type;
uint32_t lineno, col_offset;
virtual void accept(BSTVisitor* v) = 0;
// #define DEBUG_LINE_NUMBERS 1
#ifdef DEBUG_LINE_NUMBERS
private:
// Initialize lineno to something unique, so that if we see something ridiculous
// appear in the traceback, we can isolate the allocation which created it.
static int next_lineno;
public:
BST(BST_TYPE::BST_TYPE type);
#else
BST(BST_TYPE::BST_TYPE type) : type(type), lineno(0), col_offset(0) {}
#endif
BST(BST_TYPE::BST_TYPE type, uint32_t lineno, uint32_t col_offset = 0)
: type(type), lineno(lineno), col_offset(col_offset) {}
};
class BST_expr : public BST {
public:
virtual void* accept_expr(ExprVisitor* v) = 0;
BST_expr(BST_TYPE::BST_TYPE type) : BST(type) {}
BST_expr(BST_TYPE::BST_TYPE type, uint32_t lineno, uint32_t col_offset = 0) : BST(type, lineno, col_offset) {}
};
class BST_stmt : public BST {
public:
virtual void accept_stmt(StmtVisitor* v) = 0;
int cxx_exception_count = 0;
BST_stmt(BST_TYPE::BST_TYPE type) : BST(type) {}
};
class BST_slice : public BST {
public:
virtual void* accept_slice(SliceVisitor* s) = 0;
BST_slice(BST_TYPE::BST_TYPE type) : BST(type) {}
BST_slice(BST_TYPE::BST_TYPE type, uint32_t lineno, uint32_t col_offset = 0) : BST(type, lineno, col_offset) {}
};
class BST_alias : public BST {
public:
InternedString name, asname;
int name_vreg = -1, asname_vreg = -1;
virtual void accept(BSTVisitor* v);
BST_alias(InternedString name, InternedString asname) : BST(BST_TYPE::alias), name(name), asname(asname) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::alias;
};
class BST_Name;
class BST_arguments : public BST {
public:
// no lineno, col_offset attributes
std::vector<BST_expr*> args, defaults;
BST_Name* kwarg = NULL, * vararg = NULL;
virtual void accept(BSTVisitor* v);
BST_arguments() : BST(BST_TYPE::arguments) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::arguments;
};
class BST_Assert : public BST_stmt {
public:
BST_expr* msg, *test;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Assert() : BST_stmt(BST_TYPE::Assert) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Assert;
};
class BST_Assign : public BST_stmt {
public:
std::vector<BST_expr*> targets;
BST_expr* value;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Assign() : BST_stmt(BST_TYPE::Assign) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Assign;
};
class BST_AugAssign : public BST_stmt {
public:
BST_expr* value;
BST_expr* target;
BST_TYPE::BST_TYPE op_type;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_AugAssign() : BST_stmt(BST_TYPE::AugAssign) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::AugAssign;
};
class BST_AugBinOp : public BST_expr {
public:
BST_TYPE::BST_TYPE op_type;
BST_expr* left, *right;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_AugBinOp() : BST_expr(BST_TYPE::AugBinOp) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::AugBinOp;
};
class BST_Attribute : public BST_expr {
public:
BST_expr* value;
BST_TYPE::BST_TYPE ctx_type;
InternedString attr;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Attribute() : BST_expr(BST_TYPE::Attribute) {}
BST_Attribute(BST_expr* value, BST_TYPE::BST_TYPE ctx_type, InternedString attr)
: BST_expr(BST_TYPE::Attribute), value(value), ctx_type(ctx_type), attr(attr) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Attribute;
};
class BST_BinOp : public BST_expr {
public:
BST_TYPE::BST_TYPE op_type;
BST_expr* left, *right;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_BinOp() : BST_expr(BST_TYPE::BinOp) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::BinOp;
};
class BST_BoolOp : public BST_expr {
public:
BST_TYPE::BST_TYPE op_type;
std::vector<BST_expr*> values;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_BoolOp() : BST_expr(BST_TYPE::BoolOp) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::BoolOp;
};
class BST_Break : public BST_stmt {
public:
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Break() : BST_stmt(BST_TYPE::Break) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Break;
};
class BST_Call : public BST_expr {
public:
BST_expr* starargs, *kwargs, *func;
std::vector<BST_expr*> args;
std::vector<BST_keyword*> keywords;
// used during execution stores all keyword names
std::unique_ptr<std::vector<BoxedString*>> keywords_names;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Call() : BST_expr(BST_TYPE::Call) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Call;
};
class BST_Compare : public BST_expr {
public:
std::vector<BST_TYPE::BST_TYPE> ops;
std::vector<BST_expr*> comparators;
BST_expr* left;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Compare() : BST_expr(BST_TYPE::Compare) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Compare;
};
class BST_comprehension : public BST {
public:
BST_expr* target;
BST_expr* iter;
std::vector<BST_expr*> ifs;
virtual void accept(BSTVisitor* v);
BST_comprehension() : BST(BST_TYPE::comprehension) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::comprehension;
};
class BST_ClassDef : public BST_stmt {
public:
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
std::vector<BST_expr*> bases, decorator_list;
std::vector<BST_stmt*> body;
InternedString name;
BoxedCode* code;
BST_ClassDef() : BST_stmt(BST_TYPE::ClassDef) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::ClassDef;
};
class BST_Continue : public BST_stmt {
public:
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Continue() : BST_stmt(BST_TYPE::Continue) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Continue;
};
class BST_Dict : public BST_expr {
public:
std::vector<BST_expr*> keys, values;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Dict() : BST_expr(BST_TYPE::Dict) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Dict;
};
class BST_DictComp : public BST_expr {
public:
std::vector<BST_comprehension*> generators;
BST_expr* key, *value;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_DictComp() : BST_expr(BST_TYPE::DictComp) {}
const static BST_TYPE::BST_TYPE TYPE = BST_TYPE::DictComp;
};
class BST_Delete : public BST_stmt {
public:
std::vector<BST_expr*> targets;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Delete() : BST_stmt(BST_TYPE::Delete) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Delete;
};
class BST_Ellipsis : public BST_slice {
public:
virtual void accept(BSTVisitor* v);
virtual void* accept_slice(SliceVisitor* v);
BST_Ellipsis() : BST_slice(BST_TYPE::Ellipsis) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Ellipsis;
};
class BST_Expr : public BST_stmt {
public:
BST_expr* value;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Expr() : BST_stmt(BST_TYPE::Expr) {}
BST_Expr(BST_expr* value) : BST_stmt(BST_TYPE::Expr), value(value) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Expr;
};
class BST_ExceptHandler : public BST {
public:
std::vector<BST_stmt*> body;
BST_expr* type; // can be NULL for a bare "except:" clause
BST_expr* name; // can be NULL if the exception doesn't get a name
virtual void accept(BSTVisitor* v);
BST_ExceptHandler() : BST(BST_TYPE::ExceptHandler) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::ExceptHandler;
};
class BST_Exec : public BST_stmt {
public:
BST_expr* body;
BST_expr* globals;
BST_expr* locals;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Exec() : BST_stmt(BST_TYPE::Exec) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Exec;
};
// (Alternative to BST_Module, used for, e.g., eval)
class BST_Expression : public BST {
public:
std::unique_ptr<InternedStringPool> interned_strings;
// this should be an expr but we convert it into a BST_Return(BST_expr) to make the code simpler
BST_stmt* body;
BoxedCode* code;
virtual void accept(BSTVisitor* v);
BST_Expression(std::unique_ptr<InternedStringPool> interned_strings)
: BST(BST_TYPE::Expression), interned_strings(std::move(interned_strings)) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Expression;
};
class BST_ExtSlice : public BST_slice {
public:
std::vector<BST_slice*> dims;
virtual void accept(BSTVisitor* v);
virtual void* accept_slice(SliceVisitor* v);
BST_ExtSlice() : BST_slice(BST_TYPE::ExtSlice) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::ExtSlice;
};
class BST_For : public BST_stmt {
public:
std::vector<BST_stmt*> body, orelse;
BST_expr* target, *iter;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_For() : BST_stmt(BST_TYPE::For) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::For;
};
class BST_FunctionDef : public BST_stmt {
public:
std::vector<BST_stmt*> body;
std::vector<BST_expr*> decorator_list;
InternedString name; // if the name is not set this is a lambda
BST_arguments* args;
BoxedCode* code;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_FunctionDef() : BST_stmt(BST_TYPE::FunctionDef) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::FunctionDef;
};
class BST_GeneratorExp : public BST_expr {
public:
std::vector<BST_comprehension*> generators;
BST_expr* elt;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_GeneratorExp() : BST_expr(BST_TYPE::GeneratorExp) {}
const static BST_TYPE::BST_TYPE TYPE = BST_TYPE::GeneratorExp;
};
class BST_Global : public BST_stmt {
public:
std::vector<InternedString> names;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Global() : BST_stmt(BST_TYPE::Global) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Global;
};
class BST_If : public BST_stmt {
public:
std::vector<BST_stmt*> body, orelse;
BST_expr* test;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_If() : BST_stmt(BST_TYPE::If) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::If;
};
class BST_IfExp : public BST_expr {
public:
BST_expr* body, *test, *orelse;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_IfExp() : BST_expr(BST_TYPE::IfExp) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::IfExp;
};
class BST_Import : public BST_stmt {
public:
std::vector<BST_alias*> names;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Import() : BST_stmt(BST_TYPE::Import) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Import;
};
class BST_ImportFrom : public BST_stmt {
public:
InternedString module;
std::vector<BST_alias*> names;
int level;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_ImportFrom() : BST_stmt(BST_TYPE::ImportFrom) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::ImportFrom;
};
class BST_Index : public BST_slice {
public:
BST_expr* value;
virtual void accept(BSTVisitor* v);
virtual void* accept_slice(SliceVisitor* v);
BST_Index() : BST_slice(BST_TYPE::Index) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Index;
};
class BST_keyword : public BST {
public:
// no lineno, col_offset attributes
BST_expr* value;
InternedString arg;
virtual void accept(BSTVisitor* v);
BST_keyword() : BST(BST_TYPE::keyword) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::keyword;
};
class BST_Lambda : public BST_expr {
public:
BST_arguments* args;
BST_expr* body;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Lambda() : BST_expr(BST_TYPE::Lambda) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Lambda;
};
class BST_List : public BST_expr {
public:
std::vector<BST_expr*> elts;
BST_TYPE::BST_TYPE ctx_type;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_List() : BST_expr(BST_TYPE::List) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::List;
};
class BST_ListComp : public BST_expr {
public:
std::vector<BST_comprehension*> generators;
BST_expr* elt;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_ListComp() : BST_expr(BST_TYPE::ListComp) {}
const static BST_TYPE::BST_TYPE TYPE = BST_TYPE::ListComp;
};
class BST_Module : public BST {
public:
std::unique_ptr<InternedStringPool> interned_strings;
// no lineno, col_offset attributes
std::vector<BST_stmt*> body;
BoxedCode* code;
virtual void accept(BSTVisitor* v);
BST_Module(std::unique_ptr<InternedStringPool> interned_strings)
: BST(BST_TYPE::Module), interned_strings(std::move(interned_strings)) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Module;
};
class BST_Suite : public BST {
public:
std::unique_ptr<InternedStringPool> interned_strings;
std::vector<BST_stmt*> body;
virtual void accept(BSTVisitor* v);
BST_Suite(std::unique_ptr<InternedStringPool> interned_strings)
: BST(BST_TYPE::Suite), interned_strings(std::move(interned_strings)) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Suite;
};
class BST_Name : public BST_expr {
public:
BST_TYPE::BST_TYPE ctx_type;
InternedString id;
// The resolved scope of this name. Kind of hacky to be storing it in the BST node;
// in CPython it ends up getting "cached" by being translated into one of a number of
// different bytecodes.
ScopeInfo::VarScopeType lookup_type;
// These are only valid for lookup_type == FBST or CLOSURE
// The interpreter and baseline JIT store variables with FBST and CLOSURE scopes in an array (vregs) this specifies
// the zero based index of this variable inside the vregs array. If uninitialized it's value is -1.
int vreg;
bool is_kill = false;
// Only valid for lookup_type == DEREF:
DerefInfo deref_info = DerefInfo({ INT_MAX, INT_MAX });
// Only valid for lookup_type == CLOSURE:
int closure_offset = -1;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Name(InternedString id, BST_TYPE::BST_TYPE ctx_type, int lineno, int col_offset = 0)
: BST_expr(BST_TYPE::Name, lineno, col_offset),
ctx_type(ctx_type),
id(id),
lookup_type(ScopeInfo::VarScopeType::UNKNOWN),
vreg(-1) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Name;
};
class BST_Num : public BST_expr {
public:
enum NumType {
// These values must correspond to the values in parse_ast.py
INT = 0x10,
FLOAT = 0x20,
LONG = 0x30,
// for COMPLEX, n_float is the imaginary part, real part is 0
COMPLEX = 0x40,
} num_type;
union {
int64_t n_int;
double n_float;
};
std::string n_long;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Num() : BST_expr(BST_TYPE::Num) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Num;
};
class BST_Repr : public BST_expr {
public:
BST_expr* value;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Repr() : BST_expr(BST_TYPE::Repr) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Repr;
};
class BST_Pass : public BST_stmt {
public:
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Pass() : BST_stmt(BST_TYPE::Pass) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Pass;
};
class BST_Print : public BST_stmt {
public:
BST_expr* dest;
bool nl;
std::vector<BST_expr*> values;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Print() : BST_stmt(BST_TYPE::Print) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Print;
};
class BST_Raise : public BST_stmt {
public:
// In the python ast module, these are called "type", "inst", and "tback", respectively.
// Renaming to arg{0..2} since I find that confusing, since they are filled in
// sequentially rather than semantically.
// Ie "raise Exception()" will have type==Exception(), inst==None, tback==None
BST_expr* arg0, *arg1, *arg2;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Raise() : BST_stmt(BST_TYPE::Raise), arg0(NULL), arg1(NULL), arg2(NULL) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Raise;
};
class BST_Return : public BST_stmt {
public:
BST_expr* value;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Return() : BST_stmt(BST_TYPE::Return) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Return;
};
class BST_Set : public BST_expr {
public:
std::vector<BST_expr*> elts;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Set() : BST_expr(BST_TYPE::Set) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Set;
};
class BST_SetComp : public BST_expr {
public:
std::vector<BST_comprehension*> generators;
BST_expr* elt;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_SetComp() : BST_expr(BST_TYPE::SetComp) {}
const static BST_TYPE::BST_TYPE TYPE = BST_TYPE::SetComp;
};
class BST_Slice : public BST_slice {
public:
BST_expr* lower, *upper, *step;
virtual void accept(BSTVisitor* v);
virtual void* accept_slice(SliceVisitor* v);
BST_Slice() : BST_slice(BST_TYPE::Slice) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Slice;
};
class BST_Str : public BST_expr {
public:
enum StrType {
UNSET = 0x00,
STR = 0x10,
UNICODE = 0x20,
} str_type;
// The meaning of str_data depends on str_type. For STR, it's just the bytes value.
// For UNICODE, it's the utf-8 encoded value.
std::string str_data;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Str() : BST_expr(BST_TYPE::Str), str_type(UNSET) {}
BST_Str(std::string s) : BST_expr(BST_TYPE::Str), str_type(STR), str_data(std::move(s)) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Str;
};
class BST_Subscript : public BST_expr {
public:
BST_expr* value;
BST_slice* slice;
BST_TYPE::BST_TYPE ctx_type;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Subscript() : BST_expr(BST_TYPE::Subscript) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Subscript;
};
class BST_TryExcept : public BST_stmt {
public:
std::vector<BST_stmt*> body, orelse;
std::vector<BST_ExceptHandler*> handlers;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_TryExcept() : BST_stmt(BST_TYPE::TryExcept) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::TryExcept;
};
class BST_TryFinally : public BST_stmt {
public:
std::vector<BST_stmt*> body, finalbody;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_TryFinally() : BST_stmt(BST_TYPE::TryFinally) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::TryFinally;
};
class BST_Tuple : public BST_expr {
public:
std::vector<BST_expr*> elts;
BST_TYPE::BST_TYPE ctx_type;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Tuple() : BST_expr(BST_TYPE::Tuple) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Tuple;
};
class BST_UnaryOp : public BST_expr {
public:
BST_expr* operand;
BST_TYPE::BST_TYPE op_type;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_UnaryOp() : BST_expr(BST_TYPE::UnaryOp) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::UnaryOp;
};
class BST_While : public BST_stmt {
public:
BST_expr* test;
std::vector<BST_stmt*> body, orelse;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_While() : BST_stmt(BST_TYPE::While) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::While;
};
class BST_With : public BST_stmt {
public:
BST_expr* optional_vars, *context_expr;
std::vector<BST_stmt*> body;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_With() : BST_stmt(BST_TYPE::With) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::With;
};
class BST_Yield : public BST_expr {
public:
BST_expr* value;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_Yield() : BST_expr(BST_TYPE::Yield) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Yield;
};
class BST_MakeFunction : public BST_expr {
public:
BST_FunctionDef* function_def;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_MakeFunction(BST_FunctionDef* fd)
: BST_expr(BST_TYPE::MakeFunction, fd->lineno, fd->col_offset), function_def(fd) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::MakeFunction;
};
class BST_MakeClass : public BST_expr {
public:
BST_ClassDef* class_def;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_MakeClass(BST_ClassDef* cd) : BST_expr(BST_TYPE::MakeClass, cd->lineno, cd->col_offset), class_def(cd) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::MakeClass;
};
// BST pseudo-nodes that will get added during CFG-construction. These don't exist in the input BST, but adding them in
// lets us avoid creating a completely new IR for this phase
class CFGBlock;
class BST_Branch : public BST_stmt {
public:
BST_expr* test;
CFGBlock* iftrue, *iffalse;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Branch() : BST_stmt(BST_TYPE::Branch) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Branch;
};
class BST_Jump : public BST_stmt {
public:
CFGBlock* target;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Jump() : BST_stmt(BST_TYPE::Jump) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Jump;
};
class BST_ClsAttribute : public BST_expr {
public:
BST_expr* value;
InternedString attr;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_ClsAttribute() : BST_expr(BST_TYPE::ClsAttribute) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::ClsAttribute;
};
class BST_Invoke : public BST_stmt {
public:
BST_stmt* stmt;
CFGBlock* normal_dest, *exc_dest;
virtual void accept(BSTVisitor* v);
virtual void accept_stmt(StmtVisitor* v);
BST_Invoke(BST_stmt* stmt) : BST_stmt(BST_TYPE::Invoke), stmt(stmt) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Invoke;
};
// "LangPrimitive" represents operations that "primitive" to the language,
// but aren't directly *exactly* representable as normal Python.
// ClsAttribute would fall into this category.
// These are basically bytecodes, framed as pseudo-BST-nodes.
class BST_LangPrimitive : public BST_expr {
public:
enum Opcodes {
LANDINGPAD, // grabs the info about the last raised exception
LOCALS,
GET_ITER,
IMPORT_FROM,
IMPORT_NAME,
IMPORT_STAR,
NONE,
NONZERO, // determines whether something is "true" for purposes of `if' and so forth
CHECK_EXC_MATCH,
SET_EXC_INFO,
UNCACHE_EXC_INFO,
HASNEXT,
PRINT_EXPR,
} opcode;
std::vector<BST_expr*> args;
virtual void accept(BSTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
BST_LangPrimitive(Opcodes opcode) : BST_expr(BST_TYPE::LangPrimitive), opcode(opcode) {}
static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::LangPrimitive;
};
template <typename T> T* bst_cast(BST* node) {
ASSERT(!node || node->type == T::TYPE, "%d", node ? node->type : 0);
return static_cast<T*>(node);
}
class BSTVisitor {
protected:
public:
virtual ~BSTVisitor() {}
virtual bool visit_alias(BST_alias* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_arguments(BST_arguments* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_assert(BST_Assert* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_assign(BST_Assign* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_augassign(BST_AugAssign* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_augbinop(BST_AugBinOp* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_attribute(BST_Attribute* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_binop(BST_BinOp* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_boolop(BST_BoolOp* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_break(BST_Break* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_call(BST_Call* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_clsattribute(BST_ClsAttribute* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_compare(BST_Compare* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_comprehension(BST_comprehension* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_classdef(BST_ClassDef* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_continue(BST_Continue* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_delete(BST_Delete* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_dict(BST_Dict* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_dictcomp(BST_DictComp* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_ellipsis(BST_Ellipsis* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_excepthandler(BST_ExceptHandler* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_exec(BST_Exec* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_expr(BST_Expr* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_expression(BST_Expression* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_suite(BST_Suite* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_extslice(BST_ExtSlice* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_for(BST_For* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_functiondef(BST_FunctionDef* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_generatorexp(BST_GeneratorExp* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_global(BST_Global* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_if(BST_If* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_ifexp(BST_IfExp* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_import(BST_Import* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_importfrom(BST_ImportFrom* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_index(BST_Index* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_invoke(BST_Invoke* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_keyword(BST_keyword* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_lambda(BST_Lambda* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_langprimitive(BST_LangPrimitive* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_list(BST_List* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_listcomp(BST_ListComp* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_module(BST_Module* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_name(BST_Name* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_num(BST_Num* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_pass(BST_Pass* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_print(BST_Print* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_raise(BST_Raise* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_repr(BST_Repr* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_return(BST_Return* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_set(BST_Set* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_setcomp(BST_SetComp* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_slice(BST_Slice* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_str(BST_Str* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_subscript(BST_Subscript* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_tryexcept(BST_TryExcept* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_tryfinally(BST_TryFinally* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_tuple(BST_Tuple* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_unaryop(BST_UnaryOp* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_while(BST_While* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_with(BST_With* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_yield(BST_Yield* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_makeclass(BST_MakeClass* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_makefunction(BST_MakeFunction* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_branch(BST_Branch* node) { RELEASE_ASSERT(0, ""); }
virtual bool visit_jump(BST_Jump* node) { RELEASE_ASSERT(0, ""); }
};
class NoopBSTVisitor : public BSTVisitor {
protected:
public:
virtual ~NoopBSTVisitor() {}
virtual bool visit_alias(BST_alias* node) { return false; }
virtual bool visit_arguments(BST_arguments* node) { return false; }
virtual bool visit_assert(BST_Assert* node) { return false; }
virtual bool visit_assign(BST_Assign* node) { return false; }
virtual bool visit_augassign(BST_AugAssign* node) { return false; }
virtual bool visit_augbinop(BST_AugBinOp* node) { return false; }
virtual bool visit_attribute(BST_Attribute* node) { return false; }
virtual bool visit_binop(BST_BinOp* node) { return false; }
virtual bool visit_boolop(BST_BoolOp* node) { return false; }
virtual bool visit_break(BST_Break* node) { return false; }
virtual bool visit_call(BST_Call* node) { return false; }
virtual bool visit_clsattribute(BST_ClsAttribute* node) { return false; }
virtual bool visit_compare(BST_Compare* node) { return false; }
virtual bool visit_comprehension(BST_comprehension* node) { return false; }
virtual bool visit_classdef(BST_ClassDef* node) { return false; }
virtual bool visit_continue(BST_Continue* node) { return false; }
virtual bool visit_delete(BST_Delete* node) { return false; }
virtual bool visit_dict(BST_Dict* node) { return false; }
virtual bool visit_dictcomp(BST_DictComp* node) { return false; }
virtual bool visit_ellipsis(BST_Ellipsis* node) { return false; }
virtual bool visit_excepthandler(BST_ExceptHandler* node) { return false; }
virtual bool visit_exec(BST_Exec* node) { return false; }
virtual bool visit_expr(BST_Expr* node) { return false; }
virtual bool visit_expression(BST_Expression* node) { return false; }
virtual bool visit_suite(BST_Suite* node) { return false; }
virtual bool visit_extslice(BST_ExtSlice* node) { return false; }
virtual bool visit_for(BST_For* node) { return false; }
virtual bool visit_functiondef(BST_FunctionDef* node) { return false; }
virtual bool visit_generatorexp(BST_GeneratorExp* node) { return false; }
virtual bool visit_global(BST_Global* node) { return false; }
virtual bool visit_if(BST_If* node) { return false; }
virtual bool visit_ifexp(BST_IfExp* node) { return false; }
virtual bool visit_import(BST_Import* node) { return false; }
virtual bool visit_importfrom(BST_ImportFrom* node) { return false; }
virtual bool visit_index(BST_Index* node) { return false; }
virtual bool visit_invoke(BST_Invoke* node) { return false; }
virtual bool visit_keyword(BST_keyword* node) { return false; }
virtual bool visit_lambda(BST_Lambda* node) { return false; }
virtual bool visit_langprimitive(BST_LangPrimitive* node) { return false; }
virtual bool visit_list(BST_List* node) { return false; }
virtual bool visit_listcomp(BST_ListComp* node) { return false; }
virtual bool visit_module(BST_Module* node) { return false; }
virtual bool visit_name(BST_Name* node) { return false; }
virtual bool visit_num(BST_Num* node) { return false; }
virtual bool visit_pass(BST_Pass* node) { return false; }
virtual bool visit_print(BST_Print* node) { return false; }
virtual bool visit_raise(BST_Raise* node) { return false; }
virtual bool visit_repr(BST_Repr* node) { return false; }
virtual bool visit_return(BST_Return* node) { return false; }
virtual bool visit_set(BST_Set* node) { return false; }
virtual bool visit_setcomp(BST_SetComp* node) { return false; }
virtual bool visit_slice(BST_Slice* node) { return false; }
virtual bool visit_str(BST_Str* node) { return false; }
virtual bool visit_subscript(BST_Subscript* node) { return false; }
virtual bool visit_tryexcept(BST_TryExcept* node) { return false; }
virtual bool visit_tryfinally(BST_TryFinally* node) { return false; }
virtual bool visit_tuple(BST_Tuple* node) { return false; }
virtual bool visit_unaryop(BST_UnaryOp* node) { return false; }
virtual bool visit_while(BST_While* node) { return false; }
virtual bool visit_with(BST_With* node) { return false; }
virtual bool visit_yield(BST_Yield* node) { return false; }
virtual bool visit_branch(BST_Branch* node) { return false; }
virtual bool visit_jump(BST_Jump* node) { return false; }
virtual bool visit_makeclass(BST_MakeClass* node) { return false; }
virtual bool visit_makefunction(BST_MakeFunction* node) { return false; }
};
class ExprVisitor {
protected:
public:
virtual ~ExprVisitor() {}
virtual void* visit_augbinop(BST_AugBinOp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_attribute(BST_Attribute* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_binop(BST_BinOp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_boolop(BST_BoolOp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_call(BST_Call* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_clsattribute(BST_ClsAttribute* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_compare(BST_Compare* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_dict(BST_Dict* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_dictcomp(BST_DictComp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_generatorexp(BST_GeneratorExp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_ifexp(BST_IfExp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_lambda(BST_Lambda* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_langprimitive(BST_LangPrimitive* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_list(BST_List* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_listcomp(BST_ListComp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_name(BST_Name* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_num(BST_Num* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_repr(BST_Repr* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_set(BST_Set* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_setcomp(BST_SetComp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_str(BST_Str* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_subscript(BST_Subscript* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_tuple(BST_Tuple* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_unaryop(BST_UnaryOp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_yield(BST_Yield* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_makeclass(BST_MakeClass* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_makefunction(BST_MakeFunction* node) { RELEASE_ASSERT(0, ""); }
};
class StmtVisitor {
protected:
public:
virtual ~StmtVisitor() {}
virtual void visit_assert(BST_Assert* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_assign(BST_Assign* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_augassign(BST_AugAssign* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_break(BST_Break* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_classdef(BST_ClassDef* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_delete(BST_Delete* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_continue(BST_Continue* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_exec(BST_Exec* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_expr(BST_Expr* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_for(BST_For* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_functiondef(BST_FunctionDef* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_global(BST_Global* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_if(BST_If* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_import(BST_Import* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_importfrom(BST_ImportFrom* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_invoke(BST_Invoke* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_pass(BST_Pass* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_print(BST_Print* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_raise(BST_Raise* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_return(BST_Return* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_tryexcept(BST_TryExcept* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_tryfinally(BST_TryFinally* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_while(BST_While* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_with(BST_With* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_branch(BST_Branch* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_jump(BST_Jump* node) { RELEASE_ASSERT(0, ""); }
};
class SliceVisitor {
public:
virtual ~SliceVisitor() {}
virtual void* visit_ellipsis(BST_Ellipsis* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_extslice(BST_ExtSlice* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_index(BST_Index* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_slice(BST_Slice* node) { RELEASE_ASSERT(0, ""); }
};
void print_bst(BST* bst);
class PrintVisitor : public BSTVisitor {
private:
llvm::raw_ostream& stream;
int indent;
void printIndent();
void printOp(BST_TYPE::BST_TYPE op_type);
public:
PrintVisitor(int indent = 0, llvm::raw_ostream& stream = llvm::outs()) : stream(stream), indent(indent) {}
virtual ~PrintVisitor() {}
void flush() { stream.flush(); }
virtual bool visit_alias(BST_alias* node);
virtual bool visit_arguments(BST_arguments* node);
virtual bool visit_assert(BST_Assert* node);
virtual bool visit_assign(BST_Assign* node);
virtual bool visit_augassign(BST_AugAssign* node);
virtual bool visit_augbinop(BST_AugBinOp* node);
virtual bool visit_attribute(BST_Attribute* node);
virtual bool visit_binop(BST_BinOp* node);
virtual bool visit_boolop(BST_BoolOp* node);
virtual bool visit_break(BST_Break* node);
virtual bool visit_call(BST_Call* node);
virtual bool visit_compare(BST_Compare* node);
virtual bool visit_comprehension(BST_comprehension* node);
virtual bool visit_classdef(BST_ClassDef* node);
virtual bool visit_clsattribute(BST_ClsAttribute* node);
virtual bool visit_continue(BST_Continue* node);
virtual bool visit_delete(BST_Delete* node);
virtual bool visit_dict(BST_Dict* node);
virtual bool visit_dictcomp(BST_DictComp* node);
virtual bool visit_ellipsis(BST_Ellipsis* node);
virtual bool visit_excepthandler(BST_ExceptHandler* node);
virtual bool visit_exec(BST_Exec* node);
virtual bool visit_expr(BST_Expr* node);
virtual bool visit_expression(BST_Expression* node);
virtual bool visit_suite(BST_Suite* node);
virtual bool visit_extslice(BST_ExtSlice* node);
virtual bool visit_for(BST_For* node);
virtual bool visit_functiondef(BST_FunctionDef* node);
virtual bool visit_generatorexp(BST_GeneratorExp* node);
virtual bool visit_global(BST_Global* node);
virtual bool visit_if(BST_If* node);
virtual bool visit_ifexp(BST_IfExp* node);
virtual bool visit_import(BST_Import* node);
virtual bool visit_importfrom(BST_ImportFrom* node);
virtual bool visit_index(BST_Index* node);
virtual bool visit_invoke(BST_Invoke* node);
virtual bool visit_keyword(BST_keyword* node);
virtual bool visit_lambda(BST_Lambda* node);
virtual bool visit_langprimitive(BST_LangPrimitive* node);
virtual bool visit_list(BST_List* node);
virtual bool visit_listcomp(BST_ListComp* node);
virtual bool visit_module(BST_Module* node);
virtual bool visit_name(BST_Name* node);
virtual bool visit_num(BST_Num* node);
virtual bool visit_pass(BST_Pass* node);
virtual bool visit_print(BST_Print* node);
virtual bool visit_raise(BST_Raise* node);
virtual bool visit_repr(BST_Repr* node);
virtual bool visit_return(BST_Return* node);
virtual bool visit_set(BST_Set* node);
virtual bool visit_setcomp(BST_SetComp* node);
virtual bool visit_slice(BST_Slice* node);
virtual bool visit_str(BST_Str* node);
virtual bool visit_subscript(BST_Subscript* node);
virtual bool visit_tuple(BST_Tuple* node);
virtual bool visit_tryexcept(BST_TryExcept* node);
virtual bool visit_tryfinally(BST_TryFinally* node);
virtual bool visit_unaryop(BST_UnaryOp* node);
virtual bool visit_while(BST_While* node);
virtual bool visit_with(BST_With* node);
virtual bool visit_yield(BST_Yield* node);
virtual bool visit_branch(BST_Branch* node);
virtual bool visit_jump(BST_Jump* node);
virtual bool visit_makefunction(BST_MakeFunction* node);
virtual bool visit_makeclass(BST_MakeClass* node);
};
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment