00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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 }
00310 }