[Scummvm-cvs-logs] SF.net SVN: scummvm:[51189] tools/branches/gsoc2010-decompiler/decompiler
pidgeot at users.sourceforge.net
pidgeot at users.sourceforge.net
Fri Jul 23 03:38:35 CEST 2010
Revision: 51189
http://scummvm.svn.sourceforge.net/scummvm/?rev=51189&view=rev
Author: pidgeot
Date: 2010-07-23 01:38:34 +0000 (Fri, 23 Jul 2010)
Log Message:
-----------
Add handling of kSpecial metadata for SCUMMv6
Modified Paths:
--------------
tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp
tools/branches/gsoc2010-decompiler/decompiler/codegen.h
tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp
tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h
Modified: tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp 2010-07-23 01:05:26 UTC (rev 51188)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp 2010-07-23 01:38:34 UTC (rev 51189)
@@ -38,7 +38,7 @@
return this;
EntryPtr dupEntry = new DupEntry(++dupindex);
- output << dupEntry << " = " << (EntryPtr)this;
+ output << dupEntry << " = " << (EntryPtr)this << ";";
return dupEntry;
}
@@ -222,11 +222,17 @@
break;
case kSpecial:
{
- std::stringstream s;
- s << it->_name << "(";
- // TODO: Process metadata
- s << ")";
- addOutputLine(s.str());
+ _argList.clear();
+ bool returnsValue = (it->_codeGenData.find("r") == 0);
+ std::string metadata = (!returnsValue ? it->_codeGenData : it->_codeGenData.substr(1) );
+ for (size_t i = 0; i < metadata.length(); i++)
+ processSpecialMetadata(*it, metadata[i]);
+ _stack.push(new CallEntry(it->_name, _argList));
+ if (!returnsValue) {
+ std::stringstream stream;
+ stream << _stack.pop() << ";";
+ addOutputLine(stream.str());
+ }
break;
}
default:
@@ -240,3 +246,15 @@
if (_curGroup->_endElse != NULL)
addOutputLine("}");
}
+
+void CodeGenerator::processSpecialMetadata(const Instruction inst, char c) {
+ // TODO: Allow subclasses to decide if they want push_front or push_back.
+ switch (c) {
+ case 'p':
+ _argList.push_front(_stack.pop());
+ break;
+ default:
+ std::cerr << boost::format("Unknown character in metadata: %c\n") % c ;
+ break;
+ }
+}
Modified: tools/branches/gsoc2010-decompiler/decompiler/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/codegen.h 2010-07-23 01:05:26 UTC (rev 51188)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.h 2010-07-23 01:38:34 UTC (rev 51189)
@@ -43,6 +43,7 @@
const StackEntryType seArray = 5;
const StackEntryType seString = 6;
const StackEntryType seList = 7;
+const StackEntryType seCall = 8;
class StackEntry;
@@ -66,7 +67,7 @@
friend void ::boost::intrusive_ptr_release(StackEntry *p); ///< Allow access by reference counting methods in boost namespace.
public:
- const StackEntryType _type;
+ const StackEntryType _type; ///< Type of the stack entry.
/**
* Constructor for StackEntry.
@@ -264,7 +265,7 @@
class ArrayEntry : public StackEntry {
private:
const std::string _arrayName; ///< The name of the array.
- EntryList _idxs; ///< std::deque of stack entries representing the indexes used (left-to-right).
+ const EntryList _idxs; ///< std::deque of stack entries representing the indexes used (left-to-right).
public:
/**
@@ -291,6 +292,11 @@
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(seString), _str(str) { }
virtual std::ostream &print(std::ostream &output) const {
@@ -306,6 +312,11 @@
const EntryList _items; ///< Vector containing the list items.
public:
+ /**
+ * Constructor for ListEntry.
+ *
+ * @param items The items stored in the list.
+ */
ListEntry(EntryList items) : StackEntry(seList), _items(items) { }
virtual std::ostream &print(std::ostream &output) const {
@@ -321,6 +332,35 @@
};
/**
+ * 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(seCall), _funcName(funcName), _args(args) { }
+
+ virtual std::ostream &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;
+ }
+};
+
+/**
* Type representing a stack.
*/
typedef Stack<EntryPtr> EntryStack;
@@ -347,6 +387,7 @@
EntryStack _stack; ///< The stack currently being processed.
uint _indentLevel; ///< Indentation level.
GroupPtr _curGroup; ///< Pointer to the group currently being processed.
+ EntryList _argList; ///< Storage for lists of arguments to be built when processing function calls.
/**
* Processes an instruction.
@@ -378,6 +419,14 @@
*/
void writeAssignment(EntryPtr dst, EntryPtr src);
+ /**
+ * Process a single character of metadata.
+ *
+ * @param it The instruction being processed.
+ * @param c The character signifying the action to be taken.
+ */
+ virtual void processSpecialMetadata(const Instruction inst, char c);
+
public:
virtual ~CodeGenerator() {};
Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp 2010-07-23 01:05:26 UTC (rev 51188)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp 2010-07-23 01:38:34 UTC (rev 51189)
@@ -424,3 +424,43 @@
s << boost::format("array%d") % arrID;
return s.str();
}
+
+void Scumm::v6::CodeGenerator::processSpecialMetadata(const Instruction inst, char c) {
+ switch (c) {
+ // All of these meanings are taken from descumm.
+ case 'l':
+ _argList.push_front(createListEntry());
+ 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':
+ case 'j':
+ case 'i':
+ switch (inst._params[0]._type) {
+ case kSByte:
+ case kShort:
+ _argList.push_front(new IntEntry(inst._params[0].getSigned(), false));
+ break;
+ case kByte:
+ case kUShort:
+ _argList.push_front(new IntEntry(inst._params[0].getUnsigned(), false));
+ break;
+ default:
+ std::cerr << boost::format("Unexpected type for parameter 0 @ %08X while processing metadata character %c") % inst._address % c;
+ break;
+ }
+ break;
+ case 'v':
+ _argList.push_front(new VarEntry(decodeVarName(inst._params[0].getUnsigned())));
+ break;
+ case 's':
+ _argList.push_front(new StringEntry(inst._params[0].getString()));
+ break;
+ case 'z':
+ _argList.push_front(_stack.pop());
+ _argList.push_front(_stack.pop());
+ break;
+ default:
+ ::CodeGenerator::processSpecialMetadata(inst, c);
+ break;
+ }
+}
Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h 2010-07-23 01:05:26 UTC (rev 51188)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h 2010-07-23 01:38:34 UTC (rev 51189)
@@ -65,9 +65,16 @@
*/
EntryPtr createListEntry();
public:
+ /**
+ * Constructor for Scumm::v6::CodeGenerator.
+ *
+ * @param engine Pointer to the Engine used for the script.
+ * @param output The std::ostream to output the code to.
+ */
CodeGenerator(Engine *engine, std::ostream &output) : ::CodeGenerator(engine, output) {}
protected:
void processInst(const Instruction inst);
+ virtual void processSpecialMetadata(const Instruction inst, char c);
};
} // End of namespace v6
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