00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "compiler.h"
00022 #include "tree.h"
00023 #include "../utils/FormatableString.h"
00024
00025 #include <cassert>
00026 #include <memory>
00027 #include <iostream>
00028
00029 namespace Aseba
00030 {
00031 Node* Node::expandToAsebaTree(std::wostream *dump, unsigned int index)
00032 {
00033
00034 for (NodesVector::iterator it = children.begin(); it != children.end();)
00035 {
00036 *(it) = (*it)->expandToAsebaTree(dump, index);
00037 ++it;
00038 }
00039 return this;
00040 }
00041
00042
00043 Node* AssignmentNode::expandToAsebaTree(std::wostream *dump, unsigned int index)
00044 {
00045 assert(children.size() == 2);
00046
00047 MemoryVectorNode* leftVector = dynamic_cast<MemoryVectorNode*>(children[0]);
00048 if (!leftVector)
00049 throw TranslatableError(sourcePos, ERROR_INCORRECT_LEFT_VALUE).arg(children[0]->toNodeName());
00050 leftVector->setWrite(true);
00051 Node* rightVector = children[1];
00052
00053 std::auto_ptr<BlockNode> block(new BlockNode(sourcePos));
00054 for (unsigned int i = 0; i < leftVector->getVectorSize(); i++)
00055 {
00056
00057 std::auto_ptr<AssignmentNode> assignment(new AssignmentNode(sourcePos));
00058 assignment->children.push_back(leftVector->expandToAsebaTree(dump, i));
00059 assignment->children.push_back(rightVector->expandToAsebaTree(dump, i));
00060 block->children.push_back(assignment.release());
00061 }
00062
00063 delete this;
00064 return block.release();
00065 }
00066
00067
00069 Node* BinaryArithmeticNode::expandToAsebaTree(std::wostream *dump, unsigned int index)
00070 {
00071 std::auto_ptr<Node> left(children[0]->expandToAsebaTree(dump, index));
00072 std::auto_ptr<Node> right(children[1]->expandToAsebaTree(dump, index));
00073 return new BinaryArithmeticNode(sourcePos, op, left.release(), right.release());
00074 }
00075
00076
00078 Node* UnaryArithmeticNode::expandToAsebaTree(std::wostream *dump, unsigned int index)
00079 {
00080 std::auto_ptr<Node> left(children[0]->expandToAsebaTree(dump, index));
00081 return new UnaryArithmeticNode(sourcePos, op, left.release());
00082 }
00083
00084
00086 Node* TupleVectorNode::expandToAsebaTree(std::wostream *dump, unsigned int index)
00087 {
00088 size_t total = 0;
00089 size_t prevTotal = 0;
00090 for (size_t i = 0; i < children.size(); i++)
00091 {
00092 prevTotal = total;
00093 total += children[i]->getVectorSize();
00094 if (index < total)
00095 {
00096 return children[i]->expandToAsebaTree(dump, index-prevTotal);
00097 }
00098 }
00099 assert(0);
00100 return 0;
00101 }
00102
00103
00104 Node* MemoryVectorNode::expandToAsebaTree(std::wostream *dump, unsigned int index)
00105 {
00106 assert(index < getVectorSize());
00107
00108
00109 TupleVectorNode* accessIndex = NULL;
00110 if (children.size() > 0)
00111 accessIndex = dynamic_cast<TupleVectorNode*>(children[0]);
00112
00113 if (accessIndex || children.size() == 0)
00114 {
00115
00116 unsigned pointer = getVectorAddr() + index;
00117
00118 if (pointer >= arrayAddr + arraySize)
00119 throw TranslatableError(sourcePos, ERROR_ARRAY_OUT_OF_BOUND).arg(arrayName).arg(index).arg(arraySize);
00120
00121 if (write == true)
00122 return new StoreNode(sourcePos, pointer);
00123 else
00124 return new LoadNode(sourcePos, pointer);
00125 }
00126 else
00127 {
00128
00129 std::auto_ptr<Node> array;
00130 if (write == true)
00131 array.reset(new ArrayWriteNode(sourcePos, arrayAddr, arraySize, arrayName));
00132 else
00133 array.reset(new ArrayReadNode(sourcePos, arrayAddr, arraySize, arrayName));
00134
00135 array->children.push_back(children[0]->expandToAsebaTree(dump, index));
00136 children[0] = 0;
00137 return array.release();
00138 }
00139 }
00140
00141 Node* ArithmeticAssignmentNode::expandToAsebaTree(std::wostream* dump, unsigned int index)
00142 {
00143 assert(children.size() == 2);
00144
00145 Node* leftVector = children[0];
00146 Node* rightVector = children[1];
00147
00148
00149 std::auto_ptr<AssignmentNode> assignment(new AssignmentNode(sourcePos));
00150 std::auto_ptr<BinaryArithmeticNode> binary(new BinaryArithmeticNode(sourcePos, op, leftVector->deepCopy(), rightVector->deepCopy()));
00151 assignment->children.push_back(leftVector->deepCopy());
00152 assignment->children.push_back(binary.release());
00153
00154 std::auto_ptr<Node> finalBlock(assignment->expandToAsebaTree(dump, index));
00155
00156 assignment.release();
00157 delete this;
00158
00159 return finalBlock.release();
00160 }
00161
00162
00163 Node* UnaryArithmeticAssignmentNode::expandToAsebaTree(std::wostream* dump, unsigned int index)
00164 {
00165 assert(children.size() == 1);
00166
00167 Node* memoryVector = children[0];
00168
00169
00170 std::auto_ptr<TupleVectorNode> constant(new TupleVectorNode(sourcePos));
00171 for (unsigned int i = 0; i < memoryVector->getVectorSize(); i++)
00172 constant->addImmediateValue(1);
00173
00174
00175 std::auto_ptr<ArithmeticAssignmentNode> assignment(new ArithmeticAssignmentNode(sourcePos, arithmeticOp, memoryVector->deepCopy(), constant.release()));
00176 std::auto_ptr<Node> finalBlock(assignment->expandToAsebaTree(dump, index));
00177
00178 assignment.release();
00179 delete this;
00180
00181 return finalBlock.release();
00182 }
00183
00184
00185 void Node::checkVectorSize() const
00186 {
00187
00188 for (NodesVector::const_iterator it = children.begin(); it != children.end();)
00189 {
00190 (*it)->checkVectorSize();
00191 ++it;
00192 }
00193 }
00194
00195
00196 void AssignmentNode::checkVectorSize() const
00197 {
00198 assert(children.size() == 2);
00199
00200
00201 unsigned lSize = children[0]->getVectorSize();
00202 unsigned rSize = children[1]->getVectorSize();
00203
00204
00205 if (lSize != rSize)
00206 throw TranslatableError(sourcePos, ERROR_ARRAY_SIZE_MISMATCH).arg(lSize).arg(rSize);
00207 }
00208
00209 void ArithmeticAssignmentNode::checkVectorSize() const
00210 {
00211 assert(children.size() == 2);
00212
00213
00214 unsigned lSize = children[0]->getVectorSize();
00215 unsigned rSize = children[1]->getVectorSize();
00216
00217
00218 if (lSize != rSize)
00219 throw TranslatableError(sourcePos, ERROR_ARRAY_SIZE_MISMATCH).arg(lSize).arg(rSize);
00220 }
00221
00222
00223 void IfWhenNode::checkVectorSize() const
00224 {
00225 assert(children.size() > 0);
00226
00227 unsigned conditionSize = children[0]->getVectorSize();
00228 if (conditionSize != 1)
00229 throw TranslatableError(sourcePos, ERROR_IF_VECTOR_CONDITION);
00230
00231 if (children.size() > 1 && children[1])
00232 children[1]->checkVectorSize();
00233
00234 if (children.size() > 2 && children[2])
00235 children[2]->checkVectorSize();
00236 }
00237
00238 void FoldedIfWhenNode::checkVectorSize() const
00239 {
00240 assert(children.size() > 1);
00241
00242 unsigned conditionLeftSize = children[0]->getVectorSize();
00243 unsigned conditionRightSize = children[1]->getVectorSize();
00244 if (conditionLeftSize != 1 || conditionRightSize != 1)
00245 throw TranslatableError(sourcePos, ERROR_IF_VECTOR_CONDITION);
00246
00247 if (children.size() > 2 && children[2])
00248 children[2]->checkVectorSize();
00249
00250 if (children.size() > 3 && children[3])
00251 children[3]->checkVectorSize();
00252 }
00253
00254 void WhileNode::checkVectorSize() const
00255 {
00256 assert(children.size() > 0);
00257
00258 unsigned conditionSize = children[0]->getVectorSize();
00259 if (conditionSize != 1)
00260 throw TranslatableError(sourcePos, ERROR_WHILE_VECTOR_CONDITION);
00261
00262 if (children.size() > 1 && children[1])
00263 children[1]->checkVectorSize();
00264 }
00265
00266 void FoldedWhileNode::checkVectorSize() const
00267 {
00268 assert(children.size() > 1);
00269
00270 unsigned conditionLeftSize = children[0]->getVectorSize();
00271 unsigned conditionRightSize = children[1]->getVectorSize();
00272 if (conditionLeftSize != 1 || conditionRightSize != 1)
00273 throw TranslatableError(sourcePos, ERROR_WHILE_VECTOR_CONDITION);
00274
00275 if (children.size() > 2 && children[2])
00276 children[2]->checkVectorSize();
00277 }
00278
00279
00281 unsigned Node::getVectorAddr() const
00282 {
00283 if (children.size() > 0)
00284 return children[0]->getVectorAddr();
00285 else
00286 return E_NOVAL;
00287 }
00288
00289
00291 unsigned Node::getVectorSize() const
00292 {
00293 unsigned size = E_NOVAL;
00294 unsigned new_size = E_NOVAL;
00295
00296 for (NodesVector::const_iterator it = children.begin(); it != children.end(); ++it)
00297 {
00298 new_size = (*it)->getVectorSize();
00299 if (size == E_NOVAL)
00300 size = new_size;
00301 else if (size != new_size)
00302 throw TranslatableError(sourcePos, ERROR_ARRAY_SIZE_MISMATCH).arg(size).arg(new_size);
00303 }
00304
00305 return size;
00306 }
00307
00308
00309 unsigned TupleVectorNode::getVectorSize() const
00310 {
00311 unsigned size = 0;
00312 NodesVector::const_iterator it;
00313 for (it = children.begin(); it != children.end(); it++)
00314 size += (*it)->getVectorSize();
00315 return size;
00316 }
00317
00318
00322 unsigned MemoryVectorNode::getVectorAddr() const
00323 {
00324 assert(children.size() <= 1);
00325
00326 int shift = 0;
00327
00328
00329 if (children.size() == 1)
00330 {
00331 TupleVectorNode* index = dynamic_cast<TupleVectorNode*>(children[0]);
00332 if (index)
00333 {
00334 shift = index->getImmediateValue(0);
00335 }
00336 else
00337
00338 return E_NOVAL;
00339 }
00340
00341 if (shift < 0 || shift >= int(arraySize))
00342 throw TranslatableError(sourcePos, ERROR_ARRAY_OUT_OF_BOUND).arg(arrayName).arg(shift).arg(arraySize);
00343 return arrayAddr + shift;
00344 }
00345
00346
00348 unsigned MemoryVectorNode::getVectorSize() const
00349 {
00350 assert(children.size() <= 1);
00351
00352 if (children.size() == 1)
00353 {
00354 TupleVectorNode* index = dynamic_cast<TupleVectorNode*>(children[0]);
00355 if (index)
00356 {
00357 unsigned numberOfIndex = index->getVectorSize();
00358
00359 if (numberOfIndex == 1)
00360 {
00361
00362 return 1;
00363 }
00364 else if (numberOfIndex == 2)
00365 {
00366 const int im0(index->getImmediateValue(0));
00367 const int im1(index->getImmediateValue(1));
00368 if (im1 < 0 || im1 >= int(arraySize))
00369 throw TranslatableError(sourcePos, ERROR_ARRAY_OUT_OF_BOUND).arg(arrayName).arg(im1).arg(arraySize);
00370
00371 return im1 - im0 + 1;
00372 }
00373 else
00374
00375 throw TranslatableError(sourcePos, ERROR_ARRAY_ILLEGAL_ACCESS);
00376 }
00377 else
00378
00379 return 1;
00380 }
00381 else
00382
00383 return arraySize;
00384 }
00385
00387 bool MemoryVectorNode::isAddressStatic() const
00388 {
00389 if (children.empty())
00390 return true;
00391 TupleVectorNode* index = dynamic_cast<TupleVectorNode*>(children[0]);
00392 if (index && index->children.size() <= 2 && index->isImmediateVector())
00393 return true;
00394 return false;
00395 }
00396
00397 bool TupleVectorNode::isImmediateVector() const
00398 {
00399 NodesVector::const_iterator it;
00400 for (it = children.begin(); it != children.end(); it++)
00401 {
00402 ImmediateNode* node = dynamic_cast<ImmediateNode*>(*it);
00403 if (!node)
00404 return false;
00405 }
00406 return true;
00407 }
00408
00410 int TupleVectorNode::getImmediateValue(unsigned index) const
00411 {
00412 assert(index < getVectorSize());
00413 assert(isImmediateVector());
00414 ImmediateNode* node = dynamic_cast<ImmediateNode*>(children[index]);
00415 assert(node);
00416 return node->value;
00417 }
00418 }