diff --git a/ASTNode.h b/ASTNode.h index 0047b5a..78c59b8 100644 --- a/ASTNode.h +++ b/ASTNode.h @@ -11,7 +11,10 @@ public: enum Type { NODE_INVALID, NODE_LIST, NODE_OBJECT, NODE_UNARY, NODE_BINARY, NODE_COMPARE, NODE_STORE, NODE_RETURN, NODE_NAME, NODE_DELETE, - NODE_FUNCTION, NODE_CLASS, NODE_CALL, NODE_PASS + NODE_FUNCTION, NODE_CLASS, NODE_CALL, NODE_IMPORT, NODE_TUPLE, + + // Empty nodes + NODE_PASS, NODE_LOCALS }; ASTNode(int type = NODE_INVALID) : m_refs(0), m_type(type) { } @@ -77,7 +80,8 @@ class ASTBinary : public ASTNode { public: enum BinOp { BIN_POWER, BIN_MULTIPLY, BIN_DIVIDE, BIN_MODULO, BIN_ADD, - BIN_SUBTRACT, BIN_LSHIFT, BIN_RSHIFT, BIN_AND, BIN_XOR, BIN_OR + BIN_SUBTRACT, BIN_LSHIFT, BIN_RSHIFT, BIN_AND, BIN_XOR, + BIN_OR, BIN_ATTR }; ASTBinary(PycRef left, PycRef right, int op, @@ -141,16 +145,13 @@ private: class ASTName : public ASTNode { public: - typedef std::list > name_t; - ASTName(PycRef name) - : ASTNode(NODE_NAME) { m_name.push_back(name); } + : ASTNode(NODE_NAME), m_name(name) { } - const name_t& name() const { return m_name; } - void add(PycRef name) { m_name.push_back(name); } + PycRef name() const { return m_name; } private: - name_t m_name; + PycRef m_name; }; @@ -184,13 +185,17 @@ private: class ASTClass : public ASTNode { public: - ASTClass(PycRef code) - : ASTNode(NODE_CLASS), m_code(code) { } + ASTClass(PycRef code, PycRef bases, PycRef name) + : ASTNode(NODE_CLASS), m_code(code), m_bases(bases), m_name(name) { } PycRef code() const { return m_code; } + PycRef bases() const { return m_bases; } + PycRef name() const { return m_name; } private: PycRef m_code; + PycRef m_bases; + PycRef m_name; }; @@ -212,4 +217,32 @@ private: kwparam_t m_kwparams; }; + +class ASTImport : public ASTNode { +public: + ASTImport(PycRef name, PycRef fromlist) + : ASTNode(NODE_IMPORT), m_name(name), m_fromlist(fromlist) { } + + PycRef name() const { return m_name; } + PycRef fromlist() const { return m_fromlist; } + +private: + PycRef m_name; + PycRef m_fromlist; +}; + + +class ASTTuple : public ASTNode { +public: + typedef std::vector > value_t; + + ASTTuple(value_t values) + : ASTNode(NODE_TUPLE), m_values(values) { } + + const value_t& values() const { return m_values; } + +private: + value_t m_values; +}; + #endif diff --git a/ASTree.cpp b/ASTree.cpp index 417cc0d..5420bb4 100644 --- a/ASTree.cpp +++ b/ASTree.cpp @@ -47,6 +47,18 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) stack.push(new ASTBinary(left, right, ASTBinary::BIN_AND)); } break; + case (PY_1000 | Py1k::BUILD_CLASS): + case (PY_2000 | Py2k::BUILD_CLASS): + { + PycRef code = stack.top(); + stack.pop(); + PycRef bases = stack.top(); + stack.pop(); + PycRef name = stack.top(); + stack.pop(); + stack.push(new ASTClass(code, bases, name)); + } + break; case (PY_1000 | Py1k::BUILD_FUNCTION): { PycRef code = stack.top(); @@ -54,6 +66,19 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) stack.push(new ASTFunction(code, ASTFunction::defarg_t())); } break; + case (PY_1000 | Py1k::BUILD_TUPLE): + case (PY_2000 | Py2k::BUILD_TUPLE): + case (PY_3000 | Py3k::BUILD_TUPLE): + { + ASTTuple::value_t tuple; + tuple.resize(operand); + for (int i=0; i BuildFromCode(PycRef code, PycModule* mod) stack.push(new ASTCompare(left, right, operand)); } break; + case (PY_1000 | Py1k::IMPORT_NAME): + stack.push(new ASTImport(new ASTName(code->getName(operand)), Node_NULL)); + break; + case (PY_2000 | Py2k::IMPORT_NAME): + { + PycRef fromlist = stack.top(); + stack.pop(); + if (mod->minorVer() >= 5) + stack.pop(); // Level -- we don't care + stack.push(new ASTImport(new ASTName(code->getName(operand)), fromlist)); + } + break; + case (PY_3000 | Py3k::IMPORT_NAME): + { + PycRef fromlist = stack.top(); + stack.pop(); + stack.pop(); // Level -- we don't care + stack.push(new ASTImport(new ASTName(code->getName(operand)), fromlist)); + } + break; + case (PY_1000 | Py1k::LOAD_ATTR): + case (PY_2000 | Py2k::LOAD_ATTR): + case (PY_3000 | Py3k::LOAD_ATTR): + { + PycRef name = stack.top(); + stack.pop(); + stack.push(new ASTBinary(name, new ASTName(code->getName(operand)), ASTBinary::BIN_ATTR)); + } + break; case (PY_1000 | Py1k::LOAD_CONST): case (PY_2000 | Py2k::LOAD_CONST): case (PY_3000 | Py3k::LOAD_CONST): @@ -107,6 +161,12 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) case (PY_1000 | Py1k::LOAD_GLOBAL): case (PY_2000 | Py2k::LOAD_GLOBAL): case (PY_3000 | Py3k::LOAD_GLOBAL): + stack.push(new ASTName(code->getName(operand))); + break; + case (PY_1000 | Py1k::LOAD_LOCALS): + case (PY_2000 | Py2k::LOAD_LOCALS): + stack.push(new ASTNode(ASTNode::NODE_LOCALS)); + break; case (PY_1000 | Py1k::LOAD_NAME): case (PY_2000 | Py2k::LOAD_NAME): case (PY_3000 | Py3k::LOAD_NAME): @@ -174,11 +234,17 @@ void print_src(PycRef node, PycModule* mod, int indent) case ASTNode::NODE_COMPARE: { PycRef bin = node.cast(); - printf("("); - print_src(bin->left(), mod); - printf(" %s ", bin->op_str()); - print_src(bin->right(), mod); - printf(")"); + if (bin->op() == ASTBinary::BIN_ATTR) { + print_src(bin->left(), mod); + printf("."); + print_src(bin->right(), mod); + } else { + printf("("); + print_src(bin->left(), mod); + printf(" %s ", bin->op_str()); + print_src(bin->right(), mod); + printf(")"); + } } break; case ASTNode::NODE_CALL: @@ -231,6 +297,46 @@ void print_src(PycRef node, PycModule* mod, int indent) } printf("):\n"); print_src(code, mod, indent + 1); + } else if (src->type() == ASTNode::NODE_CLASS) { + printf("\n"); + start_indent(indent); + printf("class "); + print_src(dest, mod); + printf("("); + PycRef bases = src.cast()->bases().cast(); + bool first = true; + for (ASTTuple::value_t::const_iterator b = bases->values().begin(); b != bases->values().end(); ++b) { + if (!first) printf(", "); + print_src(*b, mod); + first = false; + } + printf("):\n"); + PycRef code = src.cast()->code().cast() + ->func().cast()->code(); + print_src(code, mod, indent + 1); + } else if (src->type() == ASTNode::NODE_IMPORT) { + start_indent(indent); + PycRef import = src.cast(); + if (import->fromlist() != Node_NULL) { + PycRef fromlist = import->fromlist().cast()->object().cast(); + if (fromlist != Pyc_None && fromlist->size() != 0) { + printf("from "); + print_src(import->name(), mod); + printf(" import "); + bool first = true; + PycTuple::value_t::const_iterator ii = fromlist->values().begin(); + for (; ii != fromlist->values().end(); ++ii) { + if (first) printf(", "); + printf("%s", ii->cast()->value()); + } + } else { + printf("import "); + print_src(import->name(), mod); + } + } else { + printf("import "); + print_src(import->name(), mod); + } } else { start_indent(indent); print_src(dest, mod); @@ -240,13 +346,7 @@ void print_src(PycRef node, PycModule* mod, int indent) } break; case ASTNode::NODE_NAME: - { - ASTName::name_t name = node.cast()->name(); - ASTName::name_t::const_iterator n = name.begin(); - printf("%s", (*n)->value()); - while (++n != name.end()) - printf(".%s", (*n)->value()); - } + printf("%s", node.cast()->name()->value()); break; case ASTNode::NODE_OBJECT: { @@ -266,6 +366,22 @@ void print_src(PycRef node, PycModule* mod, int indent) printf("return "); print_src(node.cast()->value(), mod); break; + case ASTNode::NODE_TUPLE: + { + PycRef tuple = node.cast(); + printf("("); + bool first = true; + for (ASTTuple::value_t::const_iterator b = tuple->values().begin(); b != tuple->values().end(); ++b) { + if (!first) printf(", "); + print_src(*b, mod); + first = false; + } + if (tuple->values().size() == 1) + printf(",)"); + else + printf(")"); + } + break; default: fprintf(stderr, "Unsupported Node type: %d\n", node->type()); } @@ -287,9 +403,8 @@ void decompyle(PycRef code, PycModule* mod, int indent) store->dest()->type() == ASTNode::NODE_NAME) { PycRef src = store->src().cast(); PycRef dest = store->dest().cast(); - if (src->name().size() == 1 && dest->name().size() == 1 && - src->name().front()->isEqual("__name__") && - dest->name().front()->isEqual("__module__")) { + if (src->name()->isEqual("__name__") && + dest->name()->isEqual("__module__")) { // __module__ = __name__ clean->removeFirst(); } diff --git a/bytecode.cpp b/bytecode.cpp index 49df5d2..68a04b0 100644 --- a/bytecode.cpp +++ b/bytecode.cpp @@ -258,7 +258,10 @@ void print_const(PycRef obj, PycModule* mod) print_const(*it, mod); } } - printf(")"); + if (values.size() == 1) + printf(",)"); + else + printf(")"); } break; case PycObject::TYPE_LIST: diff --git a/sequence.cpp b/sequence.cpp index 4f2ab12..076755c 100644 --- a/sequence.cpp +++ b/sequence.cpp @@ -3,15 +3,6 @@ #include "module.h" /* PycTuple */ -PycRef PycTuple::Build(const value_t& items) -{ - PycRef tupleObj = new PycTuple(); - tupleObj->m_size = items.size(); - tupleObj->m_values.resize(tupleObj->m_size); - std::copy(items.begin(), items.end(), tupleObj->m_values.begin()); - return tupleObj; -} - void PycTuple::load(PycData* stream, PycModule* mod) { m_size = stream->get32(); diff --git a/sequence.h b/sequence.h index 348d454..2145699 100644 --- a/sequence.h +++ b/sequence.h @@ -22,7 +22,6 @@ public: typedef std::vector > value_t; PycTuple(int type = TYPE_TUPLE) : PycSequence(type) { } - static PycRef Build(const value_t& items); bool isEqual(PycRef obj) const;