Work on try/except/finally statements.

The last time I tried this the monkey didn't survive. Let's hope it works better this time.
This commit is contained in:
Darryl Pogue
2011-01-02 05:13:46 -08:00
parent 1c441fa0ee
commit 9924eb9d0d
2 changed files with 43 additions and 12 deletions

View File

@@ -425,22 +425,35 @@ private:
PycRef<ASTNode> m_idx;
};
/*class ASTTryBlock : public ASTBlock {
/* Okay, prepare for a bit of illogic:
* We store a try block.
* We store the except and finally blocks INSIDE that try block.
*
* In implementation it gets a bit weirder, but given the way the opcodes
* work, this is the most straightforward way of doing it.
* Heh, "straightforward"...
*/
class ASTTryBlock : public ASTBlock {
public:
ASTTryBlock(unsigned int start, unsigned int end,
unsigned int except = 0, unsigned int finally = 0)
: ASTBlock(BLK_TRY, start, end), m_except(except),
m_finally(finally) { }
ASTTryBlock(unsigned int end, int finally = 0, int except = 0)
: ASTBlock(BLK_TRY, end), m_finally_pos(finally), m_finally(), m_except_pos(except), m_except() { }
unsigned int except() const { return m_except; }
unsigned int finally() const { return m_finally; }
int finallyStart() const { return m_finally_pos; }
int exceptStart() const { return m_except_pos; }
PycRef<ASTBlock> finally() const { return m_finally; }
const list_t& except() const { return m_except; }
void set_except(unsigned int except) { m_except = except; }
void set_finally(unsigned int finally) { m_finally = finally; }
void setFinallyStart(int finally) { m_finally_pos = finally; }
void setExceptStart(int except) { m_except_pos = except; }
void setFinally(PycRef<ASTBlock> finally) { m_finally = finally; }
void setExcept(const list_t& except) { m_except = except; }
private:
unsigned int m_except;
unsigned int m_finally;
};*/
int m_finally_pos;
PycRef<ASTBlock> m_finally;
int m_except_pos;
list_t m_except;
};
#endif

View File

@@ -251,9 +251,27 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
case Pyc::END_FINALLY:
{
if (curblock->blktype() == ASTBlock::BLK_FINALLY) {
PycRef<ASTBlock> finally = curblock;
blocks.pop();
curblock = blocks.top();
if (curblock->blktype() == ASTBlock::BLK_TRY) {
PycRef<ASTTryBlock> parent = curblock.cast<ASTTryBlock>();
parent->setFinally(finally);
} else {
fprintf(stderr, "Something TERRIBLE happened.\n");
}
blocks.pop();
blocks.top()->append(curblock.cast<ASTNode>());
curblock = blocks.top();
} else if (curblock->blktype() == ASTBlock::BLK_ELSE) {
/* All except statements have an "else" block that
bubbles the exception up... ignore it */
if (curblock->size() == 0) {
blocks.pop();
}
curblock = blocks.top();
}
}