ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

abstractsyntaxtree.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/stark/tools/abstractsyntaxtree.h"
00024 
00025 #include "common/debug.h"
00026 
00027 namespace Stark {
00028 namespace Tools {
00029 
00030 ASTNode::ASTNode(ASTNode *parent) :
00031         _parent(parent) {
00032 
00033 }
00034 
00035 ASTNode::~ASTNode() {
00036 
00037 }
00038 
00039 void ASTNode::printWithDepth(uint depth, const Common::String &string) const {
00040     Common::String prefix;
00041     for (uint i = 0; i < depth; i++) {
00042         prefix += "\t";
00043     }
00044 
00045     debug("%s%s", prefix.c_str(), string.c_str());
00046 }
00047 
00048 void ASTNode::findSuccessors(ASTNode **follower, ASTNode **trueBranch, ASTNode **falseBranch) const {
00049     findSuccessorsIntern(this, follower, trueBranch, falseBranch);
00050 }
00051 
00052 ASTBlock::ASTBlock(ASTNode *parent) :
00053         ASTNode(parent) {
00054 
00055 }
00056 
00057 ASTBlock::~ASTBlock() {
00058     for (uint i = 0; i < _children.size(); i++) {
00059         delete _children[i];
00060     }
00061 }
00062 
00063 void ASTBlock::addNode(ASTNode *node) {
00064     _children.push_back(node);
00065 }
00066 
00067 void ASTBlock::print(uint depth, DefinitionRegistry *definitions) {
00068     for (uint i = 0; i < _children.size(); i++) {
00069         _children[i]->print(depth, definitions);
00070     }
00071 }
00072 
00073 Common::Array<const ASTCommand *> ASTBlock::listCommands(uint16 index) const {
00074     Common::Array<const ASTCommand *> list;
00075 
00076     for (uint i = 0; i < _children.size(); i++) {
00077         list.push_back(_children[i]->listCommands(index));
00078     }
00079 
00080     return list;
00081 }
00082 
00083 void ASTBlock::findSuccessorsIntern(const ASTNode *node, ASTNode **follower, ASTNode **trueBranch, ASTNode **falseBranch) const {
00084     if (node == this) {
00085         if (_parent) {
00086             _parent->findSuccessorsIntern(node, follower, trueBranch, falseBranch);
00087         }
00088         return;
00089     }
00090 
00091     for (uint i = 0; i < _children.size() - 1; i++) {
00092         if (node == _children[i]) {
00093             *follower = _children[i+1];
00094             return;
00095         }
00096     }
00097 
00098     if (node == _children.back()) {
00099         if (_parent) {
00100             _parent->findSuccessorsIntern(this, follower, trueBranch, falseBranch);
00101         }
00102         return;
00103     }
00104 
00105     error("Unknown node");
00106 }
00107 
00108 const ASTCommand *ASTBlock::getFirstCommand() const {
00109     if (!_children.empty()) {
00110         return _children[0]->getFirstCommand();
00111     } else {
00112         return nullptr;
00113     }
00114 }
00115 
00116 ASTCommand::ASTCommand(ASTNode *parent, Command *command, DefinitionRegistry *definitions) :
00117         ASTNode(parent),
00118         Command(command) {
00119     _arguments = command->getEffectiveArguments();
00120 
00121     for (uint i = 0; i < _arguments.size(); i++) {
00122         if (_arguments[i].type == Resources::Command::Argument::kTypeResourceReference) {
00123             definitions->registerReference(_arguments[i].referenceValue);
00124         }
00125     }
00126 }
00127 
00128 void ASTCommand::print(uint depth, DefinitionRegistry *definitions) {
00129     printWithDepth(depth, callString(definitions));
00130 }
00131 
00132 Common::String ASTCommand::callString(DefinitionRegistry *definitions) {
00133     return Common::String::format("%s(%s)", _subTypeDesc->name, describeArguments(definitions).c_str());
00134 }
00135 
00136 Common::Array<const ASTCommand *> ASTCommand::listCommands(uint16 index) const {
00137     Common::Array<const ASTCommand *> list;
00138 
00139     if (_index == index) {
00140         list.push_back(this);
00141     }
00142 
00143     return list;
00144 }
00145 
00146 void ASTCommand::findSuccessorsIntern(const ASTNode *node, ASTNode **follower, ASTNode **trueBranch, ASTNode **falseBranch) const {
00147     assert(node == this);
00148 
00149     _parent->findSuccessorsIntern(node, follower, trueBranch, falseBranch);
00150 }
00151 
00152 const ASTCommand *ASTCommand::getFirstCommand() const {
00153     return this;
00154 }
00155 
00156 ASTCondition::ASTCondition(ASTNode *parent) :
00157         ASTNode(parent),
00158         condition(nullptr),
00159         invertedCondition(false),
00160         thenBlock(nullptr),
00161         elseBlock(nullptr) {
00162 
00163 }
00164 
00165 ASTCondition::~ASTCondition() {
00166     delete condition;
00167     delete thenBlock;
00168     delete elseBlock;
00169 }
00170 
00171 void ASTCondition::print(uint depth, DefinitionRegistry *definitions) {
00172     Common::String ifHeader = Common::String::format("if (%s%s) {", invertedCondition ? "!" : "",
00173                                                      condition->callString(definitions).c_str());
00174     printWithDepth(depth, ifHeader);
00175 
00176     thenBlock->print(depth + 1, definitions);
00177 
00178     if (elseBlock) {
00179         printWithDepth(depth, "} else {");
00180         elseBlock->print(depth + 1, definitions);
00181     }
00182     printWithDepth(depth, "}");
00183 }
00184 
00185 Common::Array<const ASTCommand *> ASTCondition::listCommands(uint16 index) const {
00186     Common::Array<const ASTCommand *> list;
00187 
00188     list.push_back(condition->listCommands(index));
00189     list.push_back(thenBlock->listCommands(index));
00190     if (elseBlock) {
00191         list.push_back(elseBlock->listCommands(index));
00192     }
00193 
00194     return list;
00195 }
00196 
00197 void ASTCondition::findSuccessorsIntern(const ASTNode *node, ASTNode **follower, ASTNode **trueBranch, ASTNode **falseBranch) const {
00198     if (node == this) {
00199         _parent->findSuccessorsIntern(node, follower, trueBranch, falseBranch);
00200         return;
00201     }
00202 
00203     if (node == condition) {
00204         ASTNode *nextNode = nullptr;
00205         if (!elseBlock) {
00206             _parent->findSuccessorsIntern(this, &nextNode, nullptr, nullptr);
00207         }
00208 
00209         if (!invertedCondition) {
00210             *trueBranch = thenBlock;
00211             *falseBranch = elseBlock ? elseBlock : nextNode;
00212         } else {
00213             *trueBranch = elseBlock ? elseBlock : nextNode;
00214             *falseBranch = thenBlock;
00215         }
00216 
00217         return;
00218     }
00219 
00220     if (node == thenBlock) {
00221         _parent->findSuccessorsIntern(this, follower, trueBranch, falseBranch);
00222         return;
00223     }
00224 
00225     if (node == elseBlock) {
00226         _parent->findSuccessorsIntern(this, follower, trueBranch, falseBranch);
00227         return;
00228     }
00229 
00230     error("Unknown node");
00231 }
00232 
00233 const ASTCommand *ASTCondition::getFirstCommand() const {
00234     return condition->getFirstCommand();
00235 }
00236 
00237 ASTLoop::ASTLoop(ASTNode *parent) :
00238         ASTNode(parent),
00239         condition(nullptr),
00240         invertedCondition(false),
00241         loopBlock(nullptr) {
00242 
00243 }
00244 
00245 ASTLoop::~ASTLoop() {
00246     delete condition;
00247     delete loopBlock;
00248 }
00249 
00250 void ASTLoop::print(uint depth, DefinitionRegistry *definitions) {
00251     Common::String loopHeader;
00252     if (condition) {
00253         loopHeader = Common::String::format("while (%s%s) {", invertedCondition ? "!" : "",
00254                                             condition->callString(definitions).c_str());
00255     } else {
00256         loopHeader = "loop {";
00257     }
00258     printWithDepth(depth, loopHeader);
00259 
00260     loopBlock->print(depth + 1, definitions);
00261 
00262     printWithDepth(depth, "}");
00263 }
00264 
00265 Common::Array<const ASTCommand *> ASTLoop::listCommands(uint16 index) const {
00266     Common::Array<const ASTCommand *> list;
00267 
00268     if (condition) {
00269         list.push_back(condition->listCommands(index));
00270     }
00271     list.push_back(loopBlock->listCommands(index));
00272 
00273     return list;
00274 }
00275 
00276 void ASTLoop::findSuccessorsIntern(const ASTNode *node, ASTNode **follower, ASTNode **trueBranch, ASTNode **falseBranch) const {
00277     if (node == this) {
00278         _parent->findSuccessorsIntern(node, follower, trueBranch, falseBranch);
00279         return;
00280     }
00281 
00282     if (node == condition) {
00283         ASTNode *nextNode = nullptr;
00284         _parent->findSuccessorsIntern(this, &nextNode, nullptr, nullptr);
00285 
00286         if (!invertedCondition) {
00287             *trueBranch = loopBlock;
00288             *falseBranch = nextNode;
00289         } else {
00290             *trueBranch = nextNode;
00291             *falseBranch = loopBlock;
00292         }
00293 
00294         return;
00295     }
00296 
00297     if (node == loopBlock) {
00298         *follower = condition ? (ASTNode *)condition : (ASTNode *)loopBlock;
00299         return;
00300     }
00301 
00302     error("Unknown node");
00303 }
00304 
00305 const ASTCommand *ASTLoop::getFirstCommand() const {
00306     return condition ? condition->getFirstCommand() : loopBlock->getFirstCommand();
00307 }
00308 
00309 } // End of namespace Tools
00310 } // End of namespace Stark


Generated on Sat May 18 2019 05:00:54 for ResidualVM by doxygen 1.7.1
curved edge   curved edge