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 #include <memory>
00025 #include <valarray>
00026 #include <iostream>
00027 #include <cassert>
00028 #include <typeinfo>
00029
00030 #define IS_ONE_OF(array) (isOneOf<sizeof(array)/sizeof(Token::Type)>(array))
00031 #define EXPECT_ONE_OF(array) (expectOneOf<sizeof(array)/sizeof(Token::Type)>(array))
00032
00033 #define STRICT false
00034
00035 namespace Aseba
00036 {
00038 void Compiler::internalCompilerError() const
00039 {
00040 throw TranslatableError(tokens.front().pos, ERROR_INTERNAL);
00041 }
00042
00044 void Compiler::expect(const Token::Type& type) const
00045 {
00046 if (tokens.front() != type)
00047 throw TranslatableError(tokens.front().pos,
00048 ERROR_EXPECTING)
00049 .arg(Token(type).typeName())
00050 .arg(tokens.front().typeName());
00051 }
00052
00054 unsigned Compiler::expectUInt12Literal() const
00055 {
00056 expect(Token::TOKEN_INT_LITERAL);
00057 if (tokens.front().iValue < 0 || tokens.front().iValue > 4095)
00058 throw TranslatableError(tokens.front().pos,
00059 ERROR_UINT12_OUT_OF_RANGE)
00060 .arg(tokens.front().iValue);
00061 return tokens.front().iValue;
00062 }
00063
00065 unsigned Compiler::expectUInt16Literal() const
00066 {
00067 expect(Token::TOKEN_INT_LITERAL);
00068 if (tokens.front().iValue < 0 || tokens.front().iValue > 65535)
00069 throw TranslatableError(tokens.front().pos,
00070 ERROR_UINT16_OUT_OF_RANGE)
00071 .arg(tokens.front().iValue);
00072 return tokens.front().iValue;
00073 }
00074
00076 unsigned Compiler::expectPositiveInt16Literal() const
00077 {
00078 expect(Token::TOKEN_INT_LITERAL);
00079 if (tokens.front().iValue < 0 || tokens.front().iValue > 32767)
00080 throw TranslatableError(tokens.front().pos,
00081 ERROR_PINT16_OUT_OF_RANGE)
00082 .arg(tokens.front().iValue);
00083 return tokens.front().iValue;
00084 }
00085
00087 int Compiler::expectAbsoluteInt16Literal(bool negative) const
00088 {
00089 expect(Token::TOKEN_INT_LITERAL);
00090 int limit(32767);
00091 if (negative)
00092 limit++;
00093 if (tokens.front().iValue < 0 || tokens.front().iValue > limit)
00094 throw TranslatableError(tokens.front().pos,
00095 ERROR_INT16_OUT_OF_RANGE)
00096 .arg(tokens.front().iValue);
00097 return tokens.front().iValue;
00098 }
00099
00101 unsigned Compiler::expectPositiveConstant() const
00102 {
00103 expect(Token::TOKEN_STRING_LITERAL);
00104 const std::wstring name = tokens.front().sValue;
00105 const SourcePos pos = tokens.front().pos;
00106 const ConstantsMap::const_iterator constIt(findConstant(name, pos));
00107
00108 const int value = constIt->second;
00109 if (value < 0 || value > 32767)
00110 throw TranslatableError(tokens.front().pos,
00111 ERROR_PCONSTANT_OUT_OF_RANGE)
00112 .arg(tokens.front().sValue)
00113 .arg(value);
00114 return value;
00115 }
00116
00118 int Compiler::expectConstant() const
00119 {
00120 expect(Token::TOKEN_STRING_LITERAL);
00121 const std::wstring name = tokens.front().sValue;
00122 const SourcePos pos = tokens.front().pos;
00123 const ConstantsMap::const_iterator constIt(findConstant(name, pos));
00124
00125 const int value = constIt->second;
00126 if (value < -32768 || value > 32767)
00127 throw TranslatableError(tokens.front().pos,
00128 ERROR_CONSTANT_OUT_OF_RANGE)
00129 .arg(tokens.front().sValue)
00130 .arg(value);
00131 return value;
00132 }
00133
00135 unsigned Compiler::expectPositiveInt16LiteralOrConstant() const
00136 {
00137 if (tokens.front() == Token::TOKEN_INT_LITERAL)
00138 return expectPositiveInt16Literal();
00139 else
00140 return expectPositiveConstant();
00141 }
00142
00144 int Compiler::expectInt16LiteralOrConstant()
00145 {
00146 if (tokens.front() == Token::TOKEN_OP_NEG)
00147 {
00148 tokens.pop_front();
00149 return -expectAbsoluteInt16Literal(true);
00150 }
00151 else if (tokens.front() == Token::TOKEN_INT_LITERAL)
00152 {
00153 return expectAbsoluteInt16Literal(false);
00154 }
00155 else
00156 return expectConstant();
00157 }
00158
00160 unsigned Compiler::expectGlobalEventId() const
00161 {
00162 assert(commonDefinitions);
00163
00164 expect(Token::TOKEN_STRING_LITERAL);
00165
00166 const std::wstring & name = tokens.front().sValue;
00167 const SourcePos pos = tokens.front().pos;
00168 const EventsMap::const_iterator eventIt(findGlobalEvent(name, pos));
00169
00170 return eventIt->second;
00171 }
00172
00174 unsigned Compiler::expectAnyEventId() const
00175 {
00176 assert(targetDescription);
00177
00178 expect(Token::TOKEN_STRING_LITERAL);
00179
00180 const std::wstring & name = tokens.front().sValue;
00181 const SourcePos pos = tokens.front().pos;
00182 const EventsMap::const_iterator eventIt(findAnyEvent(name, pos));
00183
00184 return eventIt->second;
00185 }
00186
00188 std::wstring Compiler::eventName(unsigned eventId) const
00189 {
00190
00191 if (eventId < commonDefinitions->events.size())
00192 return commonDefinitions->events[eventId].name;
00193
00194
00195 int localId = ASEBA_EVENT_LOCAL_EVENTS_START - eventId;
00196 if ((localId >= 0) && (localId < (int)targetDescription->localEvents.size()))
00197 return targetDescription->localEvents[localId].name;
00198
00199 return L"unknown";
00200 }
00201
00203 template <int length>
00204 bool Compiler::isOneOf(const Token::Type types[length]) const
00205 {
00206 for (size_t i = 0; i < length; i++)
00207 {
00208 if (tokens.front() == types[i])
00209 return true;
00210 }
00211 return false;
00212 }
00213
00215 template <int length>
00216 void Compiler::expectOneOf(const Token::Type types[length]) const
00217 {
00218 if (!isOneOf<length>(types))
00219 {
00220 std::wstring expectedTypes;
00221 for (size_t i = 0; i < length; i++)
00222 {
00223 expectedTypes += Token(types[i]).typeName();
00224 if (i + 1 < length)
00225 expectedTypes += L", ";
00226 }
00227
00228 throw TranslatableError(tokens.front().pos, ERROR_EXPECTING_ONE_OF).arg(expectedTypes).arg(tokens.front().typeName());
00229 }
00230 }
00231
00232 void Compiler::freeTemporaryMemory()
00233 {
00234 endVariableIndex = 0;
00235 }
00236
00237 void Compiler::allocateTemporaryMemory(const SourcePos varPos, const unsigned size, unsigned& varAddr)
00238 {
00239
00240 unsigned endOfMemory = targetDescription->variablesSize - endVariableIndex;
00241 varAddr = endOfMemory - size;
00242 endVariableIndex += size;
00243
00244
00245 if (freeVariableIndex + endVariableIndex > targetDescription->variablesSize)
00246 throw TranslatableError(varPos, ERROR_NOT_ENOUGH_TEMP_SPACE);
00247 }
00248
00249 AssignmentNode* Compiler::allocateTemporaryVariable(const SourcePos varPos, Node* rValue)
00250 {
00251 static unsigned uid = 0;
00252
00253
00254 const unsigned size = rValue->getVectorSize();
00255 unsigned addr = Node::E_NOVAL;
00256 allocateTemporaryMemory(varPos, size, addr);
00257
00258
00259 std::auto_ptr<AssignmentNode> assignment(new AssignmentNode(varPos));
00260 assignment->children.push_back(new MemoryVectorNode(varPos, addr, size, WFormatableString(L"temp%0").arg(uid++)));
00261 assignment->children.push_back(rValue);
00262 return assignment.release();
00263 }
00264
00266 Node* Compiler::parseProgram()
00267 {
00268 std::auto_ptr<ProgramNode> block(new ProgramNode(tokens.front().pos));
00269
00270 while (tokens.front() == Token::TOKEN_STR_var)
00271 {
00272
00273 Node *child = parseVarDef();
00274 if (child)
00275 block->children.push_back(child);
00276 }
00277
00278 while (tokens.front() != Token::TOKEN_END_OF_STREAM)
00279 {
00280
00281 Node *child = parseStatement();
00282 assert(child);
00283 block->children.push_back(child);
00284 }
00285 return block.release();
00286 }
00287
00289 Node* Compiler::parseStatement()
00290 {
00291
00292 freeTemporaryMemory();
00293
00294 switch (tokens.front())
00295 {
00296 case Token::TOKEN_STR_var: throw TranslatableError(tokens.front().pos, ERROR_MISPLACED_VARDEF);
00297 case Token::TOKEN_STR_onevent: return parseOnEvent();
00298 case Token::TOKEN_STR_sub: return parseSubDecl();
00299 default: return parseBlockStatement();
00300 }
00301 }
00302
00304 Node* Compiler::parseBlockStatement()
00305 {
00306 switch (tokens.front())
00307 {
00308 case Token::TOKEN_STR_if: return parseIfWhen(false);
00309 case Token::TOKEN_STR_when: return parseIfWhen(true);
00310 case Token::TOKEN_STR_for: return parseFor();
00311 case Token::TOKEN_STR_while: return parseWhile();
00312 case Token::TOKEN_STR_emit: return parseEmit();
00313 case Token::TOKEN_STR_call: return parseFunctionCall();
00314 case Token::TOKEN_STR_callsub: return parseCallSub();
00315 case Token::TOKEN_STR_return: return parseReturn();
00316 default: return parseAssignment();
00317 }
00318 }
00319
00321 Node* Compiler::parseReturn()
00322 {
00323 SourcePos pos = tokens.front().pos;
00324 tokens.pop_front();
00325 return new ReturnNode(pos);
00326 }
00327
00329 Node* Compiler::parseVarDef()
00330 {
00331 tokens.pop_front();
00332
00333
00334 if (tokens.front() != Token::TOKEN_STRING_LITERAL)
00335 throw TranslatableError(tokens.front().pos,
00336 ERROR_EXPECTING_IDENTIFIER).arg(tokens.front().toWString());
00337
00338
00339 std::wstring varName = tokens.front().sValue;
00340 SourcePos varPos = tokens.front().pos;
00341 unsigned varSize = Node::E_NOVAL;
00342 unsigned varAddr = freeVariableIndex;
00343
00344 tokens.pop_front();
00345
00346
00347 varSize = parseVariableDefSize();
00348
00349
00350 if (variablesMap.find(varName) != variablesMap.end())
00351 throw TranslatableError(varPos, ERROR_VAR_ALREADY_DEFINED).arg(varName);
00352
00353
00354 if(commonDefinitions->constants.contains(varName))
00355 throw TranslatableError(varPos, ERROR_VAR_CONST_COLLISION).arg(varName);
00356
00357
00358 std::auto_ptr<MemoryVectorNode> me(new MemoryVectorNode(varPos, varAddr, varSize, varName));
00359 std::auto_ptr<Node> temp;
00360 temp.reset(parseVarDefInit(me.get()));
00361 if (temp.get())
00362 {
00363
00364 varSize = me->getVectorSize();
00365 me.release();
00366 }
00367
00368
00369 if (varSize == 0 || varSize == Node::E_NOVAL)
00370 throw TranslatableError(varPos, ERROR_UNDEFINED_SIZE).arg(varName);
00371
00372
00373 variablesMap[varName] = std::make_pair(varAddr, varSize);
00374 freeVariableIndex += varSize;
00375
00376
00377 if (freeVariableIndex > targetDescription->variablesSize)
00378 throw TranslatableError(varPos, ERROR_NOT_ENOUGH_SPACE);
00379
00380 if (temp.get())
00381 return temp.release();
00382 else
00383 return NULL;
00384 }
00385
00386 AssignmentNode *Compiler::parseVarDefInit(MemoryVectorNode* lValue)
00387 {
00388 if (tokens.front() == Token::TOKEN_ASSIGN)
00389 {
00390 SourcePos pos = tokens.front().pos;
00391 tokens.pop_front();
00392
00393
00394 std::auto_ptr<Node> rValue(parseTupleVector(true));
00395 if (rValue.get() == NULL)
00396 {
00397
00398 rValue.reset(parseBinaryOrExpression());
00399 }
00400
00401 if (lValue->getVectorSize() == Node::E_NOVAL)
00402 {
00403
00404 lValue->arraySize = rValue->getVectorSize();
00405 }
00406
00407 std::auto_ptr<AssignmentNode> assign(new AssignmentNode(pos));
00408 assign->children.push_back(lValue);
00409 assign->children.push_back(rValue.release());
00410 return assign.release();
00411 }
00412
00413 return NULL;
00414 }
00415
00416
00418 Node* Compiler::parseAssignment()
00419 {
00420 expect(Token::TOKEN_STRING_LITERAL);
00421
00422 static const Token::Type compoundBinaryAssignment[] = { Token::TOKEN_OP_ADD_EQUAL, Token::TOKEN_OP_NEG_EQUAL,
00423 Token::TOKEN_OP_MULT_EQUAL, Token::TOKEN_OP_DIV_EQUAL, Token::TOKEN_OP_MOD_EQUAL,
00424 Token::TOKEN_OP_BIT_AND_EQUAL, Token::TOKEN_OP_BIT_OR_EQUAL, Token::TOKEN_OP_BIT_XOR_EQUAL,
00425 Token::TOKEN_OP_SHIFT_LEFT_EQUAL, Token::TOKEN_OP_SHIFT_RIGHT_EQUAL};
00426
00427
00428 std::auto_ptr<Node> lValue(parseBinaryOrExpression());
00429
00430
00431 if (tokens.front() == Token::TOKEN_ASSIGN)
00432 {
00433 std::auto_ptr<AssignmentNode> assignment(new AssignmentNode(tokens.front().pos));
00434 tokens.pop_front();
00435
00436 assignment->children.push_back(lValue.release());
00437 assignment->children.push_back(parseBinaryOrExpression());
00438 return assignment.release();
00439 }
00440 else if ((tokens.front() == Token::TOKEN_OP_PLUS_PLUS) || (tokens.front() == Token::TOKEN_OP_MINUS_MINUS))
00441 {
00442 SourcePos pos = tokens.front().pos;
00443 Compiler::Token op = tokens.front();
00444 tokens.pop_front();
00445
00446 std::auto_ptr<UnaryArithmeticAssignmentNode> assignment(
00447 new UnaryArithmeticAssignmentNode(
00448 pos,
00449 op,
00450 lValue.release()));
00451
00452 return assignment.release();
00453 }
00454 else if (IS_ONE_OF(compoundBinaryAssignment))
00455 {
00456 SourcePos pos = tokens.front().pos;
00457 Compiler::Token op = tokens.front();
00458 tokens.pop_front();
00459
00460 std::auto_ptr<ArithmeticAssignmentNode> assignment(
00461 ArithmeticAssignmentNode::fromArithmeticAssignmentToken(
00462 pos,
00463 op,
00464 lValue.release(),
00465 parseBinaryOrExpression()));
00466
00467 return assignment.release();
00468 }
00469 else
00470 throw TranslatableError(tokens.front().pos, ERROR_EXPECTING_ASSIGNMENT).arg(tokens.front().toWString());
00471
00472 return NULL;
00473 }
00474
00476 Node* Compiler::parseIfWhen(bool edgeSensitive)
00477 {
00478 const Token::Type elseEndTypes[] = { Token::TOKEN_STR_else, Token::TOKEN_STR_elseif, Token::TOKEN_STR_end };
00479
00480 std::auto_ptr<IfWhenNode> ifNode(new IfWhenNode(tokens.front().pos));
00481
00482
00483 ifNode->edgeSensitive = edgeSensitive;
00484 tokens.pop_front();
00485
00486
00487 ifNode->children.push_back(parseOr());
00488
00489
00490 if (edgeSensitive)
00491 expect(Token::TOKEN_STR_do);
00492 else
00493 expect(Token::TOKEN_STR_then);
00494 tokens.pop_front();
00495
00496
00497 ifNode->children.push_back(new BlockNode(tokens.front().pos));
00498 while (!IS_ONE_OF(elseEndTypes))
00499 ifNode->children[1]->children.push_back(parseBlockStatement());
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 if (!edgeSensitive)
00513 {
00514 if (tokens.front() == Token::TOKEN_STR_else)
00515 {
00516 tokens.pop_front();
00517
00518 ifNode->children.push_back(new BlockNode(tokens.front().pos));
00519 while (tokens.front() != Token::TOKEN_STR_end)
00520 ifNode->children[2]->children.push_back(parseBlockStatement());
00521 }
00522
00523 if (tokens.front() == Token::TOKEN_STR_elseif)
00524 {
00525 ifNode->children.push_back(parseIfWhen(false));
00526 return ifNode.release();
00527 }
00528 }
00529
00530
00531 ifNode->endLine = tokens.front().pos.row;
00532 expect(Token::TOKEN_STR_end);
00533 tokens.pop_front();
00534
00535 return ifNode.release();
00536 }
00537
00539 Node* Compiler::parseFor()
00540 {
00541
00542 SourcePos whilePos = tokens.front().pos;
00543 tokens.pop_front();
00544
00545
00546 std::auto_ptr<MemoryVectorNode> variable(parseVariable());
00547 MemoryVectorNode* variableRef = variable.get();
00548 SourcePos varPos = variable->sourcePos;
00549
00550
00551 expect(Token::TOKEN_STR_in);
00552 tokens.pop_front();
00553
00554
00555 int rangeStartIndex = expectInt16LiteralOrConstant();
00556 SourcePos rangeStartIndexPos = tokens.front().pos;
00557 tokens.pop_front();
00558
00559
00560 expect(Token::TOKEN_COLON);
00561 tokens.pop_front();
00562
00563
00564 int rangeEndIndex = expectInt16LiteralOrConstant();
00565 SourcePos rangeEndIndexPos = tokens.front().pos;
00566 tokens.pop_front();
00567
00568
00569 int step = 1;
00570 if (tokens.front() == Token::TOKEN_STR_step)
00571 {
00572 tokens.pop_front();
00573 step = expectInt16LiteralOrConstant();
00574 if (step == 0)
00575 throw TranslatableError(tokens.front().pos, ERROR_FOR_NULL_STEPS);
00576 tokens.pop_front();
00577 }
00578
00579
00580 if (step > 0)
00581 {
00582 if (rangeStartIndex > rangeEndIndex)
00583 throw TranslatableError(rangeStartIndexPos, ERROR_FOR_START_HIGHER_THAN_END);
00584 }
00585 else
00586 {
00587 if (rangeStartIndex < rangeEndIndex)
00588 throw TranslatableError(rangeStartIndexPos, ERROR_FOR_START_LOWER_THAN_END);
00589 }
00590
00591
00592 expect(Token::TOKEN_STR_do);
00593 tokens.pop_front();
00594
00595
00596 std::auto_ptr<BlockNode> blockNode(new BlockNode(whilePos));
00597 std::auto_ptr<AssignmentNode> assignment(new AssignmentNode(rangeStartIndexPos));
00598 assignment->children.push_back(variable.release());
00599 assignment->children.push_back(new TupleVectorNode(rangeStartIndexPos, rangeStartIndex));
00600 blockNode->children.push_back(assignment.release());
00601
00602
00603 WhileNode* whileNode = new WhileNode(whilePos);
00604 blockNode->children.push_back(whileNode);
00605 BinaryArithmeticNode* comparisonNode = new BinaryArithmeticNode(whilePos);
00606 comparisonNode->children.push_back(variableRef->deepCopy());
00607 if (rangeStartIndex <= rangeEndIndex)
00608 comparisonNode->op = ASEBA_OP_SMALLER_EQUAL_THAN;
00609 else
00610 comparisonNode->op = ASEBA_OP_BIGGER_EQUAL_THAN;
00611 comparisonNode->children.push_back(new TupleVectorNode(rangeEndIndexPos, rangeEndIndex));
00612 whileNode->children.push_back(comparisonNode);
00613
00614
00615 whileNode->children.push_back(new BlockNode(tokens.front().pos));
00616 while (tokens.front() != Token::TOKEN_STR_end)
00617 whileNode->children[1]->children.push_back(parseBlockStatement());
00618
00619
00620 AssignmentNode* assignmentNode = new AssignmentNode(varPos);
00621 whileNode->children[1]->children.push_back(assignmentNode);
00622 assignmentNode->children.push_back(variableRef->deepCopy());
00623 assignmentNode->children.push_back(new BinaryArithmeticNode(varPos, ASEBA_OP_ADD, variableRef->deepCopy(), new TupleVectorNode(varPos, step)));
00624
00625 tokens.pop_front();
00626
00627 return blockNode.release();
00628 }
00629
00631 Node* Compiler::parseWhile()
00632 {
00633 std::auto_ptr<WhileNode> whileNode(new WhileNode(tokens.front().pos));
00634
00635
00636 tokens.pop_front();
00637
00638
00639 whileNode->children.push_back(parseOr());
00640
00641
00642 expect(Token::TOKEN_STR_do);
00643 tokens.pop_front();
00644
00645
00646 whileNode->children.push_back(new BlockNode(tokens.front().pos));
00647 while (tokens.front() != Token::TOKEN_STR_end)
00648 whileNode->children[1]->children.push_back(parseBlockStatement());
00649
00650 tokens.pop_front();
00651
00652 return whileNode.release();
00653 }
00654
00656 Node* Compiler::parseOnEvent()
00657 {
00658 SourcePos pos = tokens.front().pos;
00659 tokens.pop_front();
00660
00661 const unsigned eventId = expectAnyEventId();
00662 if (implementedEvents.find(eventId) != implementedEvents.end())
00663 throw TranslatableError(tokens.front().pos, ERROR_EVENT_ALREADY_IMPL).arg(eventName(eventId));
00664 implementedEvents.insert(eventId);
00665
00666 tokens.pop_front();
00667
00668 return new EventDeclNode(pos, eventId);
00669 }
00670
00672 Node* Compiler::parseEmit()
00673 {
00674 SourcePos pos = tokens.front().pos;
00675 tokens.pop_front();
00676
00677 std::auto_ptr<EmitNode> emitNode(new EmitNode(pos));
00678
00679
00680 emitNode->eventId = expectGlobalEventId();
00681 tokens.pop_front();
00682
00683
00684 unsigned eventSize = commonDefinitions->events[emitNode->eventId].value;
00685 if (eventSize > 0)
00686 {
00687 std::auto_ptr<Node> preNode(parseBinaryOrExpression());
00688
00689
00690 if (!dynamic_cast<MemoryVectorNode*>(preNode.get()) || preNode->getVectorAddr() == Node::E_NOVAL)
00691 {
00692 preNode.reset(allocateTemporaryVariable(pos, preNode.release()));
00693 }
00694
00695
00696 emitNode->arrayAddr = preNode->getVectorAddr();
00697 emitNode->arraySize = preNode->getVectorSize();
00698 emitNode->children.push_back(preNode.release());
00699
00700 if (emitNode->arraySize != eventSize)
00701 throw TranslatableError(pos, ERROR_EVENT_WRONG_ARG_SIZE).arg(commonDefinitions->events[emitNode->eventId].name).arg(eventSize).arg(emitNode->arraySize);
00702 }
00703 else
00704 {
00705 emitNode->arrayAddr = 0;
00706 emitNode->arraySize = 0;
00707 }
00708
00709 return emitNode.release();
00710 }
00711
00713 Node* Compiler::parseSubDecl()
00714 {
00715 const SourcePos pos = tokens.front().pos;
00716 tokens.pop_front();
00717
00718 expect(Token::TOKEN_STRING_LITERAL);
00719
00720 const std::wstring& name = tokens.front().sValue;
00721 const SubroutineReverseTable::const_iterator it = subroutineReverseTable.find(name);
00722 if (it != subroutineReverseTable.end())
00723 throw TranslatableError(tokens.front().pos, ERROR_SUBROUTINE_ALREADY_DEF).arg(name);
00724
00725 const unsigned subroutineId = subroutineTable.size();
00726 subroutineTable.push_back(SubroutineDescriptor(name, 0, pos.row));
00727 subroutineReverseTable[name] = subroutineId;
00728
00729 tokens.pop_front();
00730
00731 return new SubDeclNode(pos, subroutineId);
00732 }
00733
00735 Node* Compiler::parseCallSub()
00736 {
00737 const SourcePos pos = tokens.front().pos;
00738 tokens.pop_front();
00739
00740 expect(Token::TOKEN_STRING_LITERAL);
00741
00742 const std::wstring& name = tokens.front().sValue;
00743 const SubroutineReverseTable::const_iterator it(findSubroutine(name, pos));
00744
00745 tokens.pop_front();
00746
00747 return new CallSubNode(pos, it->second);
00748 }
00749
00751 Node* Compiler::parseOr()
00752 {
00753 std::auto_ptr<Node> node(parseAnd());
00754
00755 while (tokens.front() == Token::TOKEN_OP_OR)
00756 {
00757 SourcePos pos = tokens.front().pos;
00758 tokens.pop_front();
00759 Node *subExpression = parseAnd();
00760 node.reset(new BinaryArithmeticNode(pos, ASEBA_OP_OR, node.release(), subExpression));
00761 }
00762
00763 return node.release();
00764 }
00765
00767 Node* Compiler::parseAnd()
00768 {
00769 std::auto_ptr<Node> node(parseNot());
00770
00771 while (tokens.front() == Token::TOKEN_OP_AND)
00772 {
00773 SourcePos pos = tokens.front().pos;
00774 tokens.pop_front();
00775 Node *subExpression = parseNot();
00776 node.reset(new BinaryArithmeticNode(pos, ASEBA_OP_AND, node.release(), subExpression));
00777 }
00778
00779 return node.release();
00780 }
00781
00783 Node* Compiler::parseNot()
00784 {
00785 SourcePos pos = tokens.front().pos;
00786
00787
00788 bool odd = false;
00789 while (tokens.front() == Token::TOKEN_OP_NOT)
00790 {
00791 odd = !odd;
00792 tokens.pop_front();
00793 }
00794
00795 if (odd)
00796 return new UnaryArithmeticNode(pos, ASEBA_UNARY_OP_NOT, parseCondition());
00797 else
00798 return parseCondition();
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 }
00824
00826 Node* Compiler::parseCondition()
00827 {
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 const Token::Type conditionTypes[] = { Token::TOKEN_OP_EQUAL, Token::TOKEN_OP_NOT_EQUAL, Token::TOKEN_OP_BIGGER, Token::TOKEN_OP_BIGGER_EQUAL, Token::TOKEN_OP_SMALLER, Token::TOKEN_OP_SMALLER_EQUAL };
00841
00842 std::auto_ptr<Node> node(parseBinaryOrExpression());
00843
00844 while (IS_ONE_OF(conditionTypes))
00845 {
00846 Token::Type op = tokens.front();
00847 SourcePos pos = tokens.front().pos;
00848 tokens.pop_front();
00849 Node *subExpression = parseBinaryOrExpression();
00850 node.reset(BinaryArithmeticNode::fromComparison(pos, op, node.release(), subExpression));
00851 }
00852
00853 return node.release();
00854 }
00855
00857 Node *Compiler::parseBinaryOrExpression()
00858 {
00859 std::auto_ptr<Node> node(parseBinaryXorExpression());
00860
00861 while (tokens.front() == Token::TOKEN_OP_BIT_OR)
00862 {
00863 SourcePos pos = tokens.front().pos;
00864 tokens.pop_front();
00865 Node *subExpression = parseBinaryXorExpression();
00866 node.reset(new BinaryArithmeticNode(pos, ASEBA_OP_BIT_OR, node.release(), subExpression));
00867 }
00868
00869 return node.release();
00870 }
00871
00873 Node *Compiler::parseBinaryXorExpression()
00874 {
00875 std::auto_ptr<Node> node(parseBinaryAndExpression());
00876
00877 while (tokens.front() == Token::TOKEN_OP_BIT_XOR)
00878 {
00879 SourcePos pos = tokens.front().pos;
00880 tokens.pop_front();
00881 Node *subExpression = parseBinaryAndExpression();
00882 node.reset(new BinaryArithmeticNode(pos, ASEBA_OP_BIT_XOR, node.release(), subExpression));
00883 }
00884
00885 return node.release();
00886 }
00887
00889 Node *Compiler::parseBinaryAndExpression()
00890 {
00891 std::auto_ptr<Node> node(parseShiftExpression());
00892
00893 while (tokens.front() == Token::TOKEN_OP_BIT_AND)
00894 {
00895 SourcePos pos = tokens.front().pos;
00896 tokens.pop_front();
00897 Node *subExpression = parseShiftExpression();
00898 node.reset(new BinaryArithmeticNode(pos, ASEBA_OP_BIT_AND, node.release(), subExpression));
00899 }
00900
00901 return node.release();
00902 }
00903
00905 Node *Compiler::parseShiftExpression()
00906 {
00907 const Token::Type opTypes[] = { Token::TOKEN_OP_SHIFT_LEFT, Token::TOKEN_OP_SHIFT_RIGHT };
00908
00909 std::auto_ptr<Node> node(parseAddExpression());
00910
00911 while (IS_ONE_OF(opTypes))
00912 {
00913 Token::Type op = tokens.front();
00914 SourcePos pos = tokens.front().pos;
00915 tokens.pop_front();
00916 Node *subExpression = parseAddExpression();
00917 node.reset(BinaryArithmeticNode::fromShiftExpression(pos, op, node.release(), subExpression));
00918 }
00919
00920 return node.release();
00921 }
00922
00924 Node *Compiler::parseAddExpression()
00925 {
00926 const Token::Type opTypes[] = { Token::TOKEN_OP_ADD, Token::TOKEN_OP_NEG };
00927
00928 std::auto_ptr<Node> node(parseMultExpression());
00929
00930 while (IS_ONE_OF(opTypes))
00931 {
00932 Token::Type op = tokens.front();
00933 SourcePos pos = tokens.front().pos;
00934 tokens.pop_front();
00935 Node *subExpression = parseMultExpression();
00936 node.reset(BinaryArithmeticNode::fromAddExpression(pos, op, node.release(), subExpression));
00937 }
00938
00939 return node.release();
00940 }
00941
00943 Node *Compiler::parseMultExpression()
00944 {
00945 const Token::Type opTypes[] = { Token::TOKEN_OP_MULT, Token::TOKEN_OP_DIV, Token::TOKEN_OP_MOD };
00946
00947 std::auto_ptr<Node> node(parseUnaryExpression());
00948
00949 while (IS_ONE_OF(opTypes))
00950 {
00951 Token::Type op = tokens.front();
00952 SourcePos pos = tokens.front().pos;
00953 tokens.pop_front();
00954 Node *subExpression = parseUnaryExpression();
00955 node.reset(BinaryArithmeticNode::fromMultExpression(pos, op, node.release(), subExpression));
00956 }
00957
00958 return node.release();
00959 }
00960
00962 Node *Compiler::parseUnaryExpression()
00963 {
00964 const Token::Type acceptableTypes[] = { Token::TOKEN_PAR_OPEN, Token::TOKEN_BRACKET_OPEN, Token::TOKEN_OP_NEG, Token::TOKEN_OP_BIT_NOT, Token::TOKEN_STR_abs, Token::TOKEN_STRING_LITERAL, Token::TOKEN_INT_LITERAL };
00965
00966 EXPECT_ONE_OF(acceptableTypes);
00967 SourcePos pos = tokens.front().pos;
00968
00969 switch (tokens.front())
00970 {
00971 case Token::TOKEN_PAR_OPEN:
00972 {
00973 tokens.pop_front();
00974
00975 std::auto_ptr<Node> expression(parseOr());
00976
00977 expect(Token::TOKEN_PAR_CLOSE);
00978 tokens.pop_front();
00979
00980 return expression.release();
00981 }
00982
00983 case Token::TOKEN_BRACKET_OPEN:
00984 {
00985 return parseTupleVector();
00986 }
00987
00988 case Token::TOKEN_OP_NEG:
00989 {
00990 tokens.pop_front();
00991
00992 return new UnaryArithmeticNode(pos, ASEBA_UNARY_OP_SUB, parseUnaryExpression());
00993 }
00994
00995 case Token::TOKEN_OP_BIT_NOT:
00996 {
00997 tokens.pop_front();
00998
00999 return new UnaryArithmeticNode(pos, ASEBA_UNARY_OP_BIT_NOT, parseUnaryExpression());
01000 };
01001
01002 case Token::TOKEN_STR_abs:
01003 {
01004 tokens.pop_front();
01005
01006 return new UnaryArithmeticNode(pos, ASEBA_UNARY_OP_ABS, parseUnaryExpression());
01007 }
01008
01009 case Token::TOKEN_INT_LITERAL:
01010 {
01011
01012 std::auto_ptr<TupleVectorNode> arrayCtor(new TupleVectorNode(pos, expectUInt16Literal()));
01013 tokens.pop_front();
01014 return arrayCtor.release();
01015 }
01016
01017 case Token::TOKEN_STRING_LITERAL:
01018 {
01019 return parseConstantAndVariable();
01020 }
01021
01022 default: internalCompilerError(); return NULL;
01023 }
01024 }
01025
01027 TupleVectorNode* Compiler::parseTupleVector(bool compatibility)
01028 {
01029 if (!compatibility)
01030 {
01031 expect(Token::TOKEN_BRACKET_OPEN);
01032 tokens.pop_front();
01033 }
01034 else
01035 {
01036
01037 if ( !(
01038 (tokens.size() >= 2 && tokens[1] == Token::TOKEN_COMMA) ||
01039 (tokens.size() >= 3 && tokens[0] == Token::TOKEN_OP_NEG && tokens[2] == Token::TOKEN_COMMA)
01040 )
01041 )
01042 {
01043
01044 return NULL;
01045 }
01046 }
01047
01048 SourcePos varPos = tokens.front().pos;
01049 std::auto_ptr<TupleVectorNode> arrayCtor(new TupleVectorNode(varPos));
01050
01051 do
01052 {
01053 if (tokens.front() == Token::TOKEN_BRACKET_OPEN)
01054 {
01055
01056 arrayCtor->children.push_back(parseTupleVector());
01057 }
01058 else
01059 {
01060 arrayCtor->children.push_back(parseBinaryOrExpression());
01061 }
01062
01063 if (tokens.front() != Token::TOKEN_COMMA)
01064 break;
01065 else
01066 tokens.pop_front();
01067 }
01068 while (1);
01069
01070 if (!compatibility)
01071 {
01072 expect(Token::TOKEN_BRACKET_CLOSE);
01073 tokens.pop_front();
01074 }
01075
01076 return arrayCtor.release();
01077 }
01078
01079 Node* Compiler::parseConstantAndVariable()
01080 {
01081 expect(Token::TOKEN_STRING_LITERAL);
01082 std::wstring varName = tokens.front().sValue;
01083 if (constantExists(varName))
01084 {
01085 std::auto_ptr<TupleVectorNode> arrayCtor(new TupleVectorNode(tokens.front().pos));
01086 arrayCtor->addImmediateValue(expectConstant());
01087 tokens.pop_front();
01088 return arrayCtor.release();
01089 }
01090 else
01091 {
01092 return parseVariable();
01093 }
01094 }
01095
01096 MemoryVectorNode* Compiler::parseVariable()
01097 {
01098 expect(Token::TOKEN_STRING_LITERAL);
01099 std::wstring varName = tokens.front().sValue;
01100 SourcePos varPos = tokens.front().pos;
01101 VariablesMap::const_iterator varIt(findVariable(varName, varPos));
01102
01103 std::auto_ptr<MemoryVectorNode> vector(
01104 new MemoryVectorNode(
01105 varPos,
01106 varIt->second.first,
01107 varIt->second.second,
01108 varName));
01109
01110
01111 tokens.pop_front();
01112 if (tokens.front() == Token::TOKEN_BRACKET_OPEN)
01113 {
01114 SourcePos pos = tokens.front().pos;
01115 tokens.pop_front();
01116
01117 int start;
01118 std::auto_ptr<Node> startIndex(tryParsingConstantExpression(pos, start));
01119
01120 if (startIndex.get() == NULL)
01121 {
01122
01123 std::auto_ptr<TupleVectorNode> index(new TupleVectorNode(pos));
01124 index->addImmediateValue(start);
01125
01126
01127 if (tokens.front() == Token::TOKEN_COLON)
01128 {
01129 pos = tokens.front().pos;
01130 tokens.pop_front();
01131
01132 int end;
01133 std::auto_ptr<Node> endIndex(tryParsingConstantExpression(pos, end));
01134
01135 if (endIndex.get() != NULL)
01136 throw TranslatableError(pos, ERROR_INDEX_EXPECTING_CONSTANT);
01137
01138
01139 if (end < start)
01140 throw TranslatableError(tokens.front().pos, ERROR_INDEX_WRONG_END);
01141
01142 index->addImmediateValue(end);
01143 }
01144
01145 vector->children.push_back(index.release());
01146 }
01147 else
01148 {
01149
01150 vector->children.push_back(startIndex.release());
01151 }
01152
01153 expect(Token::TOKEN_BRACKET_CLOSE);
01154 tokens.pop_front();
01155 }
01156
01157 return vector.release();
01158 }
01159
01160 unsigned Compiler::parseVariableDefSize()
01161 {
01162 unsigned result = 0;
01163
01164 if (tokens.front() == Token::TOKEN_BRACKET_OPEN)
01165 {
01166 SourcePos pos = tokens.front().pos;
01167 tokens.pop_front();
01168
01169 if (tokens.front() == Token::TOKEN_BRACKET_CLOSE)
01170 {
01171 result = Node::E_NOVAL;
01172 }
01173 else
01174 {
01175 result = expectConstantExpression(pos, parseBinaryOrExpression());
01176
01177 if (result < 0)
01178
01179 throw TranslatableError(pos, ERROR_SIZE_IS_NEGATIVE).arg(result);
01180 else if (result == 0)
01181 throw TranslatableError(pos, ERROR_SIZE_IS_NULL);
01182
01183 expect(Token::TOKEN_BRACKET_CLOSE);
01184 }
01185 tokens.pop_front();
01186 }
01187 else
01188
01189 result = 1;
01190
01191 return result;
01192 }
01193
01197 Node* Compiler::tryParsingConstantExpression(SourcePos pos, int& constantResult)
01198 {
01199 std::auto_ptr<Node> tree(parseBinaryOrExpression());
01200
01201 try
01202 {
01203 constantResult = expectConstantExpression(pos, tree->deepCopy());
01204 tree.reset();
01205 return NULL;
01206 }
01207 catch (TranslatableError error)
01208 {
01209
01210 return tree.release();
01211 }
01212 }
01213
01217 int Compiler::expectConstantExpression(SourcePos pos, Node* tree)
01218 {
01219 int result = 0;
01220
01221
01222
01223 std::auto_ptr<Node> tempTree1(new AssignmentNode(pos));
01224 tempTree1->children.push_back(new MemoryVectorNode(pos, 0, 1, L"fake"));
01225 tempTree1->children.push_back(tree);
01226
01227
01228
01229
01230
01231
01232
01233 std::auto_ptr<Node> tempTree2(tempTree1->expandToAsebaTree(NULL));
01234
01235
01236
01237
01238 tempTree1.release();
01239 tempTree2->optimize(NULL);
01240
01241
01242
01243
01244
01245
01246 if ( !tempTree2.get() || tempTree2->children.size() == 0 )
01247 throw TranslatableError(pos, ERROR_NOT_CONST_EXPR);
01248 AssignmentNode* assignment = dynamic_cast<AssignmentNode*>(tempTree2->children[0]);
01249 if ( !assignment || assignment->children.size() != 2 )
01250 throw TranslatableError(pos, ERROR_NOT_CONST_EXPR);
01251
01252
01253 ImmediateNode* immediate = dynamic_cast<ImmediateNode*>(assignment->children[1]);
01254 if (immediate)
01255 result = immediate->value;
01256 else
01257 throw TranslatableError(pos, ERROR_NOT_CONST_EXPR);
01258
01259
01260 tempTree2.reset();
01261
01262 return result;
01263 }
01264
01266 Node* Compiler::parseFunctionCall()
01267 {
01268 SourcePos pos = tokens.front().pos;
01269 tokens.pop_front();
01270
01271 expect(Token::TOKEN_STRING_LITERAL);
01272
01273 std::wstring funcName = tokens.front().sValue;
01274 FunctionsMap::const_iterator funcIt(findFunction(funcName, pos));
01275
01276 const TargetDescription::NativeFunction &function = targetDescription->nativeFunctions[funcIt->second];
01277 std::auto_ptr<CallNode> callNode(new CallNode(pos, funcIt->second));
01278
01279 tokens.pop_front();
01280
01281 expect(Token::TOKEN_PAR_OPEN);
01282 tokens.pop_front();
01283
01284 if (function.parameters.size() == 0)
01285 {
01286 if (tokens.front() != Token::TOKEN_PAR_CLOSE)
01287 throw TranslatableError(tokens.front().pos, ERROR_FUNCTION_HAS_NO_ARG).arg(funcName);
01288 tokens.pop_front();
01289 }
01290 else
01291 {
01292
01293 int minTemplateId = 0;
01294 for (unsigned i = 0; i < function.parameters.size(); i++)
01295 minTemplateId = std::min(function.parameters[i].size, minTemplateId);
01296 std::valarray<int> templateParameters(-1, -minTemplateId);
01297
01298
01299 for (unsigned i = 0; i < function.parameters.size(); i++)
01300 {
01301
01302 if (tokens.front() == Token::TOKEN_PAR_CLOSE)
01303 throw TranslatableError(tokens.front().pos, ERROR_FUNCTION_NO_ENOUGH_ARG).arg(funcName).arg((unsigned int)function.parameters.size()).arg(i);
01304
01305
01306 unsigned varAddr;
01307 unsigned varSize;
01308 SourcePos varPos = tokens.front().pos;
01309
01310 std::auto_ptr<Node> preNode(parseBinaryOrExpression());
01311
01312 varAddr = preNode->getVectorAddr();
01313 varSize = preNode->getVectorSize();
01314
01315
01316 if (!dynamic_cast<MemoryVectorNode*>(preNode.get()) || varAddr == Node::E_NOVAL)
01317 {
01318 preNode.reset(allocateTemporaryVariable(pos, preNode.release()));
01319 varAddr = preNode->getVectorAddr();
01320 callNode->children.push_back(preNode.release());
01321 }
01322
01323
01324 if (function.parameters[i].size > 0)
01325 {
01326 if (varSize != (unsigned)function.parameters[i].size)
01327 throw TranslatableError(varPos, ERROR_FUNCTION_WRONG_ARG_SIZE).arg(i).arg(function.parameters[i].name).arg(funcName).arg(varSize).arg(function.parameters[i].size);
01328 }
01329 else if (function.parameters[i].size < 0)
01330 {
01331 int templateIndex = -function.parameters[i].size - 1;
01332 if (templateParameters[templateIndex] < 0)
01333 {
01334
01335 templateParameters[templateIndex] = varSize;
01336 }
01337 else if ((unsigned)templateParameters[templateIndex] != varSize)
01338 {
01339 throw TranslatableError(varPos, ERROR_FUNCTION_WRONG_ARG_SIZE_TEMPLATE).arg(i).arg(function.parameters[i].name).arg(funcName).arg(varSize).arg(templateParameters[templateIndex]);
01340 }
01341 }
01342 else
01343 {
01344
01345 callNode->argumentsAddr.push_back(varSize);
01346 }
01347
01348
01349 callNode->argumentsAddr.push_back(varAddr);
01350
01351
01352 if (i + 1 == function.parameters.size())
01353 {
01354 if (tokens.front() == Token::TOKEN_COMMA)
01355 throw TranslatableError(tokens.front().pos, ERROR_FUNCTION_TOO_MANY_ARG).arg(funcName).arg((unsigned int)function.parameters.size());
01356 else
01357 expect(Token::TOKEN_PAR_CLOSE);
01358 }
01359 else
01360 {
01361 if (tokens.front() == Token::TOKEN_PAR_CLOSE)
01362 throw TranslatableError(tokens.front().pos, ERROR_FUNCTION_NO_ENOUGH_ARG).arg(funcName).arg((unsigned int)function.parameters.size()).arg(i + 1);
01363 else
01364 expect(Token::TOKEN_COMMA);
01365 }
01366 tokens.pop_front();
01367 }
01368
01369
01370 for (unsigned i = 0; i < templateParameters.size(); i++)
01371 if (templateParameters[i] >= 0)
01372 callNode->argumentsAddr.push_back(templateParameters[i]);
01373 }
01374
01375
01376 return callNode.release();
01377 }
01378 };