[Scummvm-cvs-logs] SF.net SVN: scummvm:[42030] tools/branches/gsoc2009-decompiler/decompiler/ syntax.h
kjdf at users.sourceforge.net
kjdf at users.sourceforge.net
Thu Jul 2 18:07:14 CEST 2009
Revision: 42030
http://scummvm.svn.sourceforge.net/scummvm/?rev=42030&view=rev
Author: kjdf
Date: 2009-07-02 16:07:14 +0000 (Thu, 02 Jul 2009)
Log Message:
-----------
decompiler: added missing file for previous commit
Added Paths:
-----------
tools/branches/gsoc2009-decompiler/decompiler/syntax.h
Added: tools/branches/gsoc2009-decompiler/decompiler/syntax.h
===================================================================
--- tools/branches/gsoc2009-decompiler/decompiler/syntax.h (rev 0)
+++ tools/branches/gsoc2009-decompiler/decompiler/syntax.h 2009-07-02 16:07:14 UTC (rev 42030)
@@ -0,0 +1,197 @@
+#ifndef SYNTAX_H
+#define SYNTAX_H
+
+#include <cassert>
+#include <list>
+#include <sstream>
+#include <string>
+
+#include "instruction.h"
+#include "misc.h"
+
+
+#include <iostream>
+using namespace std;
+
+
+struct Statement {
+ virtual std::string toString(unsigned i) = 0;
+ virtual ~Statement() {
+ }
+};
+
+
+struct InstructionWrapper : public Statement {
+
+ Instruction *_instruction;
+
+ InstructionWrapper(Instruction *instruction) : _instruction(instruction) {
+ };
+
+ std::string toString(unsigned i) {
+ return spaces(i) + _instruction->toString();
+ }
+};
+
+
+struct Goto : public Statement {
+
+ address_t _address;
+
+ Goto(address_t address) : _address(address) {
+ }
+
+ std::string toString(unsigned i) {
+ std::ostringstream ret;
+ ret << spaces(i) << "goto " << phex(_address-8) << std::endl;
+ return ret.str();
+ }
+};
+
+
+struct WhileLoop : public Statement {
+
+ std::list<InstructionWrapper*> _condition;
+ std::list<Statement*> _body;
+
+ std::string toString(unsigned i) {
+ std::ostringstream ret;
+ ret << std::endl << spaces(i) << "while (";
+ foreach (InstructionWrapper* insn, _condition)
+ ret << insn->toString(i);
+ ret << spaces(i) << ") {" << std::endl;
+ foreach (Statement *stmt, _body)
+ ret << stmt->toString(i+4);
+ ret << spaces(i) << "}" << std::endl << std::endl;
+ return ret.str();
+ }
+};
+
+
+struct DoWhileLoop : public Statement {
+
+ std::list<InstructionWrapper*> _condition;
+ std::list<Statement*> _body;
+
+ std::string toString(unsigned i) {
+ std::ostringstream ret;
+ ret << std::endl << spaces(i) << "do {";
+ foreach (Statement *stmt, _body)
+ ret << stmt->toString(i+4);
+ ret << spaces(i) << "} while (";
+ foreach (InstructionWrapper* insn, _condition)
+ ret << insn->toString(i);
+ ret << spaces(i) << ")" << std::endl << std::endl;
+ return ret.str();
+ }
+};
+
+
+struct IfThenElse : public Statement {
+
+ std::list<InstructionWrapper*> _condition;
+ std::list<Statement*> _consequence;
+ std::list<Statement*> _alternative;
+
+ std::string toString(unsigned i) {
+ std::ostringstream ret;
+ ret << std::endl << spaces(i) << "if (";
+ foreach (InstructionWrapper* insn, _condition)
+ ret << insn->toString(i);
+ ret << spaces(i) << ") {" << std::endl;
+ foreach (Statement *stmt, _consequence)
+ ret << stmt->toString(i+4);
+ ret << spaces(i) << "}";
+ if (!_alternative.empty()) {
+ ret << " else {" << std::endl;
+ foreach (Statement *stmt, _alternative)
+ ret << stmt->toString(i+4);
+ ret << spaces(i) << "}";
+ }
+ ret << std::endl << std::endl;
+ return ret.str();
+ }
+};
+
+
+void append(Block *block, Block *until, std::list<Statement*> &seq);
+
+
+DoWhileLoop *buildDoWhileLoop(Block *head) {
+ DoWhileLoop *loop = new DoWhileLoop;
+ foreach (Instruction *insn, head->_loopLatch->_instructions)
+ loop->_condition.push_back(new InstructionWrapper(insn));
+ append(head, head->_loopLatch, loop->_body);
+ return loop;
+}
+
+
+WhileLoop *buildWhileLoop(Block *head) {
+ WhileLoop *loop = new WhileLoop;
+ foreach (Instruction *insn, head->_instructions)
+ loop->_condition.push_back(new InstructionWrapper(insn));
+ append(head->nonFollowEdge(), head->_loopFollow, loop->_body);
+ return loop;
+}
+
+void append(Block *block, Block *until, std::list<Statement*> &seq) {
+ if (block == until)
+ return;
+ if (block->_visited) {
+ // TODO they should be printed more before append() only sometimes
+ // seq.push_back(new Goto(block->_instructions.front()->_addr));
+ return;
+ }
+ block->_visited = true;
+ if (block->_loopFollow) {
+ if (block->_loopType == PRE_TESTED)
+ seq.push_back(buildWhileLoop(block));
+ else if (block->_loopType == POST_TESTED)
+ seq.push_back(buildDoWhileLoop(block));
+ // TODO ENDLESS
+ append(block->_loopFollow, until, seq);
+ return;
+ }
+ foreach (Instruction *insn, block->_instructions) {
+ // TODO jump targets will be broken (pointing to not printed basic blocks) if the jump was rewired
+ Jump *jump = dynamic_cast<Jump*>(insn);
+ CondJump *condjump = dynamic_cast<CondJump*>(insn);
+ if (condjump) {
+ IfThenElse *ifte = new IfThenElse;
+ ifte->_condition.push_back(new InstructionWrapper(new Instruction("not", 999999)));
+ ifte->_consequence.push_back(new Goto(jump->target()));
+ seq.push_back(ifte);
+ } else if (jump)
+ seq.push_back(new Goto(jump->target()));
+ else
+ seq.push_back(new InstructionWrapper(insn));
+ }
+ if (block->_out.size() == 2) // TODO?
+ append(block->_out.back(), until, seq);
+ if (block->_out.size() >= 1)
+ append(block->_out.front(), until, seq);
+}
+
+
+std::list<Statement*> buildSequence(Block *block, Block *until=0) {
+ std::list<Statement*> seq;
+ append(block, until, seq);
+ return seq;
+}
+
+
+std::list<Statement*> buildAbstractSyntaxTree(ControlFlowGraph &graph) {
+ foreach (Block *block, graph._blocks) {
+ if (block->_loopLatch && block->_loopType == PRE_TESTED) {
+ block->_instructions.pop_back();
+ if (block->_loopLatch != block)
+ block->_loopLatch->_instructions.pop_back();
+ } else if (block->_loopLatch && block->_loopType == POST_TESTED) {
+ block->_loopLatch->_instructions.pop_back();
+ }
+ }
+ return buildSequence(graph._entry);
+}
+
+
+#endif
Property changes on: tools/branches/gsoc2009-decompiler/decompiler/syntax.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
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