[Scummvm-cvs-logs] SF.net SVN: scummvm:[54908] tools/branches/gsoc2010-decompiler/decompiler
pidgeot at users.sourceforge.net
pidgeot at users.sourceforge.net
Tue Dec 14 23:20:42 CET 2010
Revision: 54908
http://scummvm.svn.sourceforge.net/scummvm/?rev=54908&view=rev
Author: pidgeot
Date: 2010-12-14 22:20:42 +0000 (Tue, 14 Dec 2010)
Log Message:
-----------
DECOMPILER: Add operator precedence
Modified Paths:
--------------
tools/branches/gsoc2010-decompiler/decompiler/test/codegen.h
tools/branches/gsoc2010-decompiler/decompiler/value.cpp
tools/branches/gsoc2010-decompiler/decompiler/value.h
Modified: tools/branches/gsoc2010-decompiler/decompiler/test/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/test/codegen.h 2010-12-14 19:11:16 UTC (rev 54907)
+++ tools/branches/gsoc2010-decompiler/decompiler/test/codegen.h 2010-12-14 22:20:42 UTC (rev 54908)
@@ -89,11 +89,11 @@
VertexIterator v = boost::vertices(g).first;
std::vector<std::string> output, expected;
expected.push_back("do{");
- expected.push_back("if(!((18 == var321))) {");
+ expected.push_back("if(18 != var321) {");
expected.push_back("continue;");
expected.push_back("}");
- expected.push_back("(VAR_CHARSET_MASK)--;");
- expected.push_back("} while ((42 == VAR_CHARSET_MASK))");
+ expected.push_back("VAR_CHARSET_MASK--;");
+ expected.push_back("} while (42 == VAR_CHARSET_MASK)");
expected.push_back("stopObjectCodeA();");
GroupPtr gr = GET(*v);
// Find first node
@@ -132,11 +132,11 @@
VertexIterator v = boost::vertices(g).first;
std::vector<std::string> output, expected;
- expected.push_back("while (!((42 == VAR_CHARSET_MASK))) {");
- expected.push_back("if (!((18 == var321))) {");
+ expected.push_back("while (42 != VAR_CHARSET_MASK) {");
+ expected.push_back("if (18 != var321) {");
expected.push_back("break;");
expected.push_back("}");
- expected.push_back("(VAR_CHARSET_MASK)--;");
+ expected.push_back("VAR_CHARSET_MASK--;");
expected.push_back("}");
expected.push_back("stopObjectCodeA();");
GroupPtr gr = GET(*v);
@@ -176,10 +176,10 @@
VertexIterator v = boost::vertices(g).first;
std::vector<std::string> output, expected;
- expected.push_back("if (!((42 == VAR_CHARSET_MASK))) {");
- expected.push_back("(VAR_CHARSET_MASK)--;");
+ expected.push_back("if (42 != VAR_CHARSET_MASK) {");
+ expected.push_back("VAR_CHARSET_MASK--;");
expected.push_back("} else {");
- expected.push_back("(VAR_CHARSET_MASK)++;");
+ expected.push_back("VAR_CHARSET_MASK++;");
expected.push_back("}");
expected.push_back("stopObjectCodeA();");
GroupPtr gr = GET(*v);
@@ -288,7 +288,7 @@
VertexIterator v = boost::vertices(g).first;
std::vector<std::string> output, expected;
expected.push_back("auto_sub0x278(param1, param2, param3, param4) {");
- expected.push_back("if (((((var1 > param1) && (var1 < param3)) && (var2 > param2)) && (var2 < param4))) {");
+ expected.push_back("if (var1 > param1 && var1 < param3 && var2 > param2 && var2 < param4) {");
expected.push_back("retval = o1_queryGameFlag(3);");
expected.push_back("if (retval) {");
expected.push_back("retval = o2_drawBox(param1, param2, param3, param4, 199);");
Modified: tools/branches/gsoc2010-decompiler/decompiler/value.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/value.cpp 2010-12-14 19:11:16 UTC (rev 54907)
+++ tools/branches/gsoc2010-decompiler/decompiler/value.cpp 2010-12-14 22:20:42 UTC (rev 54908)
@@ -23,10 +23,44 @@
#include "value.h"
#include <boost/format.hpp>
+#include <map>
#include <sstream>
+#include <string>
static int dupindex = 0;
+static std::map<std::string, int> binaryOpPrecedence;
+static std::map<std::string, std::string> negateMap;
+void initPrecedence() {
+ binaryOpPrecedence["||"] = kLogicalOrPrecedence;
+ binaryOpPrecedence["&&"] = kLogicalAndPrecedence;
+ binaryOpPrecedence["|"] = kBitwiseOrPrecedence;
+ binaryOpPrecedence["^"] = kBitwiseXorPrecedence;
+ binaryOpPrecedence["&"] = kBitwiseAndPrecedence;
+ binaryOpPrecedence["=="] = kEqualityOpPrecedence;
+ binaryOpPrecedence["!="] = kEqualityOpPrecedence;
+ binaryOpPrecedence["<"] = kRelationOpPrecedence;
+ binaryOpPrecedence["<="] = kRelationOpPrecedence;
+ binaryOpPrecedence[">="] = kRelationOpPrecedence;
+ binaryOpPrecedence[">"] = kRelationOpPrecedence;
+ binaryOpPrecedence["<<"] = kShiftOpPrecedence;
+ binaryOpPrecedence[">>"] = kShiftOpPrecedence;
+ binaryOpPrecedence["+"] = kAddOpPrecedence;
+ binaryOpPrecedence["-"] = kAddOpPrecedence;
+ binaryOpPrecedence["*"] = kMultOpPrecedence;
+ binaryOpPrecedence["/"] = kMultOpPrecedence;
+ binaryOpPrecedence["%"] = kMultOpPrecedence;
+}
+
+void initNegateMap() {
+ negateMap["=="] = "!=";
+ negateMap["!="] = "==";
+ negateMap["<"] = ">=";
+ negateMap["<="] = ">";
+ negateMap[">="] = "<";
+ negateMap[">"] = "<=";
+}
+
bool Value::isInteger() {
return false;
}
@@ -63,6 +97,10 @@
return s.str();
}
+int Value::precedence() const {
+ return kNoPrecedence;
+}
+
bool IntValue::isInteger() {
return true;
}
@@ -149,16 +187,49 @@
}
std::ostream &BinaryOpValue::print(std::ostream &output) const {
- return output << "(" << _lhs << " " << _op << " " << _rhs << ")";
+ if (_lhs->precedence() > precedence())
+ output << "(" << _lhs << ")";
+ else
+ output << _lhs;
+ output << " " << _op << " ";
+ if (_rhs->precedence() > precedence())
+ output << "(" << _rhs << ")";
+ else
+ output << _rhs;
+ return output;
}
+int BinaryOpValue::precedence() const {
+ if (binaryOpPrecedence.empty())
+ initPrecedence();
+ return binaryOpPrecedence[_op];
+}
+
+ValuePtr BinaryOpValue::negate() throw(WrongTypeException) {
+ if (negateMap.empty())
+ initNegateMap();
+ if (negateMap.find(_op) == negateMap.end())
+ return Value::negate();
+ else
+ return new BinaryOpValue(_lhs, _rhs, negateMap[_op]);
+}
+
std::ostream &UnaryOpValue::print(std::ostream &output) const {
+ if (!_isPostfix)
+ output << _op;
+ if (_operand->precedence() > precedence())
+ output << "(" << _operand << ")";
+ else
+ output << _operand;
if (_isPostfix)
- return output << "(" << _operand << ")" << _op;
- else
- return output << _op << "(" << _operand << ")";
+ output << _op;
+ return output;
}
+int UnaryOpValue::precedence() const {
+ return kUnaryOpPrecedence;
+}
+
ValuePtr NegatedValue::negate() throw(WrongTypeException) {
return _operand;
}
Modified: tools/branches/gsoc2010-decompiler/decompiler/value.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/value.h 2010-12-14 19:11:16 UTC (rev 54907)
+++ tools/branches/gsoc2010-decompiler/decompiler/value.h 2010-12-14 22:20:42 UTC (rev 54908)
@@ -36,6 +36,19 @@
class Value;
+const int kNoPrecedence = 0; ///< Precedence value for individual values with no operations.
+const int kUnaryOpPrecedence = 1; ///< Precedence value for a unary operation. (!, -, ~, etc.)
+const int kMultOpPrecedence = 2; ///< Precedence value for multiplication, division, modulus (*, /, %)
+const int kAddOpPrecedence = 3; ///< Precedence value for addition and subtraction (+, -)
+const int kShiftOpPrecedence = 4; ///< precedence value for bit shifting (<<, >>)
+const int kRelationOpPrecedence = 5; ///< Precedence value for relative comparison (<, <=, >=, >)
+const int kEqualityOpPrecedence = 6; ///< Precedence value for equality comparisons (==, !=)
+const int kBitwiseAndPrecedence = 7; ///< Precedence value for bitwise AND (&)
+const int kBitwiseXorPrecedence = 8; ///< Precedence value for bitwise XOR (^)
+const int kBitwiseOrPrecedence = 9; ///< Precedence value for bitwise OR (|)
+const int kLogicalAndPrecedence = 10; ///< Precedence value for logical AND (&&)
+const int kLogicalOrPrecedence = 11; ///< Precedence value for logical OR (||)
+
/**
* Pointer to a Value.
*/
@@ -55,7 +68,7 @@
* Class representing a value (stack entry, parameter, etc.)
*/
class Value : public RefCounted {
- public:
+public:
virtual ~Value() { }
/**
@@ -128,6 +141,14 @@
virtual ValuePtr negate() throw(WrongTypeException);
/**
+ * Operator precedence for this value.
+ * Lower values bind stronger, i.e. they are resolved earlier.
+ * In other words, if an operand has a higher precedence value than the
+ * operator, parentheses are not required for that operand.
+ */
+ virtual int precedence() const;
+
+ /**
* Output a value to an std::ostream.
*
* @param output The std::ostream to output to.
@@ -306,6 +327,10 @@
BinaryOpValue(ValuePtr lhs, ValuePtr rhs, std::string op) : _lhs(lhs), _rhs(rhs), _op(op) { }
virtual std::ostream &print(std::ostream &output) const;
+
+ virtual ValuePtr negate() throw(WrongTypeException);
+
+ virtual int precedence() const;
};
/**
@@ -329,6 +354,8 @@
_operand(operand), _op(op), _isPostfix(isPostfix) { }
virtual std::ostream &print(std::ostream &output) const;
+
+ virtual int precedence() const;
};
/**
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list