[Scummvm-cvs-logs] SF.net SVN: scummvm:[54891] tools/branches/gsoc2010-decompiler
pidgeot at users.sourceforge.net
pidgeot at users.sourceforge.net
Sun Dec 12 23:50:15 CET 2010
Revision: 54891
http://scummvm.svn.sourceforge.net/scummvm/?rev=54891&view=rev
Author: pidgeot
Date: 2010-12-12 22:50:15 +0000 (Sun, 12 Dec 2010)
Log Message:
-----------
DECOMPILER: Create Value hierarchy
Change code generation to use Values instead of StackEntries
Next step: Use Value instead of Parameter
Modified Paths:
--------------
tools/branches/gsoc2010-decompiler/Makefile.common
tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp
tools/branches/gsoc2010-decompiler/decompiler/codegen.h
tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp
tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp
tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h
tools/branches/gsoc2010-decompiler/decompiler/test/module.mk
Added Paths:
-----------
tools/branches/gsoc2010-decompiler/decompiler/value.cpp
tools/branches/gsoc2010-decompiler/decompiler/value.h
Modified: tools/branches/gsoc2010-decompiler/Makefile.common
===================================================================
--- tools/branches/gsoc2010-decompiler/Makefile.common 2010-12-12 22:20:18 UTC (rev 54890)
+++ tools/branches/gsoc2010-decompiler/Makefile.common 2010-12-12 22:50:15 UTC (rev 54891)
@@ -229,6 +229,7 @@
decompile_OBJS := \
common/file.o \
decompiler/decompiler.o \
+ decompiler/value.o \
decompiler/disassembler.o \
decompiler/simple_disassembler.o \
decompiler/engine.o \
Modified: tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp 2010-12-12 22:20:18 UTC (rev 54890)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp 2010-12-12 22:50:15 UTC (rev 54891)
@@ -31,89 +31,6 @@
#define GET(vertex) (boost::get(boost::vertex_name, _g, vertex))
#define GET_EDGE(edge) (boost::get(boost::edge_attribute, _g, edge))
-static int dupindex = 0;
-
-int32 IntEntry::getValue() {
- return _val;
-}
-
-bool IntEntry::getSigned() {
- return _isSigned;
-}
-
-std::ostream &IntEntry::print(std::ostream &output) const {
- if (_isSigned)
- output << (int32)_val;
- else
- output << (uint32)_val;
- return output;
-}
-
-std::ostream &VarEntry::print(std::ostream &output) const {
- return output << _varName;
-}
-
-std::ostream &BinaryOpEntry::print(std::ostream &output) const {
- return output << "(" << _lhs << " " << _op << " " << _rhs << ")";
-}
-
-std::ostream &UnaryOpEntry::print(std::ostream &output) const {
- if (_isPostfix)
- return output << "(" << _operand << ")" << _op;
- else
- return output << _op << "(" << _operand << ")";
-}
-
-std::ostream &DupEntry::print(std::ostream &output) const {
- return output << "temp" << _idx;
-}
-
-std::ostream &ArrayEntry::print(std::ostream &output) const {
- output << _arrayName;
- for (EntryList::const_iterator i = _idxs.begin(); i != _idxs.end(); ++i)
- output << "[" << *i << "]";
- return output;
-}
-
-std::ostream &StringEntry::print(std::ostream &output) const {
- return output << _str;
-}
-
-std::ostream &ListEntry::print(std::ostream &output) const {
- output << "[";
- for (EntryList::const_iterator i = _items.begin(); i != _items.end(); ++i) {
- if (i != _items.begin())
- output << ", ";
- output << *i;
- }
- output << "]";
- return output;
-}
-
-std::ostream &CallEntry::print(std::ostream &output) const {
- output << _funcName << "(";
- for (EntryList::const_iterator i = _args.begin(); i != _args.end(); ++i) {
- if (i != _args.begin())
- output << ", ";
- output << *i;
- }
- output << ")";
- return output;
-}
-
-EntryPtr StackEntry::dup(std::ostream &output) {
- if (_type == kDupStackEntry)
- return this;
-
- EntryPtr dupEntry = new DupEntry(++dupindex);
- output << dupEntry << " = " << (EntryPtr)this << ";";
- return dupEntry;
-}
-
-EntryPtr IntEntry::dup(std::ostream &output) {
- return new IntEntry(_val, _isSigned);
-}
-
std::string CodeGenerator::constructFuncSignature(const Function &func) {
return "";
}
@@ -129,7 +46,7 @@
_indentLevel = 0;
}
-typedef std::pair<GraphVertex, EntryStack> DFSEntry;
+typedef std::pair<GraphVertex, ValueStack> DFSEntry;
void CodeGenerator::generate(const Graph &g) {
_g = g;
@@ -153,7 +70,7 @@
// DFS from entry point to process each vertex
Stack<DFSEntry> dfsStack;
std::set<GraphVertex> seen;
- dfsStack.push(DFSEntry(entryPoint, EntryStack()));
+ dfsStack.push(DFSEntry(entryPoint, ValueStack()));
seen.insert(entryPoint);
while (!dfsStack.empty()) {
DFSEntry e = dfsStack.pop();
@@ -202,7 +119,7 @@
_curGroup->_code.push_back(CodeLine(s, unindentBefore, indentAfter));
}
-void CodeGenerator::writeAssignment(EntryPtr dst, EntryPtr src) {
+void CodeGenerator::writeAssignment(ValuePtr dst, ValuePtr src) {
std::stringstream s;
s << dst << " = " << src << ";";
addOutputLine(s.str());
@@ -259,7 +176,7 @@
case kDupInstType:
{
std::stringstream s;
- EntryPtr p = _stack.pop()->dup(s);
+ ValuePtr p = _stack.pop()->dup(s);
if (s.str().length() > 0)
addOutputLine(s.str());
_stack.push(p);
@@ -268,16 +185,16 @@
}
case kUnaryOpPreInstType:
case kUnaryOpPostInstType:
- _stack.push(new UnaryOpEntry(_stack.pop(), inst->_codeGenData, inst->_type == kUnaryOpPostInstType));
+ _stack.push(new UnaryOpValue(_stack.pop(), inst->_codeGenData, inst->_type == kUnaryOpPostInstType));
break;
case kBinaryOpInstType:
{
- EntryPtr op1 = _stack.pop();
- EntryPtr op2 = _stack.pop();
+ ValuePtr op1 = _stack.pop();
+ ValuePtr op2 = _stack.pop();
if (_binOrder == kFIFOArgOrder)
- _stack.push(new BinaryOpEntry(op2, op1, inst->_codeGenData));
+ _stack.push(new BinaryOpValue(op2, op1, inst->_codeGenData));
else if (_binOrder == kLIFOArgOrder)
- _stack.push(new BinaryOpEntry(op1, op2, inst->_codeGenData));
+ _stack.push(new BinaryOpValue(op1, op2, inst->_codeGenData));
break;
}
case kCondJumpInstType:
@@ -300,11 +217,11 @@
s << "} else ";
}
}
- s << "if (" << _stack.pop() << ") {";
+ s << "if (" << _stack.pop()->negate() << ") {";
addOutputLine(s.str(), _curGroup->_coalescedElse, true);
break;
case kWhileCondGroupType:
- s << "while (" << _stack.pop() << ") {";
+ s << "while (" << _stack.pop()->negate() << ") {";
addOutputLine(s.str(), false, true);
break;
case kDoWhileCondGroupType:
@@ -370,7 +287,7 @@
std::string metadata = (!returnsValue ? inst->_codeGenData : inst->_codeGenData.substr(1));
for (size_t i = 0; i < metadata.length(); i++)
processSpecialMetadata(inst, metadata[i], i);
- _stack.push(new CallEntry(inst->_name, _argList));
+ _stack.push(new CallValue(inst->_name, _argList));
if (!returnsValue) {
std::stringstream stream;
stream << _stack.pop() << ";";
@@ -388,7 +305,7 @@
}
}
-void CodeGenerator::addArg(EntryPtr p) {
+void CodeGenerator::addArg(ValuePtr p) {
if (_callOrder == kFIFOArgOrder)
_argList.push_front(p);
else if (_callOrder == kLIFOArgOrder)
Modified: tools/branches/gsoc2010-decompiler/decompiler/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/codegen.h 2010-12-12 22:20:18 UTC (rev 54890)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.h 2010-12-12 22:50:15 UTC (rev 54891)
@@ -21,8 +21,8 @@
*/
#include "graph.h"
-#include "refcounted.h"
#include "stack.h"
+#include "value.h"
#include <ostream>
#include <utility>
@@ -37,282 +37,9 @@
class Function;
/**
- * Types of stack entries.
- */
-enum StackEntryType {
- kIntStackEntry, ///< Integer
- kVarStackEntry, ///< Variable
- kBinOpStackEntry, ///< Binary operation
- kUnaryOpStackEntry, ///< Unary operation
- kDupStackEntry, ///< Duplicated entry
- kArrayStackEntry, ///< Array access
- kStringStackEntry, ///< String
- kListStackEntry, ///< List
- kCallStackEntry ///< Function call
-};
-
-class StackEntry;
-
-/**
- * Pointer to a Group.
- */
-typedef boost::intrusive_ptr<StackEntry> EntryPtr;
-
-/**
- * Base class for stack entries.
- */
-class StackEntry : public RefCounted {
-public:
- const StackEntryType _type; ///< Type of the stack entry.
-
- /**
- * Constructor for StackEntry.
- *
- * @param type The StackEntryType of the StackEntry.
- */
- StackEntry(StackEntryType type) : _type(type) { }
-
- virtual ~StackEntry() { }
-
- /**
- * Print the stack entry to an std::ostream.
- *
- * @param output The std::ostream to write to.
- * @return The std::ostream used for output.
- */
- virtual std::ostream &print(std::ostream &output) const = 0;
-
- /**
- * Duplicates a stack entry.
- *
- * @param output The std::ostream to output to.
- * @return A StackEntry corresponding to a duplicate of this entry.
- */
- virtual EntryPtr dup(std::ostream &output);
-
- /**
- * Output a stack entry to an std::ostream.
- *
- * @param output The std::ostream to output to.
- * @param entry Reference counted pointer to the StackEntry to output.
- * @return The std::ostream used for output.
- */
- friend std::ostream &operator<<(std::ostream &output, EntryPtr entry) {
- return entry->print(output);
- }
-};
-
-/**
- * Stack entry containing an integer.
- */
-class IntEntry : public StackEntry {
-private:
- const int32 _val; ///< The value of the integer.
- const bool _isSigned; ///< True if the value is signed, false if it's not.
-
-public:
- /**
- * Constructor for IntEntry.
- *
- * @param val The value contained in the stack entry.
- * @param isSigned Whether or not the value is signed. This will affect output.
- */
- IntEntry(int32 val, bool isSigned) : StackEntry(kIntStackEntry), _val(val), _isSigned(isSigned) { }
-
- /**
- * Constructor for IntEntry.
- *
- * @param val The value contained in the stack entry.
- * @param isSigned Whether or not the value is signed. This will affect output.
- */
- IntEntry(uint32 val, bool isSigned) : StackEntry(kIntStackEntry), _val(val), _isSigned(isSigned) { }
-
- /**
- * Gets the value associated with the IntEntry.
- *
- * @return The value associated with the IntEntry.
- */
- int32 getValue();
-
- /**
- * Returns whether or not the integer is signed.
- *
- * @return True if the value is signed, false if it's not.
- */
- bool getSigned();
-
- virtual std::ostream &print(std::ostream &output) const;
-
- virtual EntryPtr dup(std::ostream &output);
-};
-
-/**
- * Stack entry containing a variable.
- */
-class VarEntry : public StackEntry {
-private:
- const std::string _varName; ///< The name of the variable.
-
-public:
- /**
- * Constructor for VarEntry.
- *
- * @param varName The name of the variable.
- */
- VarEntry(std::string varName) : StackEntry(kVarStackEntry), _varName(varName) { }
-
- virtual std::ostream &print(std::ostream &output) const;
-};
-
-/**
- * Stack entry containing a binary operation performed on two stack entries.
- */
-class BinaryOpEntry : public StackEntry {
-private:
- const EntryPtr _lhs; ///< Stack entry representing the left side of the operator.
- const EntryPtr _rhs; ///< Stack entry representing the right side of the operator.
- const std::string _op; ///< The operator for this entry.
-
-public:
- /**
- * Constructor for BinaryOpEntry.
- *
- * @param lhs Stack entry representing the left side of the operator.
- * @param rhs Stack entry representing the right side of the operator.
- * @param op The operator for this entry.
- */
- BinaryOpEntry(EntryPtr lhs, EntryPtr rhs, std::string op) :
- StackEntry(kBinOpStackEntry), _lhs(lhs), _rhs(rhs), _op(op) { }
-
- virtual std::ostream &print(std::ostream &output) const;
-};
-
-/**
- * Stack entry containing a unary operation performed on a single stack entry.
- */
-class UnaryOpEntry : public StackEntry {
-private:
- const EntryPtr _operand; ///< The operand the operation is performed on.
- const std::string _op; ///< The operator for this entry.
- const bool _isPostfix; ///< Whether or not the operator should be postfixed to the operand.
-
-public:
- /**
- * Constructor for UnaryOpEntry.
- *
- * @param operand Stack entry representing the operand of the operation.
- * @param op The operator for this entry.
- * @param isPostfix Whether or not the operator should be postfixed to the operand.
- */
- UnaryOpEntry(EntryPtr operand, std::string op, bool isPostfix) :
- StackEntry(kUnaryOpStackEntry), _operand(operand), _op(op), _isPostfix(isPostfix) { }
-
- virtual std::ostream &print(std::ostream &output) const;
-};
-
-/**
- * Duplicated stack entry.
- */
-class DupEntry : public StackEntry {
-private:
- const int _idx; ///< Index to distinguish multiple duplicated entries.
-
-public:
- /**
- * Constructor for DupEntry.
- *
- * @param idx Index to distinguish multiple duplicated entries.
- */
- DupEntry(int idx) : StackEntry(kDupStackEntry), _idx(idx) { }
-
- virtual std::ostream &print(std::ostream &output) const;
-};
-
-/**
- * Type representing index list for an array.
- */
-typedef std::deque<EntryPtr> EntryList;
-
-/**
- * Stack entry representing array access.
- */
-class ArrayEntry : public StackEntry {
-private:
- const std::string _arrayName; ///< The name of the array.
- const EntryList _idxs; ///< std::deque of stack entries representing the indexes used (left-to-right).
-
-public:
- /**
- * Constructor for ArrayEntry.
- *
- * @param arrayName The name of the array.
- * @param idxs std::deque of stack entries representing the indexes used (left-to-right).
- */
- ArrayEntry(std::string arrayName, std::deque<EntryPtr> idxs) : StackEntry(kArrayStackEntry), _arrayName(arrayName), _idxs(idxs) { }
-
- virtual std::ostream &print(std::ostream &output) const;
-};
-
-/**
- * Entry containing a string.
- */
-class StringEntry : public StackEntry {
-private:
- const std::string _str; ///< The string in the entry.
-
-public:
- /**
- * Constructor for StringEntry.
- *
- * @param str The string in the entry.
- */
- StringEntry(std::string str) : StackEntry(kStringStackEntry), _str(str) { }
-
- virtual std::ostream &print(std::ostream &output) const;
-};
-
-/**
- * Entry representing a list.
- */
-class ListEntry : public StackEntry {
-private:
- const EntryList _items; ///< Vector containing the list items.
-
-public:
- /**
- * Constructor for ListEntry.
- *
- * @param items The items stored in the list.
- */
- ListEntry(EntryList items) : StackEntry(kListStackEntry), _items(items) { }
-
- virtual std::ostream &print(std::ostream &output) const;
-};
-
-/**
- * Stack entry representing a function call.
- */
-class CallEntry : public StackEntry {
-private:
- const std::string _funcName; ///< The name of the function.
- const EntryList _args; ///< std::deque of stack entries representing the arguments used (stored left-to-right).
-
-public:
- /**
- * Constructor for CallEntry.
- *
- * @param funcName The name of the function.
- * @param args std::deque of stack entries representing the arguments used.
- */
- CallEntry(std::string funcName, EntryList args) : StackEntry(kCallStackEntry), _funcName(funcName), _args(args) { }
-
- virtual std::ostream &print(std::ostream &output) const;
-};
-
-/**
* Type representing a stack.
*/
-typedef Stack<EntryPtr> EntryStack;
+typedef Stack<ValuePtr> ValueStack;
const int kIndentAmount = 2; ///< How many spaces to use for each indent.
@@ -343,11 +70,11 @@
protected:
Engine *_engine; ///< Pointer to the Engine used for the script.
std::ostream &_output; ///< The std::ostream to output the code to.
- EntryStack _stack; ///< The stack currently being processed.
+ ValueStack _stack; ///< The stack currently being processed.
uint _indentLevel; ///< Indentation level.
GraphVertex _curVertex; ///< Graph vertex currently being processed.
GroupPtr _curGroup; ///< Pointer to the group currently being processed.
- EntryList _argList; ///< Storage for lists of arguments to be built when processing function calls.
+ ValueList _argList; ///< Storage for lists of arguments to be built when processing function calls.
/**
* Processes an instruction. Called by process() for each instruction.
@@ -381,7 +108,7 @@
* @param dst The variable being assigned to.
* @param src The value being assigned.
*/
- void writeAssignment(EntryPtr dst, EntryPtr src);
+ void writeAssignment(ValuePtr dst, ValuePtr src);
/**
* Process a single character of metadata.
@@ -397,7 +124,7 @@
*
* @param p The argument to add.
*/
- void addArg(EntryPtr p);
+ void addArg(ValuePtr p);
/**
* Construct the signature for a function.
Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp 2010-12-12 22:20:18 UTC (rev 54890)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp 2010-12-12 22:50:15 UTC (rev 54891)
@@ -42,31 +42,31 @@
case 2:
// If something has been called previously in this group, don't output retval variable
if (inst->_address <= findFirstCall()->_address)
- _stack.push(new VarEntry("retval"));
+ _stack.push(new VarValue("retval"));
break;
case 3:
case 4:
- _stack.push(new IntEntry(inst->_params[0].getSigned(), true));
+ _stack.push(new IntValue(inst->_params[0].getSigned(), true));
break;
case 5:
{
std::stringstream s;
s << boost::format("var%d") % inst->_params[0].getSigned();
- _stack.push(new VarEntry(s.str()));
+ _stack.push(new VarValue(s.str()));
}
break;
case 6:
{
std::stringstream s;
s << boost::format("localvar%d") % inst->_params[0].getSigned();
- _stack.push(new VarEntry(s.str()));
+ _stack.push(new VarValue(s.str()));
}
break;
case 7:
{
std::stringstream s;
s << boost::format("param%d") % inst->_params[0].getSigned();
- _stack.push(new VarEntry(s.str()));
+ _stack.push(new VarValue(s.str()));
}
break;
}
@@ -75,7 +75,7 @@
switch (inst->_opcode) {
case 8:
{
- EntryPtr p = new VarEntry("retval");
+ ValuePtr p = new VarValue("retval");
writeAssignment(p, _stack.pop());
}
break;
@@ -83,7 +83,7 @@
{
std::stringstream s;
s << boost::format("var%d") % inst->_params[0].getSigned();
- EntryPtr p = new VarEntry(s.str());
+ ValuePtr p = new VarValue(s.str());
writeAssignment(p, _stack.pop());
}
break;
@@ -91,7 +91,7 @@
{
std::stringstream s;
s << boost::format("localvar%d") % inst->_params[0].getSigned();
- EntryPtr p = new VarEntry(s.str());
+ ValuePtr p = new VarValue(s.str());
writeAssignment(p, _stack.pop());
}
break;
@@ -99,7 +99,7 @@
{
std::stringstream s;
s << boost::format("param%d") % inst->_params[0].getSigned();
- EntryPtr p = new VarEntry(s.str());
+ ValuePtr p = new VarValue(s.str());
writeAssignment(p, _stack.pop());
}
break;
@@ -115,26 +115,12 @@
for (int i = 0; i != inst->_params[0].getSigned(); ++i) {
std::stringstream s;
s << boost::format("localvar%d") % i;
- _stack.push(new VarEntry(s.str()));
+ _stack.push(new VarValue(s.str()));
}
}
break;
case kCondJumpInstType:
- switch (_curGroup->_type) {
- case kIfCondGroupType:
- case kWhileCondGroupType:
- break;
- case kDoWhileCondGroupType:
- _stack.push(new UnaryOpEntry(_stack.pop(), "!", false));
- break;
- default:
- {
- std::stringstream s;
- s << boost::format("WARNING: Couldn't handle conditional jump at address %08X") % inst->_address;
- addOutputLine(s.str());
- }
- return;
- }
+ _stack.push(_stack.pop()->negate());
CodeGenerator::processInst(inst);
break;
case kCallInstType:
@@ -143,7 +129,7 @@
Function f = _engine->_functions.find(inst->_params[0].getUnsigned())->second;
for (size_t i = 0; i < f._metadata.length(); i++)
processSpecialMetadata(inst, f._metadata[i], i);
- _stack.push(new CallEntry(f._name, _argList));
+ _stack.push(new CallValue(f._name, _argList));
// Leave call on stack if this is a condition, or other calls follow in same group
if (_curGroup->_type == kIfCondGroupType || _curGroup->_type == kWhileCondGroupType || _curGroup->_type == kDoWhileCondGroupType || inst->_address != findLastCall()->_address) {
break;
@@ -152,7 +138,7 @@
stream << _stack.pop() << ";";
addOutputLine(stream.str());
} else {
- EntryPtr p = new VarEntry("retval");
+ ValuePtr p = new VarValue("retval");
writeAssignment(p, _stack.pop());
}
break;
@@ -166,7 +152,7 @@
std::string metadata = (!returnsValue ? inst->_codeGenData : inst->_codeGenData.substr(1));
for (size_t i = 0; i < metadata.length(); i++)
processSpecialMetadata(inst, metadata[i], i);
- _stack.push(new CallEntry(inst->_name, _argList));
+ _stack.push(new CallValue(inst->_name, _argList));
// Leave call on stack if this is a condition, or other calls follow in same group
if (_curGroup->_type == kIfCondGroupType || _curGroup->_type == kWhileCondGroupType || _curGroup->_type == kDoWhileCondGroupType || inst->_address != findLastCall()->_address) {
break;
@@ -175,7 +161,7 @@
stream << _stack.pop() << ";";
addOutputLine(stream.str());
} else {
- EntryPtr p = new VarEntry("retval");
+ ValuePtr p = new VarValue("retval");
writeAssignment(p, _stack.pop());
}
break;
@@ -213,14 +199,13 @@
break;
case 's':
{
- EntryPtr p = _stack.peekPos(pos);
- if (p->_type == kIntStackEntry) {
- IntEntry *ie = (IntEntry *)p.get();
- addArg(new StringEntry(((Kyra::Kyra2Engine *)_engine)->_textStrings[ie->getValue()]));
+ ValuePtr p = _stack.peekPos(pos);
+ if (p->isInteger()) {
+ addArg(new StringValue(((Kyra::Kyra2Engine *)_engine)->_textStrings[p->getUnsigned()]));
} else {
- EntryList idxs;
+ ValueList idxs;
idxs.push_front(p);
- addArg(new ArrayEntry("strings", idxs));
+ addArg(new ArrayValue("strings", idxs));
}
}
break;
Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp 2010-12-12 22:20:18 UTC (rev 54890)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp 2010-12-12 22:50:15 UTC (rev 54891)
@@ -22,16 +22,27 @@
#include "codegen.h"
-EntryPtr Scumm::v6::Scummv6CodeGenerator::createListEntry() {
- EntryList list;
- EntryPtr countEntry = _stack.pop();
+std::ostream &Scumm::v6::ListValue::print(std::ostream &output) const {
+ output << "[";
+ for (ValueList::const_iterator i = _items.begin(); i != _items.end(); ++i) {
+ if (i != _items.begin())
+ output << ", ";
+ output << *i;
+ }
+ output << "]";
+ return output;
+}
+
+ValuePtr Scumm::v6::Scummv6CodeGenerator::createListValue() {
+ ValueList list;
+ ValuePtr countValue = _stack.pop();
std::stringstream s;
- s << countEntry;
+ s << countValue;
int count = atoi(s.str().c_str());
for (int i = 0; i < count; i++) {
list.push_front(_stack.pop());
}
- return new ListEntry(list);
+ return new ListValue(list);
}
void Scumm::v6::Scummv6CodeGenerator::processInst(const InstPtr inst) {
@@ -43,30 +54,30 @@
case kLoadInstType:
switch (inst->_opcode) {
case 0x00: // pushByte
- _stack.push(new IntEntry(inst->_params[0].getUnsigned(), false));
+ _stack.push(new IntValue(inst->_params[0].getUnsigned(), false));
break;
case 0x01: // pushWord
- _stack.push(new IntEntry(inst->_params[0].getSigned(), true));
+ _stack.push(new IntValue(inst->_params[0].getSigned(), true));
break;
case 0x02: // pushByteVar
case 0x03: // pushWordVar
- _stack.push(new VarEntry(decodeVarName(inst->_params[0].getUnsigned())));
+ _stack.push(new VarValue(decodeVarName(inst->_params[0].getUnsigned())));
break;
case 0x06: // byteArrayRead
case 0x07: // wordArrayRead
{
- EntryList idxs;
+ ValueList idxs;
idxs.push_front(_stack.pop());
- _stack.push(new ArrayEntry(decodeArrayName(inst->_params[0].getUnsigned()), idxs));
+ _stack.push(new ArrayValue(decodeArrayName(inst->_params[0].getUnsigned()), idxs));
break;
}
case 0x0A: // byteArrayIndexedRead
case 0x0B: // wordArrayIndexedRead
{
- EntryList idxs;
+ ValueList idxs;
idxs.push_front(_stack.pop());
idxs.push_front(_stack.pop());
- _stack.push(new ArrayEntry(decodeArrayName(inst->_params[0].getUnsigned()), idxs));
+ _stack.push(new ArrayValue(decodeArrayName(inst->_params[0].getUnsigned()), idxs));
break;
}
}
@@ -76,28 +87,28 @@
case 0x42: // writeByteVar
case 0x43: // writeWordVar
{
- EntryPtr p = new VarEntry(decodeVarName(inst->_params[0].getUnsigned()));
+ ValuePtr p = new VarValue(decodeVarName(inst->_params[0].getUnsigned()));
writeAssignment(p, _stack.pop());
}
break;
case 0x46: // byteArrayWrite
case 0x47: // wordArrayWrite
{
- EntryPtr value = _stack.pop();
- EntryList idxs;
+ ValuePtr value = _stack.pop();
+ ValueList idxs;
idxs.push_back(_stack.pop());
- EntryPtr p = new ArrayEntry(decodeArrayName(inst->_params[0].getUnsigned()), idxs);
+ ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0].getUnsigned()), idxs);
writeAssignment(p, value);
}
break;
case 0x4A: // byteArrayIndexedWrite
case 0x4B: // wordArrayIndexedWrite
{
- EntryPtr value = _stack.pop();
- EntryList idxs;
+ ValuePtr value = _stack.pop();
+ ValueList idxs;
idxs.push_front(_stack.pop());
idxs.push_front(_stack.pop());
- EntryPtr p = new ArrayEntry(decodeArrayName(inst->_params[0].getUnsigned()), idxs);
+ ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0].getUnsigned()), idxs);
writeAssignment(p, value);
}
break;
@@ -116,24 +127,8 @@
//addOutputLine("// pop();");
break;
case kCondJumpRelInstType:
- switch (_curGroup->_type) {
- case kIfCondGroupType:
- case kWhileCondGroupType:
- if (inst->_opcode == 0x5C) // jumpTrue
- _stack.push(new UnaryOpEntry(_stack.pop(), "!", false));
- break;
- case kDoWhileCondGroupType:
- if (inst->_opcode == 0x5D) // jumpFalse
- _stack.push(new UnaryOpEntry(_stack.pop(), "!", false));
- break;
- default:
- {
- std::stringstream s;
- s << boost::format("WARNING: Couldn't handle conditional jump at address %08X") % inst->_address;
- addOutputLine(s.str());
- }
- return;
- }
+ if (inst->_opcode == 0x5D) // jumpFalse
+ _stack.push(_stack.pop()->negate());
CodeGenerator::processInst(inst);
break;
case kUnaryOpPostInstType:
@@ -144,7 +139,7 @@
case 0x57: // wordVarDec
{
std::stringstream s;
- EntryPtr p = new UnaryOpEntry(new VarEntry(decodeVarName(inst->_params[0].getUnsigned())), inst->_codeGenData, true);
+ ValuePtr p = new UnaryOpValue(new VarValue(decodeVarName(inst->_params[0].getUnsigned())), inst->_codeGenData, true);
s << p << ";";
addOutputLine(s.str());
}
@@ -155,9 +150,9 @@
case 0x5B: // wordArrayDec
{
std::stringstream s;
- EntryList idxs;
+ ValueList idxs;
idxs.push_front(_stack.pop());
- EntryPtr p = new UnaryOpEntry(new ArrayEntry(decodeVarName(inst->_params[0].getUnsigned()), idxs), inst->_codeGenData, true);
+ ValuePtr p = new UnaryOpValue(new ArrayValue(decodeVarName(inst->_params[0].getUnsigned()), idxs), inst->_codeGenData, true);
s << p << ";";
addOutputLine(s.str());
}
@@ -171,30 +166,30 @@
switch (inst->_opcode) {
case 0xA4CD: // arrayOp_assignString
{
- EntryPtr value = new StringEntry(inst->_params[1].getString());
- EntryList idxs;
+ ValuePtr value = new StringValue(inst->_params[1].getString());
+ ValueList idxs;
idxs.push_front(_stack.pop());
- EntryPtr p = new ArrayEntry(decodeArrayName(inst->_params[0].getUnsigned()), idxs);
+ ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0].getUnsigned()), idxs);
writeAssignment(p, value);
}
break;
case 0xA4D0: // arrayOp_assignIntList
{
- EntryList idxs;
+ ValueList idxs;
idxs.push_front(_stack.pop());
- EntryPtr value = createListEntry();
- EntryPtr p = new ArrayEntry(decodeArrayName(inst->_params[0].getUnsigned()), idxs);
+ ValuePtr value = createListValue();
+ ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0].getUnsigned()), idxs);
writeAssignment(p, value);
}
break;
case 0xA4D4: // arrayOp_assign2DimList
{
- EntryList idxs;
+ ValueList idxs;
idxs.push_front(_stack.pop());
- EntryPtr value = createListEntry();
+ ValuePtr value = createListValue();
idxs.push_front(_stack.pop());
- EntryPtr p = new ArrayEntry(decodeArrayName(inst->_params[0].getUnsigned()), idxs);
+ ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0].getUnsigned()), idxs);
writeAssignment(p, value);
}
@@ -416,7 +411,7 @@
switch (c) {
// All of these meanings are taken from descumm.
case 'l':
- addArg(createListEntry());
+ addArg(createListValue());
break;
// No SCUMMv6 opcodes using these types have more than one parameter, so it's safe to assume it's the first parameter we want.
case 'w':
@@ -425,11 +420,11 @@
switch (inst->_params[0]._type) {
case kSByteParamType:
case kShortParamType:
- addArg(new IntEntry(inst->_params[0].getSigned(), true));
+ addArg(new IntValue(inst->_params[0].getSigned(), true));
break;
case kByteParamType:
case kUShortParamType:
- addArg(new IntEntry(inst->_params[0].getUnsigned(), false));
+ addArg(new IntValue(inst->_params[0].getUnsigned(), false));
break;
default:
std::cerr << boost::format("WARNING: Unexpected type for parameter 0 @ %08X while processing metadata character %c") % inst->_address % c;
@@ -437,10 +432,10 @@
}
break;
case 'v':
- addArg(new VarEntry(decodeVarName(inst->_params[0].getUnsigned())));
+ addArg(new VarValue(decodeVarName(inst->_params[0].getUnsigned())));
break;
case 's':
- addArg(new StringEntry(inst->_params[0].getString()));
+ addArg(new StringValue(inst->_params[0].getString()));
break;
case 'z':
addArg(_stack.pop());
Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h 2010-12-12 22:20:18 UTC (rev 54890)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h 2010-12-12 22:50:15 UTC (rev 54891)
@@ -29,6 +29,21 @@
namespace v6 {
+class ListValue : public Value {
+protected:
+ const ValueList _items; ///< The list items.
+
+public:
+ /**
+ * Constructor for ListValue.
+ *
+ * @param items The list items, stored left-to-right.
+ */
+ ListValue(ValueList items) : _items(items) { }
+
+ virtual std::ostream &print(std::ostream &output) const;
+};
+
/**
* SCUMMv6 code generator.
*/
@@ -59,11 +74,11 @@
std::string decodeArrayName(uint16 arrID);
/**
- * Creates a ListEntry from the stack.
+ * Creates a ListValue from the stack.
*
- * @return The ListEntry created from the stack.
+ * @return The ListValue created from the stack.
*/
- EntryPtr createListEntry();
+ ValuePtr createListValue();
public:
/**
* Constructor for Scumm::v6::CodeGenerator.
Modified: tools/branches/gsoc2010-decompiler/decompiler/test/module.mk
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/test/module.mk 2010-12-12 22:20:18 UTC (rev 54890)
+++ tools/branches/gsoc2010-decompiler/decompiler/test/module.mk 2010-12-12 22:50:15 UTC (rev 54891)
@@ -13,6 +13,7 @@
decompiler/disassembler.o \
decompiler/engine.o \
decompiler/simple_disassembler.o \
+ decompiler/value.o \
decompiler/scummv6/disassembler.o \
decompiler/scummv6/codegen.o \
decompiler/scummv6/engine.o \
Added: tools/branches/gsoc2010-decompiler/decompiler/value.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/value.cpp (rev 0)
+++ tools/branches/gsoc2010-decompiler/decompiler/value.cpp 2010-12-12 22:50:15 UTC (rev 54891)
@@ -0,0 +1,168 @@
+/* ScummVM Tools
+ * Copyright (C) 2010 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "value.h"
+
+#include <boost/format.hpp>
+
+static int dupindex = 0;
+
+bool Value::isInteger() {
+ return false;
+}
+
+bool Value::isAddress() {
+ return false;
+}
+
+bool Value::isSignedValue() throw(WrongTypeException) {
+ throw WrongTypeException();
+}
+
+int32 Value::getSigned() throw(WrongTypeException) {
+ throw WrongTypeException();
+}
+
+uint32 Value::getUnsigned() throw(WrongTypeException) {
+ throw WrongTypeException();
+}
+
+ValuePtr Value::dup(std::ostream &output) {
+ ValuePtr dupValue = new DupValue(++dupindex);
+ output << dupValue << " = " << this << ";";
+ return dupValue;
+}
+
+ValuePtr Value::negate() throw(WrongTypeException) {
+ return new NegatedValue(this);
+}
+
+bool IntValue::isInteger() {
+ return true;
+}
+
+bool IntValue::isSignedValue() throw(WrongTypeException) {
+ return _isSigned;
+}
+
+int32 IntValue::getSigned() throw(WrongTypeException) {
+ return _val;
+}
+
+uint32 IntValue::getUnsigned() throw(WrongTypeException) {
+ return (uint32)_val;
+}
+
+ValuePtr IntValue::dup(std::ostream &output) {
+ return new IntValue(_val, _isSigned);
+}
+
+std::ostream &IntValue::print(std::ostream &output) const {
+ if (_isSigned)
+ output << (int32)_val;
+ else
+ output << (uint32)_val;
+ return output;
+}
+
+bool AddressValue::isAddress() {
+ return true;
+}
+
+int32 AddressValue::getSigned() throw(WrongTypeException) {
+ throw WrongTypeException();
+}
+
+ValuePtr AddressValue::dup(std::ostream &output) {
+ return new AddressValue(_val);
+}
+
+std::ostream &AddressValue::print(std::ostream &output) const {
+ return output << boost::format("0x%x") % _val;
+}
+
+bool RelAddressValue::isAddress() {
+ return true;
+}
+
+uint32 RelAddressValue::getUnsigned() throw(WrongTypeException) {
+ return _baseaddr + _val;
+}
+
+ValuePtr RelAddressValue::dup(std::ostream &output) {
+ return new RelAddressValue(_baseaddr, _val);
+}
+
+std::ostream &RelAddressValue::print(std::ostream &output) const {
+ if (_val < 0)
+ return output << boost::format("-0x%x") % -_val;
+ return output << boost::format("+0x%x") % _val;
+}
+
+ValuePtr DupValue::dup(std::ostream &output) {
+ return this;
+}
+
+std::ostream &DupValue::print(std::ostream &output) const {
+ return output << "temp" << _idx;
+}
+
+std::ostream &StringValue::print(std::ostream &output) const {
+ return output << "\"" << _str << "\"";
+}
+
+std::ostream &VarValue::print(std::ostream &output) const {
+ return output << _varName;
+}
+
+std::ostream &ArrayValue::print(std::ostream &output) const {
+ output << _varName;
+ for (ValueList::const_iterator i = _idxs.begin(); i != _idxs.end(); ++i)
+ output << "[" << *i << "]";
+ return output;
+}
+
+std::ostream &BinaryOpValue::print(std::ostream &output) const {
+ return output << "(" << _lhs << " " << _op << " " << _rhs << ")";
+}
+
+std::ostream &UnaryOpValue::print(std::ostream &output) const {
+ if (_isPostfix)
+ return output << "(" << _operand << ")" << _op;
+ else
+ return output << _op << "(" << _operand << ")";
+}
+
+ValuePtr NegatedValue::negate() throw(WrongTypeException) {
+ return _operand;
+}
+
+std::ostream &CallValue::print(std::ostream &output) const {
+ output << _funcName << "(";
+ for (ValueList::const_iterator i = _args.begin(); i != _args.end(); ++i) {
+ if (i != _args.begin())
+ output << ", ";
+ output << *i;
+ }
+ output << ")";
+ return output;
+}
Property changes on: tools/branches/gsoc2010-decompiler/decompiler/value.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: tools/branches/gsoc2010-decompiler/decompiler/value.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/value.h (rev 0)
+++ tools/branches/gsoc2010-decompiler/decompiler/value.h 2010-12-12 22:50:15 UTC (rev 54891)
@@ -0,0 +1,355 @@
+/* ScummVM Tools
+ * Copyright (C) 2010 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef VALUE_H
+#define VALUE_H
+
+#include <deque>
+#include <exception>
+#include <ostream>
+#include <string>
+#include <boost/intrusive_ptr.hpp>
+
+#include "common/scummsys.h"
+#include "refcounted.h"
+
+/**
+ * Exception signalling that an operation was performed on a Value that doesn't support the operation.
+ */
+class WrongTypeException : public std::exception {
+};
+
+class Value;
+
+/**
+ * Pointer to a Value.
+ */
+typedef boost::intrusive_ptr<Value> ValuePtr;
+
+/**
+ * Type representing a list of values, e.g. for indexes used to access an array.
+ */
+typedef std::deque<ValuePtr> ValueList;
+
+/**
+ * Class representing a value (stack entry, parameter, etc.)
+ */
+class Value : public RefCounted {
+ public:
+ virtual ~Value() { }
+
+ /**
+ * Return whether or not the Value is an integer.
+ *
+ * @return True if the Value is an integer, otherwise false.
+ */
+ virtual bool isInteger();
+
+ /**
+ * Return whether or not the Value is an address.
+ *
+ * @return True if the Value is an address, otherwise false.
+ */
+ virtual bool isAddress();
+
+ /**
+ * Returns whether or not any stored integer value is signed.
+ *
+ * @return True if the integer value is signed, false if it is not.
+ * @throws WrongTypeException if the value is not an integer.
+ */
+ virtual bool isSignedValue() throw(WrongTypeException);
+
+ /**
+ * Retrieves a signed integer representing the value, if possible.
+ *
+ * @return A signed integer representing the value, if possible.
+ * @throws WrongTypeException if the value is not an integer.
+ */
+ virtual int32 getSigned() throw(WrongTypeException);
+
+ /**
+ * Retrieves an unsigned integer representing the value, if possible.
+ *
+ * @return An unsigned integer representing the value, if possible.
+ * @throws WrongTypeException if the value is not an integer.
+ */
+ virtual uint32 getUnsigned() throw(WrongTypeException);
+
+ /**
+ * Print the stack entry to an std::ostream.
+ *
+ * @param output The std::ostream to write to.
+ * @return The std::ostream used for output.
+ */
+ virtual std::ostream &print(std::ostream &output) const = 0;
+
+ /**
+ * Duplicates a value.
+ *
+ * @param output The std::ostream to output any necessary assignment to.
+ * @return A Value corresponding to a duplicate of this entry.
+ */
+ virtual ValuePtr dup(std::ostream &output);
+
+ /**
+ * Negates a value.
+ *
+ * @return The current Value, only negated.
+ * @throws WrongTypeException if negation is not possible.
+ */
+ virtual ValuePtr negate() throw(WrongTypeException);
+
+ /**
+ * Output a value to an std::ostream.
+ *
+ * @param output The std::ostream to output to.
+ * @param value Reference counted pointer to the value to output.
+ * @return The std::ostream used for output.
+ */
+ friend std::ostream &operator<<(std::ostream &output, ValuePtr value) {
+ return value->print(output);
+ }
+
+};
+
+/**
+ * Value containing an integer.
+ */
+class IntValue : public Value {
+protected:
+ const int32 _val; ///< The value of the integer.
+ const bool _isSigned; ///< True if the value is signed, false if it's not.
+
+public:
+ /**
+ * Constructor for IntValue.
+ *
+ * @param val The integer value to be contained.
+ * @param isSigned Whether or not the value is signed. This will affect output.
+ */
+ IntValue(int32 val, bool isSigned) : _val(val), _isSigned(isSigned) { }
+
+ /**
+ * Constructor for IntValue.
+ *
+ * @param val The integer value to be contained.
+ * @param isSigned Whether or not the value is signed. This will affect output.
+ */
+ IntValue(uint32 val, bool isSigned) : _val(val), _isSigned(isSigned) { }
+
+ bool isInteger();
+ bool isSignedValue() throw(WrongTypeException);
+ int32 getSigned() throw(WrongTypeException);
+ uint32 getUnsigned() throw(WrongTypeException);
+
+ ValuePtr dup(std::ostream &output);
+
+ virtual std::ostream &print(std::ostream &output) const;
+};
+
+/**
+ * Value containing an absolute address.
+ */
+class AddressValue : public IntValue {
+protected:
+ /**
+ * Constructor for AddressValue.
+ */
+ AddressValue(uint32 addr) : IntValue(addr, false) { }
+
+ bool isAddress();
+ int32 getSigned() throw(WrongTypeException);
+
+ ValuePtr dup(std::ostream &output);
+
+ virtual std::ostream &print(std::ostream &output) const;
+};
+
+/**
+ * Value containing a signed, relative address. When asking for unsigned integer value, exact address is returned; when printing or getting signed value, relative address is used.
+ */
+class RelAddressValue : public IntValue {
+protected:
+ const uint32 _baseaddr; ///< The base address for the offset.
+
+public:
+ RelAddressValue(uint32 baseaddr, int32 offset) : IntValue(offset, true), _baseaddr(baseaddr) { };
+
+ bool isAddress();
+ uint32 getUnsigned() throw(WrongTypeException);
+
+ ValuePtr dup(std::ostream &output);
+
+ virtual std::ostream &print(std::ostream &output) const;
+};
+
+/**
+ * Duplicated value.
+ */
+class DupValue : public Value {
+protected:
+ const int _idx; ///< Index to distinguish multiple duplicated entries.
+
+public:
+ /**
+ * Constructor for DupEntry.
+ *
+ * @param idx Index to distinguish multiple duplicated entries.
+ */
+ DupValue(int idx) : _idx(idx) { }
+
+ ValuePtr dup(std::ostream &output);
+
+ virtual std::ostream &print(std::ostream &output) const;
+};
+
+/**
+ * String value.
+ */
+class StringValue : public Value {
+protected:
+ const std::string _str; ///< The string value.
+
+public:
+ /**
+ * Constructor for StringValue.
+ *
+ * @param str The string value.
+ */
+ StringValue(std::string str) : _str(str) { }
+
+ virtual std::ostream &print(std::ostream &output) const;
+};
+
+/**
+ * Value representing a variable.
+ */
+class VarValue : public Value {
+protected:
+ const std::string _varName; ///< The variable name.
+
+public:
+ /**
+ * Constructor for VarValue.
+ *
+ * @param varName The variable name.
+ */
+ VarValue(std::string varName) : _varName(varName) { }
+
+ virtual std::ostream &print(std::ostream &output) const;
+};
+
+/**
+ * Value representing array access.
+ */
+class ArrayValue : public VarValue {
+protected:
+ const ValueList _idxs; ///< std::deque of values representing the indexes used (left-to-right).
+
+public:
+ /**
+ * Constructor for ArrayValue.
+ *
+ * @param arrayName The name of the array.
+ * @param idxs std::deque of stack entries representing the indexes used (left-to-right).
+ */
+ ArrayValue(std::string arrayName, ValueList idxs) : VarValue(arrayName), _idxs(idxs) { }
+
+ virtual std::ostream &print(std::ostream &output) const;
+};
+
+/**
+ * Value representing the result of a binary operation.
+ */
+class BinaryOpValue : public Value {
+protected:
+ const ValuePtr _lhs; ///< Value representing the left side of the operator.
+ const ValuePtr _rhs; ///< Value representing the right side of the operator.
+ const std::string _op; ///< The operator for this value.
+
+public:
+ /**
+ * Constructor for BinaryOpValue.
+ *
+ * @param lhs Value representing the left side of the operator.
+ * @param rhs Value representing the right side of the operator.
+ * @param op The operator for this value.
+ */
+ BinaryOpValue(ValuePtr lhs, ValuePtr rhs, std::string op) : _lhs(lhs), _rhs(rhs), _op(op) { }
+
+ virtual std::ostream &print(std::ostream &output) const;
+};
+
+/**
+ * Value representing the result of a unary operation.
+ * Used as base class for prefix and postfix variants.
+ */
+class UnaryOpValue : public Value {
+protected:
+ const ValuePtr _operand; ///< Value representing the operand of the operation.
+ const std::string _op; ///< The operator for this value.
+ const bool _isPostfix; ///< Whether or not the operator should be postfixed to the operand.
+
+public:
+ /**
+ * Constructor for UnaryOpValue.
+ *
+ * @param operand Value representing the operand of the operation.
+ * @param op The operator for this value.
+ */
+ UnaryOpValue(ValuePtr operand, std::string op, bool isPostfix) :
+ _operand(operand), _op(op), _isPostfix(isPostfix) { }
+
+ virtual std::ostream &print(std::ostream &output) const;
+};
+
+/**
+ * Negated value.
+ */
+class NegatedValue : public UnaryOpValue {
+public:
+ NegatedValue(ValuePtr val) : UnaryOpValue(val, "!", false) { }
+ virtual ValuePtr negate() throw(WrongTypeException);
+};
+
+/**
+ * Value representing a function call.
+ */
+class CallValue : public Value {
+protected:
+ const std::string _funcName; ///< The name of the function.
+ const ValueList _args; ///< std::deque of values representing the arguments used (stored left-to-right).
+
+public:
+ /**
+ * Constructor for CallValue.
+ *
+ * @param funcName The name of the function.
+ * @param args std::deque of values representing the arguments used.
+ */
+ CallValue(std::string funcName, ValueList args) : _funcName(funcName), _args(args) { }
+
+ virtual std::ostream &print(std::ostream &output) const;
+};
+
+#endif
Property changes on: tools/branches/gsoc2010-decompiler/decompiler/value.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
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