Add raise, break, continue, and a hacky attempt at for loops.

for loops currently generate a core dump.
This commit is contained in:
Darryl Pogue
2011-01-01 02:31:31 -08:00
parent 7e4de4e612
commit f1205548e5
4 changed files with 179 additions and 9 deletions

View File

@@ -165,6 +165,9 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
stack.push(new ASTBinary(left, right, ASTBinary::BIN_XOR));
}
break;
case Pyc::BREAK_LOOP:
stack.push(new ASTKeyword(ASTKeyword::KW_BREAK));
break;
case Pyc::BUILD_CLASS:
{
PycRef<ASTNode> code = stack.top();
@@ -229,6 +232,9 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
stack.push(new ASTCall(func, pparamList, kwparamList));
}
break;
case Pyc::CONTINUE_LOOP_A:
stack.push(new ASTKeyword(ASTKeyword::KW_CONTINUE));
break;
case Pyc::COMPARE_OP_A:
{
PycRef<ASTNode> right = stack.top();
@@ -251,6 +257,27 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
}
}
break;
case Pyc::FOR_LOOP_A:
{
PycRef<ASTNode> curidx = stack.top(); // Current index
stack.pop();
PycRef<ASTNode> iter = stack.top(); // Iterable
stack.pop();
PycRef<ASTBlock> top = blocks.top();
blocks.pop();
PycRef<ASTIterBlock> forblk = new ASTIterBlock(ASTBlock::BLK_FOR, top->end(), iter);
blocks.push(forblk.cast<ASTBlock>());
curblock = blocks.top();
/* Python Docs say:
"push the sequence, the incremented counter,
and the current item onto the stack." */
stack.push(iter);
stack.push(curidx);
stack.push(Node_NULL); // We can totally hack this >_>
}
break;
case Pyc::IMPORT_NAME_A:
if (mod->majorVer() == 1) {
stack.push(new ASTImport(new ASTName(code->getName(operand)), Node_NULL));
@@ -299,12 +326,14 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
case Pyc::POP_JUMP_IF_TRUE_A:
{
PycRef<ASTNode> cond = stack.top();
PycRef<ASTBlock> ifblk;
PycRef<ASTCondBlock> ifblk;
bool popped = false;
if (opcode == Pyc::POP_JUMP_IF_FALSE_A
|| opcode == Pyc::POP_JUMP_IF_TRUE_A) {
/* Pop condition before the jump */
stack.pop();
popped = true;
}
/* Store the current stack for the else statement(s) */
stack_hist.push(stack);
@@ -312,6 +341,7 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
|| opcode == Pyc::JUMP_IF_TRUE_OR_POP_A) {
/* Pop condition only if condition is met */
stack.pop();
popped = true;
}
/* "Jump if true" means "Jump if not false" */
@@ -345,6 +375,10 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
/* Plain old if statement */
ifblk = new ASTCondBlock(ASTBlock::BLK_IF, offs, cond, neg);
}
if (popped)
ifblk->popCondition();
blocks.push(ifblk.cast<ASTBlock>());
curblock = blocks.top();
}
@@ -457,6 +491,9 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
{
PycRef<ASTBlock> tmp = curblock;
if (tmp->blktype() == ASTBlock::BLK_FOR)
break;
blocks.pop();
curblock = blocks.top();
curblock->append(tmp.cast<ASTNode>());
@@ -476,6 +513,14 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
{
PycRef<ASTNode> value = stack.top();
stack.pop();
if (curblock->blktype() == ASTBlock::BLK_IF
|| curblock->blktype() == ASTBlock::BLK_ELIF
|| curblock->blktype() == ASTBlock::BLK_ELSE)
{
curblock.cast<ASTCondBlock>()->popCondition();
break;
}
if (value->type() == ASTNode::NODE_CALL) {
curblock->append(value);
}
@@ -488,6 +533,16 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
case Pyc::PRINT_NEWLINE:
curblock->append(new ASTPrint(Node_NULL));
break;
case Pyc::RAISE_VARARGS_A:
{
ASTRaise::param_t paramList;
for (int i = 0; i < operand; i++) {
paramList.push_front(stack.top());
stack.pop();
}
curblock->append(new ASTRaise(paramList));
}
break;
case Pyc::RETURN_VALUE:
{
PycRef<ASTNode> value = stack.top();
@@ -558,11 +613,19 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
PycRef<ASTNode> value = stack.top();
stack.pop();
PycRef<ASTNode> name;
if (mod->majorVer() == 1 && mod->minorVer() < 3)
name = new ASTName(code->getName(operand));
else
name = new ASTName(code->getVarName(operand));
curblock->append(new ASTStore(value, name));
if (curblock->blktype() == ASTBlock::BLK_FOR
&& !curblock.cast<ASTIterBlock>()->idxset())
{
curblock.cast<ASTIterBlock>()->setIndex(name);
} else {
curblock->append(new ASTStore(value, name));
}
}
break;
case Pyc::STORE_GLOBAL_A:
@@ -603,6 +666,13 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
stack.push(new ASTCall(func, ASTCall::pparam_t(), ASTCall::kwparam_t()));
}
break;
case Pyc::UNARY_CONVERT:
{
PycRef<ASTNode> name = stack.top();
stack.pop();
stack.push(new ASTConvert(name));
}
break;
case Pyc::UNARY_INVERT:
{
PycRef<ASTNode> arg = stack.top();
@@ -792,6 +862,11 @@ void print_src(PycRef<ASTNode> node, PycModule* mod)
printf(")");
}
break;
case ASTNode::NODE_KEYWORD:
{
printf("%s", node.cast<ASTKeyword>()->word_str());
}
break;
case ASTNode::NODE_LIST:
{
ASTList::value_t values = node.cast<ASTList>()->values();
@@ -901,6 +976,18 @@ void print_src(PycRef<ASTNode> node, PycModule* mod)
print_src(node.cast<ASTPrint>()->value(), mod);
}
break;
case ASTNode::NODE_RAISE:
{
PycRef<ASTRaise> raise = node.cast<ASTRaise>();
printf("raise ");
bool first = true;
for (ASTRaise::param_t::const_iterator p = raise->params().begin(); p != raise->params().end(); ++p) {
if (!first) printf(", ");
print_src(*p, mod);
first = false;
}
}
break;
case ASTNode::NODE_RETURN:
printf("return ");
print_src(node.cast<ASTReturn>()->value(), mod);
@@ -1014,6 +1101,13 @@ void print_src(PycRef<ASTNode> node, PycModule* mod)
printf("]");
}
break;
case ASTNode::NODE_CONVERT:
{
printf("`");
print_src(node.cast<ASTConvert>()->name(), mod);
printf("`");
}
break;
case ASTNode::NODE_TUPLE:
{
ASTTuple::value_t values = node.cast<ASTTuple>()->values();