From 17f962e9f1fb60abe9d5020ba41d1346ad5346c4 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Mon, 27 Jul 2009 08:42:59 +0000 Subject: [PATCH] Various formatting fixes and more code support --- ASTNode.cpp | 3 +- ASTNode.h | 53 ++++++- ASTree.cpp | 429 ++++++++++++++++++++++++++++++++++++++++------------ ASTree.h | 2 +- 4 files changed, 388 insertions(+), 99 deletions(-) diff --git a/ASTNode.cpp b/ASTNode.cpp index c09f50e..e28f52b 100644 --- a/ASTNode.cpp +++ b/ASTNode.cpp @@ -21,7 +21,8 @@ void ASTNodeList::removeFirst() const char* ASTBinary::op_str() const { static const char* s_op_strings[] = { - "**", "*", "/", "%", "+", "-", "<<", ">>", "&", "^", "|" + "**", "*", "/", "%", "+", "-", "<<", ">>", "&", "^", "|", "//", + "" }; return s_op_strings[op()]; } diff --git a/ASTNode.h b/ASTNode.h index 78c59b8..5346240 100644 --- a/ASTNode.h +++ b/ASTNode.h @@ -9,9 +9,10 @@ class ASTNode { public: enum Type { - NODE_INVALID, NODE_LIST, NODE_OBJECT, NODE_UNARY, NODE_BINARY, + NODE_INVALID, NODE_NODELIST, NODE_OBJECT, NODE_UNARY, NODE_BINARY, NODE_COMPARE, NODE_STORE, NODE_RETURN, NODE_NAME, NODE_DELETE, NODE_FUNCTION, NODE_CLASS, NODE_CALL, NODE_IMPORT, NODE_TUPLE, + NODE_LIST, NODE_MAP, NODE_SUBSCR, // Empty nodes NODE_PASS, NODE_LOCALS @@ -40,7 +41,7 @@ public: typedef std::list > list_t; ASTNodeList(list_t nodes) - : ASTNode(NODE_LIST), m_nodes(nodes) { } + : ASTNode(NODE_NODELIST), m_nodes(nodes) { } const list_t& nodes() const { return m_nodes; } void removeFirst(); @@ -81,7 +82,7 @@ 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_ATTR + BIN_OR, BIN_FLOOR, BIN_ATTR }; ASTBinary(PycRef left, PycRef right, int op, @@ -172,7 +173,7 @@ public: typedef std::list > defarg_t; ASTFunction(PycRef code, defarg_t defArgs) - : ASTNode(NODE_FUNCTION), m_code(code) { } + : ASTNode(NODE_FUNCTION), m_code(code), m_defargs(defArgs) { } PycRef code() const { return m_code; } const defarg_t& defargs() const { return m_defargs; } @@ -245,4 +246,48 @@ private: value_t m_values; }; + +class ASTList : public ASTNode { +public: + typedef std::list > value_t; + + ASTList(value_t values) + : ASTNode(NODE_LIST), m_values(values) { } + + const value_t& values() const { return m_values; } + +private: + value_t m_values; +}; + + +class ASTMap : public ASTNode { +public: + typedef std::list, PycRef > > map_t; + + ASTMap() : ASTNode(NODE_MAP) { } + + void add(PycRef key, PycRef value) + { m_values.push_back(std::make_pair(key, value)); } + + const map_t& values() const { return m_values; } + +private: + map_t m_values; +}; + + +class ASTSubscr : public ASTNode { +public: + ASTSubscr(PycRef name, PycRef key) + : ASTNode(NODE_SUBSCR), m_name(name), m_key(key) { } + + PycRef name() const { return m_name; } + PycRef key() const { return m_key; } + +private: + PycRef m_name; + PycRef m_key; +}; + #endif diff --git a/ASTree.cpp b/ASTree.cpp index 348cd59..a219307 100644 --- a/ASTree.cpp +++ b/ASTree.cpp @@ -36,6 +36,17 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) opcode |= opadd; switch (opcode) { + case (PY_1000 | Py1k::BINARY_ADD): + case (PY_2000 | Py2k::BINARY_ADD): + case (PY_3000 | Py3k::BINARY_ADD): + { + PycRef right = stack.top(); + stack.pop(); + PycRef left = stack.top(); + stack.pop(); + stack.push(new ASTBinary(left, right, ASTBinary::BIN_ADD)); + } + break; case (PY_1000 | Py1k::BINARY_AND): case (PY_2000 | Py2k::BINARY_AND): case (PY_3000 | Py3k::BINARY_AND): @@ -47,6 +58,124 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) stack.push(new ASTBinary(left, right, ASTBinary::BIN_AND)); } break; + case (PY_1000 | Py1k::BINARY_DIVIDE): + case (PY_2000 | Py2k::BINARY_DIVIDE): + { + PycRef right = stack.top(); + stack.pop(); + PycRef left = stack.top(); + stack.pop(); + stack.push(new ASTBinary(left, right, ASTBinary::BIN_DIVIDE)); + } + break; + case (PY_2000 | Py2k::BINARY_FLOOR_DIVIDE): + case (PY_3000 | Py3k::BINARY_FLOOR_DIVIDE): + { + PycRef right = stack.top(); + stack.pop(); + PycRef left = stack.top(); + stack.pop(); + stack.push(new ASTBinary(left, right, ASTBinary::BIN_FLOOR)); + } + break; + case (PY_1000 | Py1k::BINARY_LSHIFT): + case (PY_2000 | Py2k::BINARY_LSHIFT): + case (PY_3000 | Py3k::BINARY_LSHIFT): + { + PycRef right = stack.top(); + stack.pop(); + PycRef left = stack.top(); + stack.pop(); + stack.push(new ASTBinary(left, right, ASTBinary::BIN_LSHIFT)); + } + break; + case (PY_1000 | Py1k::BINARY_MODULO): + case (PY_2000 | Py2k::BINARY_MODULO): + case (PY_3000 | Py3k::BINARY_MODULO): + { + PycRef right = stack.top(); + stack.pop(); + PycRef left = stack.top(); + stack.pop(); + stack.push(new ASTBinary(left, right, ASTBinary::BIN_MODULO)); + } + break; + case (PY_1000 | Py1k::BINARY_MULTIPLY): + case (PY_2000 | Py2k::BINARY_MULTIPLY): + case (PY_3000 | Py3k::BINARY_MULTIPLY): + { + PycRef right = stack.top(); + stack.pop(); + PycRef left = stack.top(); + stack.pop(); + stack.push(new ASTBinary(left, right, ASTBinary::BIN_SUBTRACT)); + } + break; + case (PY_1000 | Py1k::BINARY_OR): + case (PY_2000 | Py2k::BINARY_OR): + case (PY_3000 | Py3k::BINARY_OR): + { + PycRef right = stack.top(); + stack.pop(); + PycRef left = stack.top(); + stack.pop(); + stack.push(new ASTBinary(left, right, ASTBinary::BIN_OR)); + } + break; + case (PY_1000 | Py1k::BINARY_POWER): + case (PY_2000 | Py2k::BINARY_POWER): + case (PY_3000 | Py3k::BINARY_POWER): + { + PycRef right = stack.top(); + stack.pop(); + PycRef left = stack.top(); + stack.pop(); + stack.push(new ASTBinary(left, right, ASTBinary::BIN_POWER)); + } + break; + case (PY_1000 | Py1k::BINARY_RSHIFT): + case (PY_2000 | Py2k::BINARY_RSHIFT): + case (PY_3000 | Py3k::BINARY_RSHIFT): + { + PycRef right = stack.top(); + stack.pop(); + PycRef left = stack.top(); + stack.pop(); + stack.push(new ASTBinary(left, right, ASTBinary::BIN_RSHIFT)); + } + break; + case (PY_1000 | Py1k::BINARY_SUBTRACT): + case (PY_2000 | Py2k::BINARY_SUBTRACT): + case (PY_3000 | Py3k::BINARY_SUBTRACT): + { + PycRef right = stack.top(); + stack.pop(); + PycRef left = stack.top(); + stack.pop(); + stack.push(new ASTBinary(left, right, ASTBinary::BIN_SUBTRACT)); + } + break; + case (PY_2000 | Py2k::BINARY_TRUE_DIVIDE): + case (PY_3000 | Py3k::BINARY_TRUE_DIVIDE): + { + PycRef right = stack.top(); + stack.pop(); + PycRef left = stack.top(); + stack.pop(); + stack.push(new ASTBinary(left, right, ASTBinary::BIN_DIVIDE)); + } + break; + case (PY_1000 | Py1k::BINARY_XOR): + case (PY_2000 | Py2k::BINARY_XOR): + case (PY_3000 | Py3k::BINARY_XOR): + { + PycRef right = stack.top(); + stack.pop(); + PycRef left = stack.top(); + stack.pop(); + stack.push(new ASTBinary(left, right, ASTBinary::BIN_XOR)); + } + break; case (PY_1000 | Py1k::BUILD_CLASS): case (PY_2000 | Py2k::BUILD_CLASS): { @@ -66,17 +195,34 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) stack.push(new ASTFunction(code, ASTFunction::defarg_t())); } break; + case (PY_1000 | Py1k::BUILD_LIST): + case (PY_2000 | Py2k::BUILD_LIST): + case (PY_3000 | Py3k::BUILD_LIST): + { + ASTList::value_t values; + for (int i=0; i BuildFromCode(PycRef code, PycModule* mod) stack.push(new ASTCompare(left, right, operand)); } break; + case (PY_1000 | Py1k::DUP_TOP): + case (PY_2000 | Py2k::DUP_TOP): + case (PY_3000 | Py3k::DUP_TOP): + stack.push(stack.top()); + break; case (PY_1000 | Py1k::IMPORT_NAME): stack.push(new ASTImport(new ASTName(code->getName(operand)), Node_NULL)); break; @@ -213,6 +364,21 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) lines.push_back(new ASTReturn(value)); } break; + case (PY_1000 | Py1k::ROT_THREE): + case (PY_2000 | Py2k::ROT_THREE): + case (PY_3000 | Py3k::ROT_THREE): + { + PycRef one = stack.top(); + stack.pop(); + PycRef two = stack.top(); + stack.pop(); + PycRef three = stack.top(); + stack.pop(); + stack.push(one); + stack.push(three); + stack.push(two); + } + break; case (PY_1000 | Py1k::STORE_ATTR): case (PY_2000 | Py2k::STORE_ATTR): case (PY_3000 | Py3k::STORE_ATTR): @@ -225,13 +391,24 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) lines.push_back(new ASTStore(value, attr)); } break; - case (PY_1000 | Py1k::STORE_NAME): - case (PY_2000 | Py2k::STORE_NAME): - case (PY_3000 | Py3k::STORE_NAME): + case (PY_1000 | Py1k::STORE_FAST): { PycRef value = stack.top(); stack.pop(); - PycRef name = new ASTName(code->getName(operand)); + PycRef name; + if (mod->minorVer() < 3) + name = new ASTName(code->getName(operand)); + else + name = new ASTName(code->getVarName(operand)); + lines.push_back(new ASTStore(value, name)); + } + break; + case (PY_2000 | Py2k::STORE_FAST): + case (PY_3000 | Py3k::STORE_FAST): + { + PycRef value = stack.top(); + stack.pop(); + PycRef name = new ASTName(code->getVarName(operand)); lines.push_back(new ASTStore(value, name)); } break; @@ -245,6 +422,33 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) lines.push_back(new ASTStore(value, name)); } break; + case (PY_1000 | Py1k::STORE_NAME): + case (PY_2000 | Py2k::STORE_NAME): + case (PY_3000 | Py3k::STORE_NAME): + { + PycRef value = stack.top(); + stack.pop(); + PycRef name = new ASTName(code->getName(operand)); + lines.push_back(new ASTStore(value, name)); + } + break; + case (PY_1000 | Py1k::STORE_SUBSCR): + case (PY_2000 | Py2k::STORE_SUBSCR): + case (PY_3000 | Py3k::STORE_SUBSCR): + { + PycRef subscr = stack.top(); + stack.pop(); + PycRef dest = stack.top(); + stack.pop(); + PycRef src = stack.top(); + stack.pop(); + if (dest->type() == ASTNode::NODE_MAP) { + dest.cast()->add(subscr, src); + } else { + lines.push_back(new ASTStore(src, new ASTSubscr(dest, subscr))); + } + } + break; default: if (mod->majorVer() == 1) fprintf(stderr, "Unsupported opcode: %s\n", Py1k::OpcodeNames[opcode & 0xFF]); @@ -275,14 +479,14 @@ void print_src(PycRef node, PycModule* mod, int indent) { PycRef bin = node.cast(); if (bin->op() == ASTBinary::BIN_ATTR) { - print_src(bin->left(), mod); + print_src(bin->left(), mod, indent); printf("."); - print_src(bin->right(), mod); + print_src(bin->right(), mod, indent); } else { printf("("); - print_src(bin->left(), mod); + print_src(bin->left(), mod, indent); printf(" %s ", bin->op_str()); - print_src(bin->right(), mod); + print_src(bin->right(), mod, indent); printf(")"); } } @@ -290,20 +494,18 @@ void print_src(PycRef node, PycModule* mod, int indent) case ASTNode::NODE_CALL: { PycRef call = node.cast(); - start_indent(indent); - print_src(call->func(), mod); + print_src(call->func(), mod, indent); printf("("); bool first = true; for (ASTCall::pparam_t::const_iterator p = call->pparams().begin(); p != call->pparams().end(); ++p) { if (!first) printf(", "); - print_src(*p, mod); + print_src(*p, mod, indent); first = false; } for (ASTCall::kwparam_t::const_iterator p = call->kwparams().begin(); p != call->kwparams().end(); ++p) { if (!first) printf(", "); - print_src(p->first, mod); - printf("="); - print_src(p->second, mod); + printf("%s = ", p->first.cast()->name()->value()); + print_src(p->second, mod, indent); first = false; } printf(")"); @@ -311,84 +513,49 @@ void print_src(PycRef node, PycModule* mod, int indent) break; case ASTNode::NODE_LIST: { - ASTNodeList::list_t lines = node.cast()->nodes(); - for (ASTNodeList::list_t::const_iterator ln = lines.begin(); ln != lines.end(); ++ln) { - print_src(*ln, mod, indent); - printf("\n"); + ASTList::value_t values = node.cast()->values(); + printf("["); + bool first = true; + for (ASTList::value_t::const_iterator b = values.begin(); b != values.end(); ++b) { + if (first) printf("\n"); + else printf(",\n"); + start_indent(indent + 1); + print_src(*b, mod, indent + 1); + first = false; } + printf("]"); } break; - case ASTNode::NODE_STORE: + case ASTNode::NODE_MAP: { - PycRef src = node.cast()->src(); - PycRef dest = node.cast()->dest(); - if (src->type() == ASTNode::NODE_FUNCTION) { - printf("\n"); - start_indent(indent); - printf("def "); - print_src(dest, mod); - printf("("); - //TODO: Keyword and Default args - PycRef code = src.cast()->code(); - PycRef code_src = code.cast()->object().cast(); - for (int i=0; iargCount(); i++) { - if (i > 0) printf(", "); - printf("%s", code_src->getVarName(i)->value()); - } - 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()); - first = false; - } - } else { - printf("import "); - print_src(import->name(), mod); - } - } else { - printf("import "); - print_src(import->name(), mod); - } - } else { - start_indent(indent); - print_src(dest, mod); - printf(" = "); - print_src(src, mod); + ASTMap::map_t values = node.cast()->values(); + printf("{"); + bool first = true; + for (ASTMap::map_t::const_iterator b = values.begin(); b != values.end(); ++b) { + if (first) printf("\n"); + else printf(",\n"); + start_indent(indent + 1); + print_src(b->first, mod, indent + 1); + printf(": "); + print_src(b->second, mod, indent + 1); + first = false; } + printf("}"); } break; case ASTNode::NODE_NAME: printf("%s", node.cast()->name()->value()); break; + case ASTNode::NODE_NODELIST: + { + ASTNodeList::list_t lines = node.cast()->nodes(); + for (ASTNodeList::list_t::const_iterator ln = lines.begin(); ln != lines.end(); ++ln) { + start_indent(indent); + print_src(*ln, mod, indent); + printf("\n"); + } + } + break; case ASTNode::NODE_OBJECT: { PycRef obj = node.cast()->object(); @@ -399,31 +566,107 @@ void print_src(PycRef node, PycModule* mod, int indent) } break; case ASTNode::NODE_PASS: - start_indent(indent); printf("pass"); break; case ASTNode::NODE_RETURN: - start_indent(indent); printf("return "); - print_src(node.cast()->value(), mod); + print_src(node.cast()->value(), mod, indent); + break; + case ASTNode::NODE_STORE: + { + PycRef src = node.cast()->src(); + PycRef dest = node.cast()->dest(); + if (src->type() == ASTNode::NODE_FUNCTION) { + printf("\n"); + start_indent(indent); + printf("def "); + print_src(dest, mod, indent); + printf("("); + PycRef code = src.cast()->code(); + PycRef code_src = code.cast()->object().cast(); + ASTFunction::defarg_t defargs = src.cast()->defargs(); + ASTFunction::defarg_t::iterator da = defargs.begin(); + for (int i=0; iargCount(); i++) { + if (i > 0) printf(", "); + printf("%s", code_src->getVarName(i)->value()); + if ((code_src->argCount() - i) <= (int)defargs.size()) { + printf(" = "); + print_src(*da++, mod, 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, indent); + 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, indent); + 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) { + 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, indent); + 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()); + first = false; + } + } else { + printf("import "); + print_src(import->name(), mod, indent); + } + } else { + printf("import "); + print_src(import->name(), mod, indent); + } + } else { + print_src(dest, mod, indent); + printf(" = "); + print_src(src, mod, indent); + } + } + break; + case ASTNode::NODE_SUBSCR: + print_src(node.cast()->name(), mod, indent); + printf("["); + print_src(node.cast()->key(), mod, indent); + printf("]"); break; case ASTNode::NODE_TUPLE: { - PycRef tuple = node.cast(); + ASTTuple::value_t values = node.cast()->values(); printf("("); bool first = true; - for (ASTTuple::value_t::const_iterator b = tuple->values().begin(); b != tuple->values().end(); ++b) { + for (ASTTuple::value_t::const_iterator b = values.begin(); b != values.end(); ++b) { if (!first) printf(", "); - print_src(*b, mod); + print_src(*b, mod, indent); first = false; } - if (tuple->values().size() == 1) + if (values.size() == 1) printf(",)"); else printf(")"); } break; default: + printf("", node->type()); fprintf(stderr, "Unsupported Node type: %d\n", node->type()); cleanBuild = false; return; diff --git a/ASTree.h b/ASTree.h index 2361a0d..22e7575 100644 --- a/ASTree.h +++ b/ASTree.h @@ -4,7 +4,7 @@ #include "ASTNode.h" PycRef BuildFromCode(PycRef code, PycModule* mod); -void print_src(PycRef node, PycModule* mod, int indent = 0); +void print_src(PycRef node, PycModule* mod, int indent); void decompyle(PycRef code, PycModule* mod, int indent = 0);