diff --git a/src/analysis/function_analysis.cpp b/src/analysis/function_analysis.cpp
index 697ebe50835891b1d7b7bab2b1240b27d910e482..b6f23ce91600eb52bf896f3c4ef48567a517aa43 100644
--- a/src/analysis/function_analysis.cpp
+++ b/src/analysis/function_analysis.cpp
@@ -78,8 +78,6 @@ public:
 
     bool isKilledAt(BST_Name* node, bool is_live_at_end) { return node->is_kill; }
 
-    bool visit_import(BST_Import* node) { RELEASE_ASSERT(0, "these should all get removed by the cfg"); }
-
     bool visit_classdef(BST_ClassDef* node) {
         for (auto e : node->bases)
             e->accept(this);
@@ -118,8 +116,6 @@ public:
         }
         return true;
     }
-
-    bool visit_alias(BST_alias* node) { RELEASE_ASSERT(0, "these should be removed by the cfg"); }
 };
 
 LivenessAnalysis::LivenessAnalysis(CFG* cfg) : cfg(cfg), result_cache(cfg->getVRegInfo().getTotalNumOfVRegs()) {
@@ -282,30 +278,27 @@ public:
     virtual bool visit_assert(BST_Assert* node) { return true; }
     virtual bool visit_branch(BST_Branch* node) { return true; }
     virtual bool visit_expr(BST_Expr* node) { return true; }
-    virtual bool visit_global(BST_Global* node) { return true; }
     virtual bool visit_invoke(BST_Invoke* node) { return false; }
     virtual bool visit_jump(BST_Jump* node) { return true; }
-    virtual bool visit_pass(BST_Pass* node) { return true; }
     virtual bool visit_print(BST_Print* node) { return true; }
     virtual bool visit_raise(BST_Raise* node) { return true; }
     virtual bool visit_return(BST_Return* node) { return true; }
 
     virtual bool visit_delete(BST_Delete* node) {
-        for (auto t : node->targets) {
-            if (t->type == BST_TYPE::Name) {
-                BST_Name* name = bst_cast<BST_Name>(t);
-                if (name->lookup_type != ScopeInfo::VarScopeType::GLOBAL
-                    && name->lookup_type != ScopeInfo::VarScopeType::NAME) {
-                    assert(name->vreg != -1);
-                    state[name->vreg] = DefinednessAnalysis::Undefined;
-                } else
-                    assert(name->vreg == -1);
-            } else {
-                // The CFG pass should reduce all deletes to the "basic" deletes on names/attributes/subscripts.
-                // If not, probably the best way to do this would be to just do a full BST traversal
-                // and look for BST_Name's with a ctx of Del
-                assert(t->type == BST_TYPE::Attribute || t->type == BST_TYPE::Subscript);
-            }
+        auto t = node->target;
+        if (t->type == BST_TYPE::Name) {
+            BST_Name* name = bst_cast<BST_Name>(t);
+            if (name->lookup_type != ScopeInfo::VarScopeType::GLOBAL
+                && name->lookup_type != ScopeInfo::VarScopeType::NAME) {
+                assert(name->vreg != -1);
+                state[name->vreg] = DefinednessAnalysis::Undefined;
+            } else
+                assert(name->vreg == -1);
+        } else {
+            // The CFG pass should reduce all deletes to the "basic" deletes on names/attributes/subscripts.
+            // If not, probably the best way to do this would be to just do a full BST traversal
+            // and look for BST_Name's with a ctx of Del
+            assert(t->type == BST_TYPE::Attribute || t->type == BST_TYPE::Subscript);
         }
         return true;
     }
@@ -322,21 +315,8 @@ public:
         return true;
     }
 
-    virtual bool visit_alias(BST_alias* node) {
-        int vreg = node->name_vreg;
-        if (node->asname.s().size())
-            vreg = node->asname_vreg;
-
-        _doSet(vreg);
-        return true;
-    }
-    virtual bool visit_import(BST_Import* node) { return false; }
-    virtual bool visit_importfrom(BST_ImportFrom* node) { return false; }
-
     virtual bool visit_assign(BST_Assign* node) {
-        for (int i = 0; i < node->targets.size(); i++) {
-            _doSet(node->targets[i]);
-        }
+        _doSet(node->target);
         return true;
     }
 
diff --git a/src/analysis/scoping_analysis.cpp b/src/analysis/scoping_analysis.cpp
index fd92541f8fd1ca7c26040d9e32e85aaca6d4683e..1abe93f9c987da519ecc72fc9260683809c2833a 100644
--- a/src/analysis/scoping_analysis.cpp
+++ b/src/analysis/scoping_analysis.cpp
@@ -606,8 +606,6 @@ public:
     bool visit_while(AST_While* node) override { return false; }
     bool visit_with(AST_With* node) override { return false; }
     bool visit_yield(AST_Yield* node) override { return false; }
-    bool visit_branch(AST_Branch* node) override { return false; }
-    bool visit_jump(AST_Jump* node) override { return false; }
     bool visit_delete(AST_Delete* node) override { return false; }
 
     bool visit_global(AST_Global* node) override {
diff --git a/src/analysis/type_analysis.cpp b/src/analysis/type_analysis.cpp
index 0e9585487afec6a09f9e5d3fc8924a3fd78a6f9a..18f8fbcfc85f8340c9bb3c80c27d7e7a9a46926b 100644
--- a/src/analysis/type_analysis.cpp
+++ b/src/analysis/type_analysis.cpp
@@ -297,21 +297,6 @@ private:
         return rtn;
     }
 
-    void* visit_boolop(BST_BoolOp* node) override {
-        int n = node->values.size();
-
-        CompilerType* rtn = NULL;
-        for (int i = 0; i < n; i++) {
-            CompilerType* t = getType(node->values[i]);
-            if (rtn == NULL)
-                rtn = t;
-            else if (rtn != t)
-                rtn = UNKNOWN;
-        }
-
-        return rtn;
-    }
-
     void* visit_call(BST_Call* node) override {
         CompilerType* func = getType(node->func);
 
@@ -349,29 +334,24 @@ private:
     }
 
     void* visit_compare(BST_Compare* node) override {
-        if (node->ops.size() == 1) {
-            CompilerType* left = getType(node->left);
-            CompilerType* right = getType(node->comparators[0]);
-
-            AST_TYPE::AST_TYPE op_type = node->ops[0];
-            if (op_type == AST_TYPE::Is || op_type == AST_TYPE::IsNot || op_type == AST_TYPE::In
-                || op_type == AST_TYPE::NotIn) {
-                assert(node->ops.size() == 1 && "I don't think this should happen");
-                return BOOL;
-            }
+        CompilerType* left = getType(node->left);
+        CompilerType* right = getType(node->comparator);
+
+        AST_TYPE::AST_TYPE op_type = node->op;
+        if (op_type == AST_TYPE::Is || op_type == AST_TYPE::IsNot || op_type == AST_TYPE::In
+            || op_type == AST_TYPE::NotIn) {
+            return BOOL;
+        }
 
-            BoxedString* name = getOpName(node->ops[0]);
-            CompilerType* attr_type = left->getattrType(name, true);
+        BoxedString* name = getOpName(node->op);
+        CompilerType* attr_type = left->getattrType(name, true);
 
-            if (attr_type == UNDEF)
-                attr_type = UNKNOWN;
+        if (attr_type == UNDEF)
+            attr_type = UNKNOWN;
 
-            std::vector<CompilerType*> arg_types;
-            arg_types.push_back(right);
-            return attr_type->callType(ArgPassSpec(2), arg_types, NULL);
-        } else {
-            return UNKNOWN;
-        }
+        std::vector<CompilerType*> arg_types;
+        arg_types.push_back(right);
+        return attr_type->callType(ArgPassSpec(2), arg_types, NULL);
     }
 
     void* visit_dict(BST_Dict* node) override {
@@ -541,9 +521,7 @@ private:
 
     void visit_assign(BST_Assign* node) override {
         CompilerType* t = getType(node->value);
-        for (int i = 0; i < node->targets.size(); i++) {
-            _doSet(node->targets[i], t);
-        }
+        _doSet(node->target, t);
     }
 
     void visit_branch(BST_Branch* node) override {
@@ -569,27 +547,26 @@ private:
     }
 
     void visit_delete(BST_Delete* node) override {
-        for (BST_expr* target : node->targets) {
-            switch (target->type) {
-                case BST_TYPE::Subscript:
-                    getType(bst_cast<BST_Subscript>(target)->value);
-                    break;
-                case BST_TYPE::Attribute:
-                    getType(bst_cast<BST_Attribute>(target)->value);
-                    break;
-                case BST_TYPE::Name: {
-                    auto name = bst_cast<BST_Name>(target);
-                    assert(name->lookup_type != ScopeInfo::VarScopeType::UNKNOWN);
-                    if (name->lookup_type == ScopeInfo::VarScopeType::FAST
-                        || name->lookup_type == ScopeInfo::VarScopeType::CLOSURE) {
-                        sym_table[name->vreg] = NULL;
-                    } else
-                        assert(name->vreg == -1);
-                    break;
-                }
-                default:
-                    RELEASE_ASSERT(0, "%d", target->type);
+        BST_expr* target = node->target;
+        switch (target->type) {
+            case BST_TYPE::Subscript:
+                getType(bst_cast<BST_Subscript>(target)->value);
+                break;
+            case BST_TYPE::Attribute:
+                getType(bst_cast<BST_Attribute>(target)->value);
+                break;
+            case BST_TYPE::Name: {
+                auto name = bst_cast<BST_Name>(target);
+                assert(name->lookup_type != ScopeInfo::VarScopeType::UNKNOWN);
+                if (name->lookup_type == ScopeInfo::VarScopeType::FAST
+                    || name->lookup_type == ScopeInfo::VarScopeType::CLOSURE) {
+                    sym_table[name->vreg] = NULL;
+                } else
+                    assert(name->vreg == -1);
+                break;
             }
+            default:
+                RELEASE_ASSERT(0, "%d", target->type);
         }
     }
 
@@ -617,12 +594,6 @@ private:
         return t;
     }
 
-    void visit_global(BST_Global* node) override {}
-
-    void visit_import(BST_Import* node) override { assert(0 && "this should get removed by cfg"); }
-
-    void visit_importfrom(BST_ImportFrom* node) override { assert(0 && "this should get removed by cfg"); }
-
     void visit_exec(BST_Exec* node) override {
         getType(node->body);
         if (node->globals)
@@ -634,17 +605,13 @@ private:
     void visit_invoke(BST_Invoke* node) override { node->stmt->accept_stmt(this); }
 
     void visit_jump(BST_Jump* node) override {}
-    void visit_pass(BST_Pass* node) override {}
 
     void visit_print(BST_Print* node) override {
         if (node->dest)
             getType(node->dest);
 
-        if (EXPAND_UNNEEDED) {
-            for (int i = 0; i < node->values.size(); i++) {
-                getType(node->values[i]);
-            }
-        }
+        if (EXPAND_UNNEEDED && node->value)
+            getType(node->value);
     }
 
     void visit_raise(BST_Raise* node) override {
diff --git a/src/codegen/ast_interpreter.cpp b/src/codegen/ast_interpreter.cpp
index bd14cbfa3f2126c7554e83eb7833cacd4dab51c0..30f6e452a5ada10c154a62c64d7c4e8359c96e21 100644
--- a/src/codegen/ast_interpreter.cpp
+++ b/src/codegen/ast_interpreter.cpp
@@ -88,8 +88,6 @@ private:
     Value visit_compare(BST_Compare* node);
     Value visit_delete(BST_Delete* node);
     Value visit_exec(BST_Exec* node);
-    Value visit_global(BST_Global* node);
-    Value visit_module(BST_Module* node);
     Value visit_print(BST_Print* node);
     Value visit_raise(BST_Raise* node);
     Value visit_return(BST_Return* node);
@@ -1055,10 +1053,6 @@ Value ASTInterpreter::visit_stmt(BST_stmt* node) {
                 throw e;
             }
             return rtn;
-        case BST_TYPE::Global:
-            rtn = visit_global((BST_Global*)node);
-            ASTInterpreterJitInterface::pendingCallsCheckHelper();
-            break;
 
         // pseudo
         case BST_TYPE::Branch:
@@ -1308,111 +1302,98 @@ Value ASTInterpreter::visit_assert(BST_Assert* node) {
     return Value();
 }
 
-Value ASTInterpreter::visit_global(BST_Global* node) {
-#ifndef NDEBUG
-    for (auto name : node->names) {
-        assert(!getSymVRegMap().count(name));
-    }
-#endif
-    return Value();
-}
-
 Value ASTInterpreter::visit_delete(BST_Delete* node) {
-    for (BST_expr* target_ : node->targets) {
-        switch (target_->type) {
-            case BST_TYPE::Subscript: {
-                BST_Subscript* sub = (BST_Subscript*)target_;
-                Value value = visit_expr(sub->value);
-                AUTO_DECREF(value.o);
-
-                bool is_slice = (sub->slice->type == BST_TYPE::Slice) && (((BST_Slice*)sub->slice)->step == NULL);
-                if (is_slice) {
-                    BST_Slice* slice = (BST_Slice*)sub->slice;
-                    Value lower = slice->lower ? visit_expr(slice->lower) : Value();
-                    AUTO_XDECREF(lower.o);
-                    Value upper = slice->upper ? visit_expr(slice->upper) : Value();
-                    AUTO_XDECREF(upper.o);
-                    assert(slice->step == NULL);
+    BST_expr* target_ = node->target;
+    switch (target_->type) {
+        case BST_TYPE::Subscript: {
+            BST_Subscript* sub = (BST_Subscript*)target_;
+            Value value = visit_expr(sub->value);
+            AUTO_DECREF(value.o);
+
+            bool is_slice = (sub->slice->type == BST_TYPE::Slice) && (((BST_Slice*)sub->slice)->step == NULL);
+            if (is_slice) {
+                BST_Slice* slice = (BST_Slice*)sub->slice;
+                Value lower = slice->lower ? visit_expr(slice->lower) : Value();
+                AUTO_XDECREF(lower.o);
+                Value upper = slice->upper ? visit_expr(slice->upper) : Value();
+                AUTO_XDECREF(upper.o);
+                assert(slice->step == NULL);
 
-                    if (jit)
-                        jit->emitAssignSlice(value, lower, upper, jit->imm(0ul));
-                    assignSlice(value.o, lower.o, upper.o, NULL);
-                } else {
-                    Value slice = visit_slice(sub->slice);
-                    AUTO_DECREF(slice.o);
-                    if (jit)
-                        jit->emitDelItem(value, slice);
-                    delitem(value.o, slice.o);
-                }
-                break;
+                if (jit)
+                    jit->emitAssignSlice(value, lower, upper, jit->imm(0ul));
+                assignSlice(value.o, lower.o, upper.o, NULL);
+            } else {
+                Value slice = visit_slice(sub->slice);
+                AUTO_DECREF(slice.o);
+                if (jit)
+                    jit->emitDelItem(value, slice);
+                delitem(value.o, slice.o);
             }
-            case BST_TYPE::Attribute: {
-                BST_Attribute* attr = (BST_Attribute*)target_;
-                Value target = visit_expr(attr->value);
-                AUTO_DECREF(target.o);
-                BoxedString* str = attr->attr.getBox();
+            break;
+        }
+        case BST_TYPE::Attribute: {
+            BST_Attribute* attr = (BST_Attribute*)target_;
+            Value target = visit_expr(attr->value);
+            AUTO_DECREF(target.o);
+            BoxedString* str = attr->attr.getBox();
+            if (jit)
+                jit->emitDelAttr(target, str);
+            delattr(target.o, str);
+            break;
+        }
+        case BST_TYPE::Name: {
+            BST_Name* target = (BST_Name*)target_;
+            assert(target->lookup_type != ScopeInfo::VarScopeType::UNKNOWN);
+
+            ScopeInfo::VarScopeType vst = target->lookup_type;
+            if (vst == ScopeInfo::VarScopeType::GLOBAL) {
                 if (jit)
-                    jit->emitDelAttr(target, str);
-                delattr(target.o, str);
+                    jit->emitDelGlobal(target->id.getBox());
+                delGlobal(frame_info.globals, target->id.getBox());
                 break;
-            }
-            case BST_TYPE::Name: {
-                BST_Name* target = (BST_Name*)target_;
-                assert(target->lookup_type != ScopeInfo::VarScopeType::UNKNOWN);
+            } else if (vst == ScopeInfo::VarScopeType::NAME) {
+                if (jit)
+                    jit->emitDelName(target->id);
+                ASTInterpreterJitInterface::delNameHelper(this, target->id);
+            } else {
+                assert(vst == ScopeInfo::VarScopeType::FAST);
 
-                ScopeInfo::VarScopeType vst = target->lookup_type;
-                if (vst == ScopeInfo::VarScopeType::GLOBAL) {
-                    if (jit)
-                        jit->emitDelGlobal(target->id.getBox());
-                    delGlobal(frame_info.globals, target->id.getBox());
-                    continue;
-                } else if (vst == ScopeInfo::VarScopeType::NAME) {
+                assert(getVRegInfo().getVReg(target->id) == target->vreg);
+
+                if (target->id.s()[0] == '#') {
+                    assert(vregs[target->vreg] != NULL);
                     if (jit)
-                        jit->emitDelName(target->id);
-                    ASTInterpreterJitInterface::delNameHelper(this, target->id);
+                        jit->emitKillTemporary(target);
                 } else {
-                    assert(vst == ScopeInfo::VarScopeType::FAST);
-
-                    assert(getVRegInfo().getVReg(target->id) == target->vreg);
-
-                    if (target->id.s()[0] == '#') {
-                        assert(vregs[target->vreg] != NULL);
-                        if (jit)
-                            jit->emitKillTemporary(target);
-                    } else {
-                        abortJITing();
-                        if (vregs[target->vreg] == 0) {
-                            assertNameDefined(0, target->id.c_str(), NameError, true /* local_var_msg */);
-                            return Value();
-                        }
+                    abortJITing();
+                    if (vregs[target->vreg] == 0) {
+                        assertNameDefined(0, target->id.c_str(), NameError, true /* local_var_msg */);
+                        return Value();
                     }
-
-                    frame_info.num_vregs = std::max(frame_info.num_vregs, target->vreg + 1);
-                    Py_DECREF(vregs[target->vreg]);
-                    vregs[target->vreg] = NULL;
                 }
-                break;
+
+                frame_info.num_vregs = std::max(frame_info.num_vregs, target->vreg + 1);
+                Py_DECREF(vregs[target->vreg]);
+                vregs[target->vreg] = NULL;
             }
-            default:
-                ASSERT(0, "Unsupported del target: %d", target_->type);
-                abort();
+            break;
         }
+        default:
+            ASSERT(0, "Unsupported del target: %d", target_->type);
+            abort();
     }
     return Value();
 }
 
 Value ASTInterpreter::visit_assign(BST_Assign* node) {
-    assert(node->targets.size() == 1 && "cfg should have lowered it to a single target");
-
     Value v = visit_expr(node->value);
-    doStore(node->targets[0], v);
+    doStore(node->target, v);
     return Value();
 }
 
 Value ASTInterpreter::visit_print(BST_Print* node) {
-    assert(node->values.size() <= 1 && "cfg should have lowered it to 0 or 1 values");
     Value dest = node->dest ? visit_expr(node->dest) : Value();
-    Value var = node->values.size() ? visit_expr(node->values[0]) : Value();
+    Value var = node->value ? visit_expr(node->value) : Value();
 
     if (jit)
         jit->emitPrint(dest, var, node->nl);
@@ -1442,12 +1423,11 @@ Value ASTInterpreter::visit_exec(BST_Exec* node) {
 }
 
 Value ASTInterpreter::visit_compare(BST_Compare* node) {
-    RELEASE_ASSERT(node->comparators.size() == 1, "not implemented");
     Value left = visit_expr(node->left);
     AUTO_DECREF(left.o);
-    Value right = visit_expr(node->comparators[0]);
+    Value right = visit_expr(node->comparator);
     AUTO_DECREF(right.o);
-    return doBinOp(node, left, right, node->ops[0], BinExpType::Compare);
+    return doBinOp(node, left, right, node->op, BinExpType::Compare);
 }
 
 Value ASTInterpreter::visit_expr(BST_expr* node) {
@@ -2127,9 +2107,8 @@ extern "C" Box* astInterpretDeoptFromASM(BoxedCode* code, BST_expr* after_expr,
         if (enclosing_stmt->type == BST_TYPE::Assign) {
             auto asgn = bst_cast<BST_Assign>(enclosing_stmt);
             RELEASE_ASSERT(asgn->value == after_expr, "%p %p", asgn->value, after_expr);
-            assert(asgn->targets.size() == 1);
-            assert(asgn->targets[0]->type == BST_TYPE::Name);
-            auto name = bst_cast<BST_Name>(asgn->targets[0]);
+            assert(asgn->target->type == BST_TYPE::Name);
+            auto name = bst_cast<BST_Name>(asgn->target);
             assert(name->id.s()[0] == '#');
             interpreter.addSymbol(name->vreg, expr_val, true);
             break;
diff --git a/src/codegen/irgen.cpp b/src/codegen/irgen.cpp
index a815256bc841349ddc33b5a0765b36bc4f104051..4b027869595f8dbd61f5321d1d68a756c53b91b0 100644
--- a/src/codegen/irgen.cpp
+++ b/src/codegen/irgen.cpp
@@ -727,13 +727,12 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
 
                     if (stmt->type == BST_TYPE::Assign) {
                         auto asgn = bst_cast<BST_Assign>(stmt);
-                        assert(asgn->targets.size() == 1);
-                        if (asgn->targets[0]->type == BST_TYPE::Name) {
-                            auto asname = bst_cast<BST_Name>(asgn->targets[0]);
+                        if (asgn->target->type == BST_TYPE::Name) {
+                            auto asname = bst_cast<BST_Name>(asgn->target);
                             assert(asname->lookup_type != ScopeInfo::VarScopeType::UNKNOWN);
 
                             InternedString name = asname->id;
-                            int vreg = bst_cast<BST_Name>(asgn->targets[0])->vreg;
+                            int vreg = bst_cast<BST_Name>(asgn->target)->vreg;
                             assert(name.c_str()[0] == '#'); // it must be a temporary
                             // You might think I need to check whether `name' is being assigned globally or locally,
                             // since a global assign doesn't affect the symbol table. However, the CFG pass only
diff --git a/src/codegen/irgen/irgenerator.cpp b/src/codegen/irgen/irgenerator.cpp
index 9679cfbcef044ade2516ca43e8a4183030a486c7..c36e6dfc80da429531705c62e5bdf10a4dc21349 100644
--- a/src/codegen/irgen/irgenerator.cpp
+++ b/src/codegen/irgen/irgenerator.cpp
@@ -1137,19 +1137,16 @@ private:
     }
 
     CompilerVariable* evalCompare(BST_Compare* node, const UnwindInfo& unw_info) {
-        RELEASE_ASSERT(node->ops.size() == 1, "");
-
         CompilerVariable* left = evalExpr(node->left, unw_info);
-        CompilerVariable* right = evalExpr(node->comparators[0], unw_info);
+        CompilerVariable* right = evalExpr(node->comparator, unw_info);
 
         assert(left);
         assert(right);
 
-        if (node->ops[0] == AST_TYPE::Is || node->ops[0] == AST_TYPE::IsNot) {
-            return doIs(emitter, left, right, node->ops[0] == AST_TYPE::IsNot);
-        }
+        if (node->op == AST_TYPE::Is || node->op == AST_TYPE::IsNot)
+            return doIs(emitter, left, right, node->op == AST_TYPE::IsNot);
 
-        CompilerVariable* rtn = _evalBinExp(node, left, right, node->ops[0], Compare, unw_info);
+        CompilerVariable* rtn = _evalBinExp(node, left, right, node->op, Compare, unw_info);
         return rtn;
     }
 
@@ -2084,27 +2081,24 @@ private:
     void doAssign(BST_Assign* node, const UnwindInfo& unw_info) {
         CompilerVariable* val = evalExpr(node->value, unw_info);
 
-        for (int i = 0; i < node->targets.size(); i++) {
-            _doSet(node->targets[i], val, unw_info);
-        }
+        _doSet(node->target, val, unw_info);
     }
 
     void doDelete(BST_Delete* node, const UnwindInfo& unw_info) {
-        for (BST_expr* target : node->targets) {
-            switch (target->type) {
-                case BST_TYPE::Subscript:
-                    _doDelitem(static_cast<BST_Subscript*>(target), unw_info);
-                    break;
-                case BST_TYPE::Attribute:
-                    _doDelAttr(static_cast<BST_Attribute*>(target), unw_info);
-                    break;
-                case BST_TYPE::Name:
-                    _doDelName(static_cast<BST_Name*>(target), unw_info);
-                    break;
-                default:
-                    ASSERT(0, "Unsupported del target: %d", target->type);
-                    abort();
-            }
+        BST_expr* target = node->target;
+        switch (target->type) {
+            case BST_TYPE::Subscript:
+                _doDelitem(static_cast<BST_Subscript*>(target), unw_info);
+                break;
+            case BST_TYPE::Attribute:
+                _doDelAttr(static_cast<BST_Attribute*>(target), unw_info);
+                break;
+            case BST_TYPE::Name:
+                _doDelName(static_cast<BST_Name*>(target), unw_info);
+                break;
+            default:
+                ASSERT(0, "Unsupported del target: %d", target->type);
+                abort();
         }
     }
 
@@ -2237,11 +2231,10 @@ private:
         }
         assert(dest);
 
-        assert(node->values.size() <= 1);
         ConcreteCompilerVariable* converted;
 
-        if (node->values.size() == 1) {
-            CompilerVariable* var = evalExpr(node->values[0], unw_info);
+        if (node->value) {
+            CompilerVariable* var = evalExpr(node->value, unw_info);
             converted = var->makeConverted(emitter, var->getBoxType());
         } else {
             converted = new ConcreteCompilerVariable(UNKNOWN, getNullPtr(g.llvm_value_type_ptr));
@@ -2561,15 +2554,6 @@ private:
                 if ((((BST_Expr*)node)->value)->type != BST_TYPE::Str)
                     doExpr(bst_cast<BST_Expr>(node), unw_info);
                 break;
-            // case BST_TYPE::If:
-            // doIf(bst_cast<BST_If>(node));
-            // break;
-            // case BST_TYPE::Import:
-            //     doImport(bst_cast<BST_Import>(node), unw_info);
-            //     break;
-            // case BST_TYPE::ImportFrom:
-            //     doImportFrom(bst_cast<BST_ImportFrom>(node), unw_info);
-            //     break;
             case BST_TYPE::Global:
                 // Should have been handled already
                 break;
diff --git a/src/core/ast.cpp b/src/core/ast.cpp
index c5efa579e731cd4156af1d82bd5850b323af8252..b34012b2e2ea91e548a997a83513a41daba02e4b 100644
--- a/src/core/ast.cpp
+++ b/src/core/ast.cpp
@@ -887,28 +887,6 @@ void AST_Yield::accept(ASTVisitor* v) {
         value->accept(v);
 }
 
-void AST_Branch::accept(ASTVisitor* v) {
-    bool skip = v->visit_branch(this);
-    if (skip)
-        return;
-
-    test->accept(v);
-}
-
-void AST_Branch::accept_stmt(ASTStmtVisitor* v) {
-    v->visit_branch(this);
-}
-
-void AST_Jump::accept(ASTVisitor* v) {
-    bool skip = v->visit_jump(this);
-    if (skip)
-        return;
-}
-
-void AST_Jump::accept_stmt(ASTStmtVisitor* v) {
-    v->visit_jump(this);
-}
-
 void AST_ClsAttribute::accept(ASTVisitor* v) {
     bool skip = v->visit_clsattribute(this);
     if (skip)
@@ -917,22 +895,6 @@ void AST_ClsAttribute::accept(ASTVisitor* v) {
     value->accept(v);
 }
 
-void AST_MakeFunction::accept(ASTVisitor* v) {
-    bool skip = v->visit_makefunction(this);
-    if (skip)
-        return;
-
-    function_def->accept(v);
-}
-
-void AST_MakeClass::accept(ASTVisitor* v) {
-    bool skip = v->visit_makeclass(this);
-    if (skip)
-        return;
-
-    class_def->accept(v);
-}
-
 void print_ast(AST* ast) {
     ASTPrintVisitor v;
     ast->accept(&v);
@@ -1827,18 +1789,6 @@ bool ASTPrintVisitor::visit_yield(AST_Yield* node) {
     return true;
 }
 
-bool ASTPrintVisitor::visit_branch(AST_Branch* node) {
-    stream << "if ";
-    node->test->accept(this);
-    stream << " goto " << node->iftrue->idx << " else goto " << node->iffalse->idx;
-    return true;
-}
-
-bool ASTPrintVisitor::visit_jump(AST_Jump* node) {
-    stream << "goto " << node->target->idx;
-    return true;
-}
-
 bool ASTPrintVisitor::visit_clsattribute(AST_ClsAttribute* node) {
     // printf("getclsattr(");
     // node->value->accept(this);
@@ -1848,16 +1798,7 @@ bool ASTPrintVisitor::visit_clsattribute(AST_ClsAttribute* node) {
     return true;
 }
 
-bool ASTPrintVisitor::visit_makefunction(AST_MakeFunction* node) {
-    stream << "make_";
-    return false;
-}
-
-bool ASTPrintVisitor::visit_makeclass(AST_MakeClass* node) {
-    stream << "make_";
-    return false;
-}
-
+namespace {
 class FlattenVisitor : public ASTVisitor {
 private:
     std::vector<AST*>* output;
@@ -2101,30 +2042,14 @@ public:
         return false;
     }
 
-    virtual bool visit_branch(AST_Branch* node) {
-        output->push_back(node);
-        return false;
-    }
-    virtual bool visit_jump(AST_Jump* node) {
-        output->push_back(node);
-        return false;
-    }
     virtual bool visit_clsattribute(AST_ClsAttribute* node) {
         output->push_back(node);
         return false;
     }
-
-    virtual bool visit_makeclass(AST_MakeClass* node) {
-        output->push_back(node);
-        return false;
-    }
-    virtual bool visit_makefunction(AST_MakeFunction* node) {
-        output->push_back(node);
-        return false;
-    }
 };
+}
 
-void flatten(const llvm::SmallVector<AST_stmt*, 4>& roots, std::vector<AST*>& output, bool expand_scopes) {
+void flatten(llvm::ArrayRef<AST_stmt*> roots, std::vector<AST*>& output, bool expand_scopes) {
     FlattenVisitor visitor(&output, expand_scopes);
 
     for (int i = 0; i < roots.size(); i++) {
diff --git a/src/core/ast.h b/src/core/ast.h
index 67c4843c668c4b5f10fc22918aecf7e0f8d919bd..56e34cbb1884a551fadc03734d3cd4b83e9325d5 100644
--- a/src/core/ast.h
+++ b/src/core/ast.h
@@ -206,8 +206,6 @@ class AST_stmt : public AST {
 public:
     virtual void accept_stmt(ASTStmtVisitor* v) = 0;
 
-    int cxx_exception_count = 0;
-
     AST_stmt(AST_TYPE::AST_TYPE type) : AST(type) {}
 };
 
@@ -220,7 +218,6 @@ public:
 class AST_alias : public AST {
 public:
     InternedString name, asname;
-    int name_vreg = -1, asname_vreg = -1;
 
     virtual void accept(ASTVisitor* v);
 
@@ -352,9 +349,6 @@ public:
     std::vector<AST_expr*> args;
     std::vector<AST_keyword*> keywords;
 
-    // used during execution stores all keyword names
-    std::unique_ptr<std::vector<BoxedString*>> keywords_names;
-
     virtual void accept(ASTVisitor* v);
 
     AST_Call() : AST_expr(AST_TYPE::Call) {}
@@ -723,25 +717,13 @@ public:
     // different bytecodes.
     ScopeInfo::VarScopeType lookup_type;
 
-    // These are only valid for lookup_type == FAST or CLOSURE
-    // The interpreter and baseline JIT store variables with FAST 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(ASTVisitor* v);
 
     AST_Name(InternedString id, AST_TYPE::AST_TYPE ctx_type, int lineno, int col_offset = 0)
         : AST_expr(AST_TYPE::Name, lineno, col_offset),
           ctx_type(ctx_type),
           id(id),
-          lookup_type(ScopeInfo::VarScopeType::UNKNOWN),
-          vreg(-1) {}
+          lookup_type(ScopeInfo::VarScopeType::UNKNOWN) {}
 
     static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Name;
 };
@@ -987,60 +969,12 @@ public:
     static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Yield;
 };
 
-class AST_MakeFunction : public AST_expr {
-public:
-    AST_FunctionDef* function_def;
-
-    virtual void accept(ASTVisitor* v);
-
-    AST_MakeFunction(AST_FunctionDef* fd)
-        : AST_expr(AST_TYPE::MakeFunction, fd->lineno, fd->col_offset), function_def(fd) {}
-
-    static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::MakeFunction;
-};
-
-class AST_MakeClass : public AST_expr {
-public:
-    AST_ClassDef* class_def;
-
-    virtual void accept(ASTVisitor* v);
-
-    AST_MakeClass(AST_ClassDef* cd) : AST_expr(AST_TYPE::MakeClass, cd->lineno, cd->col_offset), class_def(cd) {}
-
-    static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::MakeClass;
-};
-
 
 // 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(ASTStmtVisitor* v);
-
-    AST_Branch() : AST_stmt(AST_TYPE::Branch) {}
-
-    static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Branch;
-};
-
-class AST_Jump : public AST_stmt {
-public:
-    CFGBlock* target;
-
-    virtual void accept(ASTVisitor* v);
-    virtual void accept_stmt(ASTStmtVisitor* v);
-
-    AST_Jump() : AST_stmt(AST_TYPE::Jump) {}
-
-    static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Jump;
-};
-
 class AST_ClsAttribute : public AST_expr {
 public:
     AST_expr* value;
@@ -1102,8 +1036,6 @@ template <typename T> T* ast_cast(AST* node) {
     return static_cast<T*>(node);
 }
 
-
-
 class ASTVisitor {
 protected:
 public:
@@ -1170,11 +1102,6 @@ public:
     virtual bool visit_while(AST_While* node) { RELEASE_ASSERT(0, ""); }
     virtual bool visit_with(AST_With* node) { RELEASE_ASSERT(0, ""); }
     virtual bool visit_yield(AST_Yield* node) { RELEASE_ASSERT(0, ""); }
-
-    virtual bool visit_makeclass(AST_MakeClass* node) { RELEASE_ASSERT(0, ""); }
-    virtual bool visit_makefunction(AST_MakeFunction* node) { RELEASE_ASSERT(0, ""); }
-    virtual bool visit_branch(AST_Branch* node) { RELEASE_ASSERT(0, ""); }
-    virtual bool visit_jump(AST_Jump* node) { RELEASE_ASSERT(0, ""); }
 };
 
 class NoopASTVisitor : public ASTVisitor {
@@ -1243,11 +1170,6 @@ public:
     virtual bool visit_while(AST_While* node) { return false; }
     virtual bool visit_with(AST_With* node) { return false; }
     virtual bool visit_yield(AST_Yield* node) { return false; }
-
-    virtual bool visit_branch(AST_Branch* node) { return false; }
-    virtual bool visit_jump(AST_Jump* node) { return false; }
-    virtual bool visit_makeclass(AST_MakeClass* node) { return false; }
-    virtual bool visit_makefunction(AST_MakeFunction* node) { return false; }
 };
 
 class ASTStmtVisitor {
@@ -1279,9 +1201,6 @@ public:
     virtual void visit_tryfinally(AST_TryFinally* node) { RELEASE_ASSERT(0, ""); }
     virtual void visit_while(AST_While* node) { RELEASE_ASSERT(0, ""); }
     virtual void visit_with(AST_With* node) { RELEASE_ASSERT(0, ""); }
-
-    virtual void visit_branch(AST_Branch* node) { RELEASE_ASSERT(0, ""); }
-    virtual void visit_jump(AST_Jump* node) { RELEASE_ASSERT(0, ""); }
 };
 
 void print_ast(AST* ast);
@@ -1358,17 +1277,12 @@ public:
     virtual bool visit_while(AST_While* node);
     virtual bool visit_with(AST_With* node);
     virtual bool visit_yield(AST_Yield* node);
-
-    virtual bool visit_branch(AST_Branch* node);
-    virtual bool visit_jump(AST_Jump* node);
-    virtual bool visit_makefunction(AST_MakeFunction* node);
-    virtual bool visit_makeclass(AST_MakeClass* 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.
-void flatten(const llvm::SmallVector<AST_stmt*, 4>& roots, std::vector<AST*>& output, bool expand_scopes);
+void flatten(llvm::ArrayRef<AST_stmt*> roots, std::vector<AST*>& output, bool expand_scopes);
 void flatten(AST_expr* root, std::vector<AST*>& output, bool expand_scopes);
 // Similar to the flatten() function, but filters for a specific type of ast nodes:
 template <class T, class R> void findNodes(const R& roots, std::vector<T*>& output, bool expand_scopes) {
diff --git a/src/core/bst.cpp b/src/core/bst.cpp
index d4ae6f14a62691265c4ddad231570f117c8037da..7d67a09818256b937118b036d1be25d8ae127686 100644
--- a/src/core/bst.cpp
+++ b/src/core/bst.cpp
@@ -49,12 +49,6 @@ static void visitCFG(CFG* cfg, BSTVisitor* v) {
             e->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)
@@ -83,32 +77,13 @@ void BST_Assign::accept(BSTVisitor* v) {
         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);
-    }
+    target->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)
@@ -147,28 +122,6 @@ 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)
@@ -193,25 +146,13 @@ void BST_Compare::accept(BSTVisitor* v) {
         return;
 
     left->accept(v);
-    visitVector(comparators, v);
+    comparator->accept(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)
@@ -226,22 +167,12 @@ 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);
+    target->accept(v);
 }
 
 void BST_Delete::accept_stmt(StmtVisitor* v) {
@@ -263,23 +194,6 @@ 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)
@@ -290,18 +204,6 @@ 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)
@@ -343,21 +245,6 @@ 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)
@@ -372,84 +259,6 @@ 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)
@@ -482,19 +291,6 @@ void BST_keyword::accept(BSTVisitor* v) {
     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)
@@ -519,46 +315,6 @@ 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);
 }
@@ -575,14 +331,6 @@ 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)
@@ -590,7 +338,9 @@ void BST_Print::accept(BSTVisitor* v) {
 
     if (dest)
         dest->accept(v);
-    visitVector(values, v);
+
+    if (value)
+        value->accept(v);
 }
 
 void BST_Print::accept_stmt(StmtVisitor* v) {
@@ -651,22 +401,6 @@ 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)
@@ -707,33 +441,6 @@ 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)
@@ -758,35 +465,6 @@ 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)
@@ -870,13 +548,6 @@ void PrintVisitor::printIndent() {
     }
 }
 
-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 ndefault = node->defaults.size();
     for (int i = 0; i < ndefault; i++) {
@@ -900,10 +571,8 @@ bool PrintVisitor::visit_assert(BST_Assert* node) {
 }
 
 bool PrintVisitor::visit_assign(BST_Assign* node) {
-    for (int i = 0; i < node->targets.size(); i++) {
-        node->targets[i]->accept(this);
-        stream << " = ";
-    }
+    node->target->accept(this);
+    stream << " = ";
     node->value->accept(this);
     return true;
 }
@@ -949,14 +618,6 @@ void PrintVisitor::printOp(AST_TYPE::AST_TYPE op_type) {
     }
 }
 
-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 << '=';
@@ -979,32 +640,6 @@ bool PrintVisitor::visit_binop(BST_BinOp* node) {
     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 << "(";
@@ -1040,27 +675,8 @@ bool PrintVisitor::visit_call(BST_Call* node) {
 
 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);
-    }
+    stream << " " << getOpSymbol(node->op) << " ";
+    node->comparator->accept(this);
 
     return true;
 }
@@ -1096,18 +712,9 @@ bool PrintVisitor::visit_classdef(BST_ClassDef* node) {
     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);
-    }
+    node->target->accept(this);
     return true;
 }
 
@@ -1124,46 +731,11 @@ bool PrintVisitor::visit_dict(BST_Dict* node) {
     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 ";
 
@@ -1194,11 +766,6 @@ bool PrintVisitor::visit_extslice(BST_ExtSlice* node) {
     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 << "@";
@@ -1231,94 +798,6 @@ bool PrintVisitor::visit_functiondef(BST_FunctionDef* node) {
     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;
 }
@@ -1329,14 +808,6 @@ bool PrintVisitor::visit_invoke(BST_Invoke* node) {
     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) {
@@ -1403,47 +874,12 @@ bool PrintVisitor::visit_list(BST_List* node) {
     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
@@ -1482,11 +918,6 @@ bool PrintVisitor::visit_num(BST_Num* node) {
     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) {
@@ -1494,11 +925,8 @@ bool PrintVisitor::visit_print(BST_Print* node) {
         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->value)
+        node->value->accept(this);
     if (!node->nl)
         stream << ",";
     return true;
@@ -1555,17 +983,6 @@ bool PrintVisitor::visit_set(BST_Set* node) {
     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)
@@ -1601,70 +1018,6 @@ bool PrintVisitor::visit_subscript(BST_Subscript* node) {
     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();
@@ -1703,54 +1056,6 @@ bool PrintVisitor::visit_unaryop(BST_UnaryOp* node) {
     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)
@@ -1789,6 +1094,7 @@ bool PrintVisitor::visit_makeclass(BST_MakeClass* node) {
     return false;
 }
 
+namespace {
 class FlattenVisitor : public BSTVisitor {
 private:
     std::vector<BST*>* output;
@@ -1799,10 +1105,6 @@ public:
         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;
@@ -1815,10 +1117,6 @@ public:
         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;
@@ -1831,14 +1129,6 @@ public:
         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;
@@ -1851,14 +1141,6 @@ public:
         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;
@@ -1867,18 +1149,10 @@ public:
         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;
@@ -1891,38 +1165,10 @@ public:
         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;
@@ -1935,10 +1181,6 @@ public:
         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;
@@ -1947,14 +1189,6 @@ public:
         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;
@@ -1963,10 +1197,6 @@ public:
         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;
@@ -1987,10 +1217,6 @@ public:
         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;
@@ -2003,14 +1229,6 @@ public:
         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;
@@ -2019,14 +1237,6 @@ public:
         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;
@@ -2054,8 +1264,9 @@ public:
         return false;
     }
 };
+}
 
-void flatten(const llvm::SmallVector<BST_stmt*, 4>& roots, std::vector<BST*>& output, bool expand_scopes) {
+void flatten(llvm::ArrayRef<BST_stmt*> roots, std::vector<BST*>& output, bool expand_scopes) {
     FlattenVisitor visitor(&output, expand_scopes);
 
     for (int i = 0; i < roots.size(); i++) {
diff --git a/src/core/bst.h b/src/core/bst.h
index 6b0cd8ea9945b8685d170e746a2e76724cf2ed81..b8d5873f0959a9da4cbb2abdb73d7f1c00a98224 100644
--- a/src/core/bst.h
+++ b/src/core/bst.h
@@ -215,18 +215,6 @@ public:
     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 {
@@ -255,7 +243,7 @@ public:
 
 class BST_Assign : public BST_stmt {
 public:
-    std::vector<BST_expr*> targets;
+    BST_expr* target;
     BST_expr* value;
 
     virtual void accept(BSTVisitor* v);
@@ -266,20 +254,6 @@ public:
     static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Assign;
 };
 
-class BST_AugAssign : public BST_stmt {
-public:
-    BST_expr* value;
-    BST_expr* target;
-    AST_TYPE::AST_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:
     AST_TYPE::AST_TYPE op_type;
@@ -323,29 +297,6 @@ public:
     static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::BinOp;
 };
 
-class BST_BoolOp : public BST_expr {
-public:
-    AST_TYPE::AST_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;
@@ -365,8 +316,8 @@ public:
 
 class BST_Compare : public BST_expr {
 public:
-    std::vector<AST_TYPE::AST_TYPE> ops;
-    std::vector<BST_expr*> comparators;
+    AST_TYPE::AST_TYPE op;
+    BST_expr* comparator;
     BST_expr* left;
 
     virtual void accept(BSTVisitor* v);
@@ -377,19 +328,6 @@ public:
     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);
@@ -405,16 +343,6 @@ public:
     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;
@@ -427,22 +355,9 @@ public:
     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;
+    BST_expr* target;
     virtual void accept(BSTVisitor* v);
     virtual void accept_stmt(StmtVisitor* v);
 
@@ -474,19 +389,6 @@ public:
     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;
@@ -501,22 +403,6 @@ public:
     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;
-
-    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;
@@ -529,19 +415,6 @@ public:
     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_expr*> decorator_list;
@@ -558,82 +431,6 @@ public:
     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;
@@ -659,19 +456,6 @@ public:
     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;
@@ -685,48 +469,6 @@ public:
     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;
-
-    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:
     AST_TYPE::AST_TYPE ctx_type;
@@ -792,26 +534,16 @@ public:
     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;
+    BST_expr* value;
 
     virtual void accept(BSTVisitor* v);
     virtual void accept_stmt(StmtVisitor* v);
 
-    BST_Print() : BST_stmt(BST_TYPE::Print) {}
+    BST_Print() : BST_stmt(BST_TYPE::Print), value(NULL) {}
 
     static const BST_TYPE::BST_TYPE TYPE = BST_TYPE::Print;
 };
@@ -856,19 +588,6 @@ public:
     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;
@@ -912,31 +631,6 @@ public:
     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;
@@ -963,32 +657,6 @@ public:
     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;
@@ -1127,66 +795,40 @@ 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, ""); }
@@ -1200,66 +842,40 @@ 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; }
@@ -1276,23 +892,16 @@ public:
     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, ""); }
@@ -1309,28 +918,15 @@ public:
 
     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, ""); }
@@ -1358,66 +954,40 @@ public:
     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);
@@ -1429,7 +999,7 @@ public:
 // Given an BST 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.
-void flatten(const llvm::SmallVector<BST_stmt*, 4>& roots, std::vector<BST*>& output, bool expand_scopes);
+void flatten(llvm::ArrayRef<BST_stmt*> roots, std::vector<BST*>& output, bool expand_scopes);
 void flatten(BST_expr* root, std::vector<BST*>& output, bool expand_scopes);
 };
 
diff --git a/src/core/cfg.cpp b/src/core/cfg.cpp
index d645397149cf669101bba4fcd1a7c47f7abef3a6..b71afc85b102508610bae111d3155dd9b699f122 100644
--- a/src/core/cfg.cpp
+++ b/src/core/cfg.cpp
@@ -786,9 +786,9 @@ private:
 
     BST_Compare* makeCompare(AST_TYPE::AST_TYPE oper, BST_expr* left, BST_expr* right) {
         auto compare = new BST_Compare();
-        compare->ops.push_back(oper);
+        compare->op = oper;
         compare->left = left;
-        compare->comparators.push_back(right);
+        compare->comparator = right;
         return compare;
     }
 
@@ -818,7 +818,7 @@ private:
         assign->value = val;
         assign->col_offset = val->col_offset;
         assign->lineno = val->lineno;
-        assign->targets.push_back(target);
+        assign->target = target;
         push_back(assign);
     }
 
@@ -829,7 +829,7 @@ private:
         assign->lineno = val->lineno;
 
         if (target->type == AST_TYPE::Name) {
-            assign->targets.push_back(makeName(ast_cast<AST_Name>(target)->id, AST_TYPE::Store, val->lineno, 0));
+            assign->target = makeName(ast_cast<AST_Name>(target)->id, AST_TYPE::Store, val->lineno, 0);
             push_back(assign);
         } else if (target->type == AST_TYPE::Subscript) {
             AST_Subscript* s = ast_cast<AST_Subscript>(target);
@@ -842,7 +842,7 @@ private:
             s_target->col_offset = s->col_offset;
             s_target->lineno = s->lineno;
 
-            assign->targets.push_back(s_target);
+            assign->target = s_target;
             push_back(assign);
         } else if (target->type == AST_TYPE::Attribute) {
             AST_Attribute* a = ast_cast<AST_Attribute>(target);
@@ -855,7 +855,7 @@ private:
             a_target->col_offset = a->col_offset;
             a_target->lineno = a->lineno;
 
-            assign->targets.push_back(a_target);
+            assign->target = a_target;
             push_back(assign);
         } else if (target->type == AST_TYPE::Tuple || target->type == AST_TYPE::List) {
             std::vector<AST_expr*>* elts;
@@ -876,7 +876,7 @@ private:
 
             // A little hackery: push the assign, even though we're not done constructing it yet,
             // so that we can iteratively push more stuff after it
-            assign->targets.push_back(new_target);
+            assign->target = new_target;
             push_back(assign);
 
             for (int i = 0; i < elts->size(); i++) {
@@ -895,7 +895,7 @@ private:
         assign->value = val;
         assign->col_offset = val->col_offset;
         assign->lineno = val->lineno;
-        assign->targets.push_back(makeName(id, AST_TYPE::Store, val->lineno, 0));
+        assign->target = makeName(id, AST_TYPE::Store, val->lineno, 0);
         push_back(assign);
     }
 
@@ -1122,12 +1122,11 @@ private:
             rtn->lineno = node->lineno;
             rtn->col_offset = node->col_offset;
 
-            rtn->ops = node->ops;
+            rtn->op = node->ops[0];
 
             rtn->left = remapExpr(node->left);
-            for (auto elt : node->comparators) {
-                rtn->comparators.push_back(remapExpr(elt));
-            }
+            assert(node->comparators.size() == 1);
+            rtn->comparator = remapExpr(node->comparators[0]);
             return rtn;
         } else {
             InternedString name = nodeName();
@@ -1146,10 +1145,10 @@ private:
                 val->lineno = node->lineno;
                 val->left = left;
                 if (i < node->ops.size() - 1)
-                    val->comparators.push_back(_dup(right));
+                    val->comparator = _dup(right);
                 else
-                    val->comparators.push_back(right);
-                val->ops.push_back(node->ops[i]);
+                    val->comparator = right;
+                val->op = node->ops[i];
 
                 pushAssign(name, val);
 
@@ -1754,9 +1753,8 @@ public:
 
         if (node->type == BST_TYPE::Assign) {
             BST_Assign* asgn = bst_cast<BST_Assign>(node);
-            assert(asgn->targets.size() == 1);
-            if (asgn->targets[0]->type == BST_TYPE::Name) {
-                BST_Name* target = bst_cast<BST_Name>(asgn->targets[0]);
+            if (asgn->target->type == BST_TYPE::Name) {
+                BST_Name* target = bst_cast<BST_Name>(asgn->target);
                 if (target->id.s()[0] != '#') {
 // assigning to a non-temporary
 #ifndef NDEBUG
@@ -1789,9 +1787,8 @@ public:
         // Deleting temporary names is safe, since we only use it to represent kills.
         if (node->type == BST_TYPE::Delete) {
             BST_Delete* del = bst_cast<BST_Delete>(node);
-            assert(del->targets.size() == 1);
-            if (del->targets[0]->type == BST_TYPE::Name) {
-                BST_Name* target = bst_cast<BST_Name>(del->targets[0]);
+            if (del->target->type == BST_TYPE::Name) {
+                BST_Name* target = bst_cast<BST_Name>(del->target);
                 if (target->id.s()[0] == '#') {
                     curblock->push_back(node);
                     return;
@@ -1836,7 +1833,7 @@ public:
         target->elts.push_back(makeName(exc_info.exc_type_name, AST_TYPE::Store, node->lineno));
         target->elts.push_back(makeName(exc_info.exc_value_name, AST_TYPE::Store, node->lineno));
         target->elts.push_back(makeName(exc_info.exc_traceback_name, AST_TYPE::Store, node->lineno));
-        exc_asgn->targets.push_back(target);
+        exc_asgn->target = target;
 
         exc_asgn->value = new BST_LangPrimitive(BST_LangPrimitive::LANDINGPAD);
         curblock->push_back(exc_asgn);
@@ -1897,10 +1894,8 @@ public:
         return true;
     }
 
-    bool visit_global(AST_Global* node) override {
-        BST_Global* newnode = new BST_Global();
-        newnode->names = std::move(node->names);
-        push_back(newnode);
+    bool visit_global(AST_Global*) override {
+        // nothing todo only the scoping analysis cares about this node
         return true;
     }
 
@@ -2183,9 +2178,6 @@ public:
 
     bool visit_delete(AST_Delete* node) override {
         for (auto t : node->targets) {
-            BST_Delete* astdel = new BST_Delete();
-            astdel->lineno = node->lineno;
-            astdel->col_offset = node->col_offset;
             BST_expr* target = NULL;
             switch (t->type) {
                 case AST_TYPE::Subscript: {
@@ -2235,11 +2227,13 @@ public:
                     RELEASE_ASSERT(0, "Unsupported del target: %d", t->type);
             }
 
-            if (target != NULL)
-                astdel->targets.push_back(target);
-
-            if (astdel->targets.size() > 0)
+            if (target != NULL) {
+                BST_Delete* astdel = new BST_Delete();
+                astdel->lineno = node->lineno;
+                astdel->col_offset = node->col_offset;
+                astdel->target = target;
                 push_back(astdel);
+            }
         }
 
         return true;
@@ -2271,7 +2265,7 @@ public:
                 remapped->nl = node->nl;
             }
 
-            remapped->values.push_back(remapExpr(v));
+            remapped->value = remapExpr(v);
             push_back(remapped);
 
             i++;
@@ -2447,7 +2441,7 @@ public:
     BST_stmt* makeKill(InternedString name) {
         // There might be a better way to represent this, maybe with a dedicated AST_Kill bytecode?
         auto del = new BST_Delete();
-        del->targets.push_back(makeName(name, AST_TYPE::Del, 0, 0, false));
+        del->target = makeName(name, AST_TYPE::Del, 0, 0, false);
         return del;
     }
 
@@ -2934,8 +2928,6 @@ public:
 
     AssignVRegsVisitor() : current_block(0), next_vreg(0) {}
 
-    bool visit_alias(BST_alias* node) override { RELEASE_ASSERT(0, "these should be removed by the cfg"); }
-
     bool visit_arguments(BST_arguments* node) override {
         for (BST_expr* d : node->defaults)
             d->accept(this);
@@ -2957,12 +2949,6 @@ public:
         return true;
     }
 
-    bool visit_lambda(BST_Lambda* node) override {
-        node->args->accept(this);
-        return true;
-    }
-
-
     bool isNameUsedInSingleBlock(InternedString id) {
         assert(step != TrackBlockUsage);
         assert(sym_blocks_map.count(id));
@@ -3087,7 +3073,7 @@ static CFG* computeCFG(llvm::ArrayRef<AST_stmt*> body, AST_TYPE::AST_TYPE ast_ty
         auto module_name_value = new BST_Name(stringpool.get("__name__"), AST_TYPE::Load, lineno);
         fillScopingInfo(module_name_value, scoping);
 
-        module_assign->targets.push_back(module_name_target);
+        module_assign->target = module_name_target;
         module_assign->value = module_name_value;
 
         module_assign->lineno = lineno;
@@ -3100,7 +3086,7 @@ static CFG* computeCFG(llvm::ArrayRef<AST_stmt*> body, AST_TYPE::AST_TYPE ast_ty
                 BST_Assign* doc_assign = new BST_Assign();
                 auto doc_target_name = new BST_Name(stringpool.get("__doc__"), AST_TYPE::Store, lineno);
                 fillScopingInfo(doc_target_name, scoping);
-                doc_assign->targets.push_back(doc_target_name);
+                doc_assign->target = doc_target_name;
                 auto doc_val = new BST_Str();
                 doc_val->str_data = ast_cast<AST_Str>(first_expr->value)->str_data;
                 doc_val->str_type = ast_cast<AST_Str>(first_expr->value)->str_type;