Commit 21b0ec56 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add AST nodes for except handling; just the data structures, no functionality yet

parent 7a44bcaf
......@@ -328,6 +328,18 @@ AST_Dict* read_dict(BufferedReader *reader) {
return rtn;
}
AST_ExceptHandler* read_excepthandler(BufferedReader *reader) {
AST_ExceptHandler *rtn = new AST_ExceptHandler();
readStmtVector(rtn->body, reader);
rtn->col_offset = readColOffset(reader);
rtn->lineno = reader->readULL();
rtn->name = readASTExpr(reader);
rtn->type = readASTExpr(reader);
return rtn;
}
AST_Expr* read_expr(BufferedReader *reader) {
AST_Expr *rtn = new AST_Expr();
......@@ -521,6 +533,19 @@ AST_Print* read_print(BufferedReader *reader) {
return rtn;
}
AST_Raise* read_raise(BufferedReader *reader) {
AST_Raise *rtn = new AST_Raise();
// "arg0" "arg1" "arg2" are called "type", "inst", and "tback" in the python ast,
// so that's the order we have to read them:
rtn->col_offset = readColOffset(reader);
rtn->arg1 /*inst*/ = readASTExpr(reader);
rtn->lineno = reader->readULL();
rtn->arg2 /*tback*/ = readASTExpr(reader);
rtn->arg0 /*type*/ = readASTExpr(reader);
return rtn;
}
AST_Return* read_return(BufferedReader *reader) {
AST_Return *rtn = new AST_Return();
......@@ -564,6 +589,27 @@ AST_Subscript* read_subscript(BufferedReader *reader) {
return rtn;
}
AST_TryExcept* read_tryexcept(BufferedReader *reader) {
AST_TryExcept *rtn = new AST_TryExcept();
readStmtVector(rtn->body, reader);
rtn->col_offset = readColOffset(reader);
readMiscVector(rtn->handlers, reader);
rtn->lineno = reader->readULL();
readStmtVector(rtn->orelse, reader);
return rtn;
}
AST_TryFinally* read_tryfinally(BufferedReader *reader) {
AST_TryFinally *rtn = new AST_TryFinally();
readStmtVector(rtn->body, reader);
rtn->col_offset = readColOffset(reader);
readStmtVector(rtn->finalbody, reader);
rtn->lineno = reader->readULL();
return rtn;
}
AST_Tuple* read_tuple(BufferedReader *reader) {
AST_Tuple *rtn = new AST_Tuple();
......@@ -705,8 +751,14 @@ AST_stmt* readASTStmt(BufferedReader *reader) {
return read_pass(reader);
case AST_TYPE::Print:
return read_print(reader);
case AST_TYPE::Raise:
return read_raise(reader);
case AST_TYPE::Return:
return read_return(reader);
case AST_TYPE::TryExcept:
return read_tryexcept(reader);
case AST_TYPE::TryFinally:
return read_tryfinally(reader);
case AST_TYPE::While:
return read_while(reader);
case AST_TYPE::With:
......@@ -735,6 +787,8 @@ AST* readASTMisc(BufferedReader *reader) {
return read_arguments(reader);
case AST_TYPE::comprehension:
return read_comprehension(reader);
case AST_TYPE::ExceptHandler:
return read_excepthandler(reader);
case AST_TYPE::keyword:
return read_keyword(reader);
case AST_TYPE::Module:
......
......@@ -367,6 +367,15 @@ void* AST_Dict::accept_expr(ExprVisitor *v) {
return v->visit_dict(this);
}
void AST_ExceptHandler::accept(ASTVisitor *v) {
bool skip = v->visit_excepthandler(this);
if (skip) return;
if (type) type->accept(v);
if (name) name->accept(v);
visitVector(body, v);
}
void AST_Expr::accept(ASTVisitor *v) {
bool skip = v->visit_expr(this);
if (skip) return;
......@@ -529,15 +538,6 @@ void* AST_Num::accept_expr(ExprVisitor *v) {
return v->visit_num(this);
}
void AST_Repr::accept(ASTVisitor *v) {
bool skip = v->visit_repr(this);
}
void* AST_Repr::accept_expr(ExprVisitor *v) {
return v->visit_repr(this);
}
void AST_Pass::accept(ASTVisitor *v) {
bool skip = v->visit_pass(this);
}
......@@ -558,6 +558,28 @@ void AST_Print::accept_stmt(StmtVisitor *v) {
v->visit_print(this);
}
void AST_Raise::accept(ASTVisitor *v) {
bool skip = v->visit_raise(this);
if (skip) return;
if (arg0) arg0->accept(v);
if (arg1) arg1->accept(v);
if (arg2) arg2->accept(v);
}
void AST_Raise::accept_stmt(StmtVisitor *v) {
v->visit_raise(this);
}
void AST_Repr::accept(ASTVisitor *v) {
bool skip = v->visit_repr(this);
if (skip) return;
}
void* AST_Repr::accept_expr(ExprVisitor *v) {
return v->visit_repr(this);
}
void AST_Return::accept(ASTVisitor *v) {
bool skip = v->visit_return(this);
if (skip) return;
......@@ -603,6 +625,31 @@ void* AST_Subscript::accept_expr(ExprVisitor *v) {
return v->visit_subscript(this);
}
void AST_TryExcept::accept(ASTVisitor *v) {
bool skip = v->visit_tryexcept(this);
if (skip) return;
visitVector(body, v);
visitVector(orelse, v);
visitVector(handlers, v);
}
void AST_TryExcept::accept_stmt(StmtVisitor *v) {
v->visit_tryexcept(this);
}
void AST_TryFinally::accept(ASTVisitor *v) {
bool skip = v->visit_tryfinally(this);
if (skip) return;
visitVector(body, v);
visitVector(finalbody, v);
}
void AST_TryFinally::accept_stmt(StmtVisitor *v) {
v->visit_tryfinally(this);
}
void AST_Tuple::accept(ASTVisitor *v) {
bool skip = v->visit_tuple(this);
if (skip) return;
......@@ -935,6 +982,28 @@ bool PrintVisitor::visit_dict(AST_Dict *node) {
return true;
}
bool PrintVisitor::visit_excepthandler(AST_ExceptHandler *node) {
printf("except");
if (node->type) {
printf(" ");
node->type->accept(this);
}
if (node->name) {
printf(" as ");
node->name->accept(this);
}
printf(":\n");
indent += 4;
for (AST* subnode : node->body) {
printIndent();
subnode->accept(this);
printf("\n");
}
indent -= 4;
return true;
}
bool PrintVisitor::visit_expr(AST_Expr *node) {
return false;
}
......@@ -1113,6 +1182,23 @@ bool PrintVisitor::visit_print(AST_Print *node) {
return true;
}
bool PrintVisitor::visit_raise(AST_Raise *node) {
printf("raise");
if (node->arg0) {
printf(" ");
node->arg0->accept(this);
}
if (node->arg1) {
printf(", ");
node->arg1->accept(this);
}
if (node->arg2) {
printf(", ");
node->arg2->accept(this);
}
return true;
}
bool PrintVisitor::visit_repr(AST_Repr *node) {
printf("`");
node->value->accept(this);
......@@ -1152,6 +1238,70 @@ bool PrintVisitor::visit_subscript(AST_Subscript *node) {
return true;
}
bool PrintVisitor::visit_tryexcept(AST_TryExcept *node) {
printf("try:\n");
indent += 4;
for (AST* subnode : node->body) {
printIndent();
subnode->accept(this);
printf("\n");
}
indent -= 4;
for (AST_ExceptHandler* handler : node->handlers) {
printIndent();
handler->accept(this);
}
if (node->orelse.size()) {
printIndent();
printf("else:\n");
indent += 4;
for (AST* subnode : node->orelse) {
printIndent();
subnode->accept(this);
printf("\n");
}
indent -= 4;
}
return true;
}
bool PrintVisitor::visit_tryfinally(AST_TryFinally *node) {
if (node->body.size() == 1 && node->body[0]->type == AST_TYPE::TryExcept) {
node->body[0]->accept(this);
printIndent();
printf("finally:\n");
indent += 4;
for (AST* subnode : node->finalbody) {
printIndent();
subnode->accept(this);
printf("\n");
}
indent -= 4;
} else {
printf("try:\n");
indent += 4;
for (AST* subnode : node->body) {
printIndent();
subnode->accept(this);
printf("\n");
}
indent -= 4;
printIndent();
printf("finally:\n");
indent += 4;
for (AST* subnode : node->finalbody) {
printIndent();
subnode->accept(this);
printf("\n");
}
indent -= 4;
}
return true;
}
bool PrintVisitor::visit_tuple(AST_Tuple *node) {
printf("(");
int n = node->elts.size();
......
......@@ -372,6 +372,19 @@ class AST_Expr : public AST_stmt {
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Expr;
};
class AST_ExceptHandler : public AST{
public:
std::vector<AST_stmt*> body;
AST_expr* type; // can be NULL for a bare "except:" clause
AST_expr* name; // can be NULL if the exception doesn't get a name
virtual void accept(ASTVisitor *v);
AST_ExceptHandler() : AST(AST_TYPE::ExceptHandler) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::ExceptHandler;
};
class AST_For : public AST_stmt {
public:
std::vector<AST_stmt*> body, orelse;
......@@ -596,6 +609,22 @@ class AST_Print : public AST_stmt {
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Print;
};
class AST_Raise : public AST_stmt {
public:
// In the python ast module, these are called "type", "inst", and "tback", respectively.
// Renaming to arg{0..2} since I find that confusing, since they are filled in
// sequentially rather than semantically.
// Ie "raise Exception()" will have type==Exception(), inst==None, tback==None
AST_expr *arg0, *arg1, *arg2;
virtual void accept(ASTVisitor *v);
virtual void accept_stmt(StmtVisitor *v);
AST_Raise() : AST_stmt(AST_TYPE::Raise) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Raise;
};
class AST_Return : public AST_stmt {
public:
AST_expr* value;
......@@ -645,6 +674,31 @@ class AST_Subscript : public AST_expr {
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Subscript;
};
class AST_TryExcept : public AST_stmt {
public:
std::vector<AST_stmt*> body, orelse;
std::vector<AST_ExceptHandler*> handlers;
virtual void accept(ASTVisitor *v);
virtual void accept_stmt(StmtVisitor *v);
AST_TryExcept() : AST_stmt(AST_TYPE::TryExcept) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::TryExcept;
};
class AST_TryFinally : public AST_stmt {
public:
std::vector<AST_stmt*> body, finalbody;
virtual void accept(ASTVisitor *v);
virtual void accept_stmt(StmtVisitor *v);
AST_TryFinally() : AST_stmt(AST_TYPE::TryFinally) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::TryFinally;
};
class AST_Tuple : public AST_expr {
public:
std::vector<AST_expr*> elts;
......@@ -771,6 +825,7 @@ class ASTVisitor {
virtual bool visit_classdef(AST_ClassDef *node) { assert(0); abort(); }
virtual bool visit_continue(AST_Continue *node) { assert(0); abort(); }
virtual bool visit_dict(AST_Dict *node) { assert(0); abort(); }
virtual bool visit_excepthandler(AST_ExceptHandler *node) { assert(0); abort(); }
virtual bool visit_expr(AST_Expr *node) { assert(0); abort(); }
virtual bool visit_for(AST_For *node) { assert(0); abort(); }
virtual bool visit_functiondef(AST_FunctionDef *node) { assert(0); abort(); }
......@@ -788,11 +843,14 @@ class ASTVisitor {
virtual bool visit_num(AST_Num *node) { assert(0); abort(); }
virtual bool visit_pass(AST_Pass *node) { assert(0); abort(); }
virtual bool visit_print(AST_Print *node) { assert(0); abort(); }
virtual bool visit_raise(AST_Raise *node) { assert(0); abort(); }
virtual bool visit_repr(AST_Repr *node) { assert(0); abort(); }
virtual bool visit_return(AST_Return *node) { assert(0); abort(); }
virtual bool visit_slice(AST_Slice *node) { assert(0); abort(); }
virtual bool visit_str(AST_Str *node) { assert(0); abort(); }
virtual bool visit_subscript(AST_Subscript *node) { assert(0); abort(); }
virtual bool visit_tryexcept(AST_TryExcept *node) { assert(0); abort(); }
virtual bool visit_tryfinally(AST_TryFinally *node) { assert(0); abort(); }
virtual bool visit_tuple(AST_Tuple *node) { assert(0); abort(); }
virtual bool visit_unaryop(AST_UnaryOp *node) { assert(0); abort(); }
virtual bool visit_while(AST_While *node) { assert(0); abort(); }
......@@ -824,6 +882,7 @@ class NoopASTVisitor : public ASTVisitor {
virtual bool visit_classdef(AST_ClassDef *node) { return false; }
virtual bool visit_continue(AST_Continue *node) { return false; }
virtual bool visit_dict(AST_Dict *node) { return false; }
virtual bool visit_excepthandler(AST_ExceptHandler *node) { return false; }
virtual bool visit_expr(AST_Expr *node) { return false; }
virtual bool visit_for(AST_For *node) { return false; }
virtual bool visit_functiondef(AST_FunctionDef *node) { return false; }
......@@ -841,11 +900,14 @@ class NoopASTVisitor : public ASTVisitor {
virtual bool visit_num(AST_Num *node) { return false; }
virtual bool visit_pass(AST_Pass *node) { return false; }
virtual bool visit_print(AST_Print *node) { return false; }
virtual bool visit_raise(AST_Raise *node) {return false; }
virtual bool visit_repr(AST_Repr *node) { return false; }
virtual bool visit_return(AST_Return *node) { return false; }
virtual bool visit_slice(AST_Slice *node) { return false; }
virtual bool visit_str(AST_Str *node) { return false; }
virtual bool visit_subscript(AST_Subscript *node) { return false; }
virtual bool visit_tryexcept(AST_TryExcept *node) { return false; }
virtual bool visit_tryfinally(AST_TryFinally *node) { return false; }
virtual bool visit_tuple(AST_Tuple *node) { return false; }
virtual bool visit_unaryop(AST_UnaryOp *node) { return false; }
virtual bool visit_while(AST_While *node) { return false; }
......@@ -902,7 +964,10 @@ class StmtVisitor {
virtual void visit_importfrom(AST_ImportFrom *node) { assert(0); abort(); }
virtual void visit_pass(AST_Pass *node) { assert(0); abort(); }
virtual void visit_print(AST_Print *node) { assert(0); abort(); }
virtual void visit_raise(AST_Raise *node) { assert(0); abort(); }
virtual void visit_return(AST_Return *node) { assert(0); abort(); }
virtual void visit_tryexcept(AST_TryExcept *node) { assert(0); abort(); }
virtual void visit_tryfinally(AST_TryFinally *node) { assert(0); abort(); }
virtual void visit_while(AST_While *node) { assert(0); abort(); }
virtual void visit_with(AST_With *node) { assert(0); abort(); }
......@@ -936,6 +1001,7 @@ class PrintVisitor : public ASTVisitor {
virtual bool visit_clsattribute(AST_ClsAttribute *node);
virtual bool visit_continue(AST_Continue *node);
virtual bool visit_dict(AST_Dict *node);
virtual bool visit_excepthandler(AST_ExceptHandler *node);
virtual bool visit_expr(AST_Expr *node);
virtual bool visit_for(AST_For *node);
virtual bool visit_functiondef(AST_FunctionDef *node);
......@@ -953,12 +1019,15 @@ class PrintVisitor : public ASTVisitor {
virtual bool visit_num(AST_Num *node);
virtual bool visit_pass(AST_Pass *node);
virtual bool visit_print(AST_Print *node);
virtual bool visit_raise(AST_Raise *node);
virtual bool visit_repr(AST_Repr *node);
virtual bool visit_return(AST_Return *node);
virtual bool visit_slice(AST_Slice *node);
virtual bool visit_str(AST_Str *node);
virtual bool visit_subscript(AST_Subscript *node);
virtual bool visit_tuple(AST_Tuple *node);
virtual bool visit_tryexcept(AST_TryExcept *node);
virtual bool visit_tryfinally(AST_TryFinally *node);
virtual bool visit_unaryop(AST_UnaryOp *node);
virtual bool visit_while(AST_While *node);
virtual bool visit_with(AST_With *node);
......
def f():
with a as b:
try:
raise 1
except (c, d) as e:
pass
except:
pass
else:
1
finally:
pass
# Note: don't call f
......@@ -39,3 +39,23 @@ def f1():
__builtin__.StopIteration = _StopIteration
f1()
def f2(throw):
print "f2"
try:
try:
print "inner try"
if throw:
raise Exception()
except:
print "inner except"
else:
print "inner else"
raise Exception()
except:
print "outer except"
else:
print "outer else"
f2(True)
f2(False)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment