Support for closure functions.

This commit is contained in:
Darryl Pogue
2011-10-16 22:46:17 -07:00
parent 03b96592a2
commit f795613445
3 changed files with 74 additions and 5 deletions

View File

@@ -1133,6 +1133,9 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
}
}
break;
case Pyc::LOAD_CLOSURE_A:
/* Ignore this */
break;
case Pyc::LOAD_CONST_A:
{
PycRef<ASTObject> t_ob = new ASTObject(code->getConst(operand));
@@ -1148,6 +1151,9 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
}
}
break;
case Pyc::LOAD_DEREF_A:
stack.push(new ASTName(code->getCellVar(operand).cast<PycString>()));
break;
case Pyc::LOAD_FAST_A:
if (mod->majorVer() == 1 && mod->minorVer() < 3)
stack.push(new ASTName(code->getName(operand)));
@@ -1163,6 +1169,7 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
case Pyc::LOAD_NAME_A:
stack.push(new ASTName(code->getName(operand)));
break;
case Pyc::MAKE_CLOSURE_A:
case Pyc::MAKE_FUNCTION_A:
{
PycRef<ASTNode> code = stack.top();
@@ -1526,6 +1533,39 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
}
}
break;
case Pyc::STORE_DEREF_A:
{
if (unpack) {
PycRef<ASTNode> name = new ASTName(code->getCellVar(operand).cast<PycString>());
PycRef<ASTNode> tup = stack.top();
if (tup->type() == ASTNode::NODE_TUPLE) {
stack.pop();
PycRef<ASTTuple> tuple = tup.cast<ASTTuple>();
tuple->add(name);
stack.push(tuple.cast<ASTNode>());
} else {
fprintf(stderr, "Something TERRIBLE happened!\n");
}
if (--unpack <= 0) {
PycRef<ASTNode> tup = stack.top();
stack.pop();
PycRef<ASTNode> seq = stack.top();
stack.pop();
curblock->append(new ASTStore(seq, tup));
}
} else {
PycRef<ASTNode> value = stack.top();
stack.pop();
PycRef<ASTNode> name = new ASTName(code->getCellVar(operand).cast<PycString>());
curblock->append(new ASTStore(value, name));
}
}
break;
case Pyc::STORE_FAST_A:
{
if (unpack) {
@@ -1583,10 +1623,39 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
break;
case Pyc::STORE_GLOBAL_A:
{
PycRef<ASTNode> value = stack.top();
stack.pop();
PycRef<ASTNode> name = new ASTName(code->getName(operand));
curblock->append(new ASTStore(value, name));
if (unpack) {
PycRef<ASTNode> tup = stack.top();
if (tup->type() == ASTNode::NODE_TUPLE) {
stack.pop();
PycRef<ASTTuple> tuple = tup.cast<ASTTuple>();
tuple->add(name);
stack.push(tuple.cast<ASTNode>());
} else {
fprintf(stderr, "Something TERRIBLE happened!\n");
}
if (--unpack <= 0) {
PycRef<ASTNode> tup = stack.top();
stack.pop();
PycRef<ASTNode> seq = stack.top();
stack.pop();
if (curblock->blktype() == ASTBlock::BLK_FOR
&& !curblock->inited()) {
curblock.cast<ASTIterBlock>()->setIndex(tup);
} else {
curblock->append(new ASTStore(seq, tup));
}
}
} else {
PycRef<ASTNode> value = stack.top();
stack.pop();
curblock->append(new ASTStore(value, name));
}
/* Mark the global as used */
code->markGlobal(name.cast<ASTName>()->name());

View File

@@ -317,7 +317,7 @@ void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent)
printf("%d: %s", operand, code->getVarName(operand)->value());
} else if (Pyc::IsCellArg(opcode)) {
printf("%d: ", operand);
print_const(code->getConst(operand), mod);
print_const(code->getCellVar(operand), mod);
} else if (Pyc::IsJumpOffsetArg(opcode)) {
printf("%d (to %d)", operand, pos+operand);
} else {

2
code.h
View File

@@ -57,7 +57,7 @@ public:
PycRef<PycObject> getCellVar(int idx) const
{
return (idx > m_cellVars->size()) ? m_freeVars->get(idx - m_cellVars->size())
return (idx >= m_cellVars->size()) ? m_freeVars->get(idx - m_cellVars->size())
: m_cellVars->get(idx);
}