[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