00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "compiler.h"
00025 #include "tree.h"
00026 #include "../utils/FormatableString.h"
00027 #include <memory>
00028 #include <valarray>
00029 #include <iostream>
00030 #include <cassert>
00031
00032 #define IS_ONE_OF(array) (isOneOf<sizeof(array)/sizeof(Token::Type)>(array))
00033 #define EXPECT_ONE_OF(array) (expectOneOf<sizeof(array)/sizeof(Token::Type)>(array))
00034
00035
00036 template<typename Derived, typename Base>
00037 static inline Derived polymorphic_downcast(Base base)
00038 {
00039 Derived derived = dynamic_cast<Derived>(base);
00040 if (!derived)
00041 abort();
00042 return derived;
00043 }
00044
00045 namespace Aseba
00046 {
00048 void Compiler::internalCompilerError() const
00049 {
00050 throw Error(tokens.front().pos, "Internal compiler error, please report a bug containing the source which triggered this error");
00051 }
00052
00054 void Compiler::expect(const Token::Type& type) const
00055 {
00056 if (tokens.front() != type)
00057 throw Error(tokens.front().pos,
00058 FormatableString("Expecting %0, found %1 instead")
00059 .arg(Token(type).typeName())
00060 .arg(tokens.front().typeName())
00061 );
00062 }
00063
00065 unsigned Compiler::expectUInt12Literal() const
00066 {
00067 expect(Token::TOKEN_INT_LITERAL);
00068 if (tokens.front().iValue < 0 || tokens.front().iValue > 4095)
00069 throw Error(tokens.front().pos,
00070 FormatableString("Integer value %0 out of [0;4095] range")
00071 .arg(tokens.front().iValue)
00072 );
00073 return tokens.front().iValue;
00074 }
00075
00077 unsigned Compiler::expectUInt16Literal() const
00078 {
00079 expect(Token::TOKEN_INT_LITERAL);
00080 if (tokens.front().iValue < 0 || tokens.front().iValue > 65535)
00081 throw Error(tokens.front().pos,
00082 FormatableString("Integer value %0 out of [0;65535] range")
00083 .arg(tokens.front().iValue)
00084 );
00085 return tokens.front().iValue;
00086 }
00087
00089 unsigned Compiler::expectPositiveInt16Literal() const
00090 {
00091 expect(Token::TOKEN_INT_LITERAL);
00092 if (tokens.front().iValue < 0 || tokens.front().iValue > 32767)
00093 throw Error(tokens.front().pos,
00094 FormatableString("Integer value %0 out of [0;32767] range")
00095 .arg(tokens.front().iValue)
00096 );
00097 return tokens.front().iValue;
00098 }
00099
00101 int Compiler::expectAbsoluteInt16Literal(bool negative) const
00102 {
00103 expect(Token::TOKEN_INT_LITERAL);
00104 int limit(32767);
00105 if (negative)
00106 limit++;
00107 if (tokens.front().iValue < 0 || tokens.front().iValue > limit)
00108 throw Error(tokens.front().pos,
00109 FormatableString("Integer value %0 out of [-32768;32767] range")
00110 .arg(tokens.front().iValue)
00111 );
00112 return tokens.front().iValue;
00113 }
00114
00116 unsigned Compiler::expectPositiveConstant() const
00117 {
00118 expect(Token::TOKEN_STRING_LITERAL);
00119 for (size_t i = 0; i < commonDefinitions->constants.size(); ++i)
00120 {
00121 if (commonDefinitions->constants[i].name == tokens.front().sValue)
00122 {
00123 int value = commonDefinitions->constants[i].value;
00124 if (value < 0 || value > 32767)
00125 throw Error(tokens.front().pos,
00126 FormatableString("Constant %0 has value %1, which is out of [0;32767] range")
00127 .arg(tokens.front().sValue)
00128 .arg(value)
00129 );
00130 return value;
00131 }
00132 }
00133
00134 throw Error(tokens.front().pos, FormatableString("Constant %0 not defined").arg(tokens.front().sValue));
00135
00136 return 0;
00137 }
00138
00140 int Compiler::expectConstant() const
00141 {
00142 expect(Token::TOKEN_STRING_LITERAL);
00143 for (size_t i = 0; i < commonDefinitions->constants.size(); ++i)
00144 {
00145 if (commonDefinitions->constants[i].name == tokens.front().sValue)
00146 {
00147 int value = commonDefinitions->constants[i].value;
00148 if (value < -32768 || value > 32767)
00149 throw Error(tokens.front().pos,
00150 FormatableString("Constant %0 has value %1, which is out of [-32768;32767] range")
00151 .arg(tokens.front().sValue)
00152 .arg(value)
00153 );
00154 return value;
00155 }
00156 }
00157
00158 throw Error(tokens.front().pos, FormatableString("Constant %0 not defined").arg(tokens.front().sValue));
00159
00160 return 0;
00161 }
00162
00164 unsigned Compiler::expectPositiveInt16LiteralOrConstant() const
00165 {
00166 if (tokens.front() == Token::TOKEN_INT_LITERAL)
00167 return expectPositiveInt16Literal();
00168 else
00169 return expectPositiveConstant();
00170 }
00171
00173 int Compiler::expectInt16LiteralOrConstant()
00174 {
00175 if (tokens.front() == Token::TOKEN_OP_NEG)
00176 {
00177 tokens.pop_front();
00178 return -expectAbsoluteInt16Literal(true);
00179 }
00180 else if (tokens.front() == Token::TOKEN_INT_LITERAL)
00181 {
00182 return expectAbsoluteInt16Literal(false);
00183 }
00184 else
00185 return expectConstant();
00186 }
00187
00189 unsigned Compiler::expectGlobalEventId() const
00190 {
00191 assert(commonDefinitions);
00192
00193 expect(Token::TOKEN_STRING_LITERAL);
00194
00195 const std::string & eventName = tokens.front().sValue;
00196 for (size_t i = 0; i < commonDefinitions->events.size(); ++i)
00197 if (commonDefinitions->events[i].name == eventName)
00198 {
00199 return i;
00200 }
00201
00202 throw Error(tokens.front().pos, FormatableString("%0 is not a known event").arg(eventName));
00203 }
00204
00206 unsigned Compiler::expectAnyEventId() const
00207 {
00208 assert(targetDescription);
00209
00210 expect(Token::TOKEN_STRING_LITERAL);
00211
00212
00213 const std::string & eventName = tokens.front().sValue;
00214 for (size_t i = 0; i < targetDescription->localEvents.size(); ++i)
00215 if (targetDescription->localEvents[i].name == eventName)
00216 {
00217 return ASEBA_EVENT_LOCAL_EVENTS_START - i;
00218 }
00219
00220
00221 return expectGlobalEventId();
00222 }
00223
00225 std::string Compiler::eventName(unsigned eventId) const
00226 {
00227
00228 if (eventId < commonDefinitions->events.size())
00229 return commonDefinitions->events[eventId].name;
00230
00231
00232 int localId = ASEBA_EVENT_LOCAL_EVENTS_START - eventId;
00233 if ((localId >= 0) && (localId < (int)targetDescription->localEvents.size()))
00234 return targetDescription->localEvents[localId].name;
00235
00236 return "unknown";
00237 }
00238
00240 template <int length>
00241 bool Compiler::isOneOf(const Token::Type types[length]) const
00242 {
00243 for (size_t i = 0; i < length; i++)
00244 {
00245 if (tokens.front() == types[i])
00246 return true;
00247 }
00248 return false;
00249 }
00250
00252 template <int length>
00253 void Compiler::expectOneOf(const Token::Type types[length]) const
00254 {
00255 if (!isOneOf<length>(types))
00256 {
00257 std::string errorMessage("Expecting one of ");
00258 for (size_t i = 0; i < length; i++)
00259 {
00260 errorMessage += Token(types[i]).typeName();
00261 if (i + 1 < length)
00262 errorMessage += ", ";
00263 }
00264 errorMessage += "; but found ";
00265 errorMessage += tokens.front().typeName();
00266 errorMessage += " instead";
00267 throw Error(tokens.front().pos, errorMessage);
00268 }
00269 }
00270
00272 Node* Compiler::parseProgram()
00273 {
00274 std::auto_ptr<ProgramNode> block(new ProgramNode(tokens.front().pos));
00275
00276 while (tokens.front() == Token::TOKEN_STR_var)
00277 {
00278
00279 Node *child = parseVarDef();
00280 if (child)
00281 block->children.push_back(child);
00282 }
00283
00284 while (tokens.front() != Token::TOKEN_END_OF_STREAM)
00285 {
00286
00287 Node *child = parseStatement();
00288 assert(child);
00289 block->children.push_back(child);
00290 }
00291 return block.release();
00292 }
00293
00295 Node* Compiler::parseStatement()
00296 {
00297 switch (tokens.front())
00298 {
00299 case Token::TOKEN_STR_var: throw Error(tokens.front().pos, "Variable definition is allowed only at the beginning of the program before any statement");
00300 case Token::TOKEN_STR_onevent: return parseOnEvent();
00301 case Token::TOKEN_STR_sub: return parseSubDecl();
00302 default: return parseBlockStatement();
00303 }
00304 }
00305
00307 Node* Compiler::parseBlockStatement()
00308 {
00309 switch (tokens.front())
00310 {
00311 case Token::TOKEN_STR_if: return parseIfWhen(false);
00312 case Token::TOKEN_STR_when: return parseIfWhen(true);
00313 case Token::TOKEN_STR_for: return parseFor();
00314 case Token::TOKEN_STR_while: return parseWhile();
00315 case Token::TOKEN_STR_emit: return parseEmit();
00316 case Token::TOKEN_STR_call: return parseFunctionCall();
00317 case Token::TOKEN_STR_callsub: return parseCallSub();
00318 default: return parseAssignment();
00319 }
00320 }
00321
00323 Node* Compiler::parseVarDef()
00324 {
00325 tokens.pop_front();
00326
00327
00328 if (tokens.front() != Token::TOKEN_STRING_LITERAL)
00329 throw Error(tokens.front().pos,
00330 FormatableString("Expecting identifier, found %0").arg(tokens.front().toString()));
00331
00332
00333 std::string varName = tokens.front().sValue;
00334 SourcePos varPos = tokens.front().pos;
00335 unsigned varSize = 1;
00336 unsigned varAddr = freeVariableIndex;
00337
00338 tokens.pop_front();
00339
00340
00341 if (tokens.front() == Token::TOKEN_BRACKET_OPEN)
00342 {
00343 tokens.pop_front();
00344
00345 varSize = expectPositiveInt16LiteralOrConstant();
00346 tokens.pop_front();
00347
00348 expect(Token::TOKEN_BRACKET_CLOSE);
00349 tokens.pop_front();
00350 }
00351
00352
00353 if (variablesMap.find(varName) != variablesMap.end())
00354 throw Error(varPos, FormatableString("Variable %0 is already defined").arg(varName));
00355
00356
00357 variablesMap[varName] = std::make_pair(varAddr, varSize);
00358 freeVariableIndex += varSize;
00359
00360
00361 if (freeVariableIndex > targetDescription->variablesSize)
00362 throw Error(varPos, "No more free variable space");
00363
00364
00365 if (tokens.front() == Token::TOKEN_ASSIGN)
00366 {
00367 std::auto_ptr<BlockNode> block(new BlockNode(tokens.front().pos));
00368
00369 tokens.pop_front();
00370
00371 for (unsigned i = 0; i < varSize; i++)
00372 {
00373 SourcePos assignPos = tokens.front().pos;
00374 block->children.push_back(parseBinaryOrExpression());
00375 block->children.push_back(new StoreNode(assignPos, varAddr + i));
00376
00377 if (i + 1 < varSize)
00378 {
00379 expect(Token::TOKEN_COMMA);
00380 tokens.pop_front();
00381 }
00382 }
00383
00384 return block.release();
00385 }
00386 else
00387 return NULL;
00388 }
00389
00391 Node* Compiler::parseAssignment()
00392 {
00393 expect(Token::TOKEN_STRING_LITERAL);
00394
00395 std::string varName = tokens.front().sValue;
00396 SourcePos varPos = tokens.front().pos;
00397 VariablesMap::const_iterator varIt = variablesMap.find(varName);
00398
00399
00400 if (varIt == variablesMap.end())
00401 throw Error(varPos, FormatableString("Variable %0 is not defined").arg(varName));
00402
00403 unsigned varAddr = varIt->second.first;
00404 unsigned varSize = varIt->second.second;
00405
00406 tokens.pop_front();
00407
00408 std::auto_ptr<AssignmentNode> assignement(new AssignmentNode(varPos));
00409
00410
00411 if (tokens.front() == Token::TOKEN_BRACKET_OPEN)
00412 {
00413 tokens.pop_front();
00414
00415 std::auto_ptr<Node> array(new ArrayWriteNode(tokens.front().pos, varAddr, varSize, varName));
00416
00417 array->children.push_back(parseBinaryOrExpression());
00418
00419 expect(Token::TOKEN_BRACKET_CLOSE);
00420 tokens.pop_front();
00421
00422 assignement->children.push_back(array.release());
00423 }
00424 else
00425 {
00426 if (varSize != 1)
00427 throw Error(varPos, FormatableString("Accessing variable %0 as a scalar, but is an array of size %1 instead").arg(varName).arg(varSize));
00428
00429 assignement->children.push_back(new StoreNode(tokens.front().pos, varAddr));
00430 }
00431
00432 expect(Token::TOKEN_ASSIGN);
00433 tokens.pop_front();
00434
00435 assignement->children.push_back(parseBinaryOrExpression());
00436
00437 return assignement.release();
00438 }
00439
00440
00442 Node* Compiler::parseIfWhen(bool edgeSensitive)
00443 {
00444 const Token::Type elseEndTypes[] = { Token::TOKEN_STR_else, Token::TOKEN_STR_elseif, Token::TOKEN_STR_end };
00445
00446 std::auto_ptr<IfWhenNode> ifNode(new IfWhenNode(tokens.front().pos));
00447
00448
00449 ifNode->edgeSensitive = edgeSensitive;
00450 tokens.pop_front();
00451
00452
00453 ifNode->children.push_back(parseOr());
00454
00455
00456 if (edgeSensitive)
00457 expect(Token::TOKEN_STR_do);
00458 else
00459 expect(Token::TOKEN_STR_then);
00460 tokens.pop_front();
00461
00462
00463 ifNode->children.push_back(new BlockNode(tokens.front().pos));
00464 while (!IS_ONE_OF(elseEndTypes))
00465 ifNode->children[1]->children.push_back(parseBlockStatement());
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 if (!edgeSensitive)
00479 {
00480 if (tokens.front() == Token::TOKEN_STR_else)
00481 {
00482 tokens.pop_front();
00483
00484 ifNode->children.push_back(new BlockNode(tokens.front().pos));
00485 while (tokens.front() != Token::TOKEN_STR_end)
00486 ifNode->children[2]->children.push_back(parseBlockStatement());
00487 }
00488
00489 if (tokens.front() == Token::TOKEN_STR_elseif)
00490 {
00491 ifNode->children.push_back(parseIfWhen(false));
00492 return ifNode.release();
00493 }
00494 }
00495
00496
00497 ifNode->endLine = tokens.front().pos.row;
00498 expect(Token::TOKEN_STR_end);
00499 tokens.pop_front();
00500
00501 return ifNode.release();
00502 }
00503
00505 Node* Compiler::parseFor()
00506 {
00507
00508 SourcePos whilePos = tokens.front().pos;
00509 tokens.pop_front();
00510
00511
00512 expect(Token::TOKEN_STRING_LITERAL);
00513 std::string varName = tokens.front().sValue;
00514 SourcePos varPos = tokens.front().pos;
00515 VariablesMap::const_iterator varIt = variablesMap.find(varName);
00516
00517
00518 if (varIt == variablesMap.end())
00519 throw Error(varPos, FormatableString("Variable %0 is not defined").arg(varName));
00520 unsigned varAddr = varIt->second.first;
00521 tokens.pop_front();
00522
00523
00524 expect(Token::TOKEN_STR_in);
00525 tokens.pop_front();
00526
00527
00528 int rangeStartIndex = expectInt16LiteralOrConstant();
00529 SourcePos rangeStartIndexPos = tokens.front().pos;
00530 tokens.pop_front();
00531
00532
00533 expect(Token::TOKEN_COLON);
00534 tokens.pop_front();
00535
00536
00537 int rangeEndIndex = expectInt16LiteralOrConstant();
00538 SourcePos rangeEndIndexPos = tokens.front().pos;
00539 tokens.pop_front();
00540
00541
00542 int step = 1;
00543 if (tokens.front() == Token::TOKEN_STR_step)
00544 {
00545 tokens.pop_front();
00546 step = expectInt16LiteralOrConstant();
00547 if (step == 0)
00548 throw Error(tokens.front().pos, "Null steps are not allowed in for loops");
00549 tokens.pop_front();
00550 }
00551
00552
00553 if (step > 0)
00554 {
00555 if (rangeStartIndex > rangeEndIndex)
00556 throw Error(rangeStartIndexPos, "Start index must be lower than end index in increasing loops");
00557 }
00558 else
00559 {
00560 if (rangeStartIndex < rangeEndIndex)
00561 throw Error(rangeStartIndexPos, "Start index must be higher than end index in decreasing loops");
00562 }
00563
00564
00565 expect(Token::TOKEN_STR_do);
00566 tokens.pop_front();
00567
00568
00569 std::auto_ptr<BlockNode> blockNode(new BlockNode(whilePos));
00570 blockNode->children.push_back(new ImmediateNode(rangeStartIndexPos, rangeStartIndex));
00571 blockNode->children.push_back(new StoreNode(varPos, varAddr));
00572
00573
00574 WhileNode* whileNode = new WhileNode(whilePos);
00575 blockNode->children.push_back(whileNode);
00576 BinaryArithmeticNode* comparisonNode = new BinaryArithmeticNode(whilePos);
00577 comparisonNode->children.push_back(new LoadNode(varPos, varAddr));
00578 if (rangeStartIndex <= rangeEndIndex)
00579 comparisonNode->op = ASEBA_OP_SMALLER_EQUAL_THAN;
00580 else
00581 comparisonNode->op = ASEBA_OP_BIGGER_EQUAL_THAN;
00582 comparisonNode->children.push_back(new ImmediateNode(rangeEndIndexPos, rangeEndIndex));
00583 whileNode->children.push_back(comparisonNode);
00584
00585
00586 whileNode->children.push_back(new BlockNode(tokens.front().pos));
00587 while (tokens.front() != Token::TOKEN_STR_end)
00588 whileNode->children[1]->children.push_back(parseBlockStatement());
00589
00590
00591 AssignmentNode* assignmentNode = new AssignmentNode(varPos);
00592 whileNode->children[1]->children.push_back(assignmentNode);
00593 assignmentNode->children.push_back(new StoreNode(varPos, varAddr));
00594 assignmentNode->children.push_back(new BinaryArithmeticNode(varPos, ASEBA_OP_ADD, new LoadNode(varPos, varAddr), new ImmediateNode(varPos, step)));
00595
00596 tokens.pop_front();
00597
00598 return blockNode.release();
00599 }
00600
00602 Node* Compiler::parseWhile()
00603 {
00604 std::auto_ptr<WhileNode> whileNode(new WhileNode(tokens.front().pos));
00605
00606
00607 tokens.pop_front();
00608
00609
00610 whileNode->children.push_back(parseOr());
00611
00612
00613 expect(Token::TOKEN_STR_do);
00614 tokens.pop_front();
00615
00616
00617 whileNode->children.push_back(new BlockNode(tokens.front().pos));
00618 while (tokens.front() != Token::TOKEN_STR_end)
00619 whileNode->children[1]->children.push_back(parseBlockStatement());
00620
00621 tokens.pop_front();
00622
00623 return whileNode.release();
00624 }
00625
00627 Node* Compiler::parseOnEvent()
00628 {
00629 SourcePos pos = tokens.front().pos;
00630 tokens.pop_front();
00631
00632 unsigned eventId = expectAnyEventId();
00633 if (implementedEvents.find(eventId) != implementedEvents.end())
00634 throw Error(tokens.front().pos, FormatableString("Event %0 is already implemented").arg(eventName(eventId)));
00635 implementedEvents.insert(eventId);
00636
00637 tokens.pop_front();
00638
00639 return new EventDeclNode(pos, eventId);
00640 }
00641
00643 Node* Compiler::parseEmit()
00644 {
00645 SourcePos pos = tokens.front().pos;
00646 tokens.pop_front();
00647
00648 std::auto_ptr<EmitNode> emitNode(new EmitNode(pos));
00649
00650
00651 emitNode->eventId = expectGlobalEventId();
00652 tokens.pop_front();
00653
00654
00655 unsigned eventSize = commonDefinitions->events[emitNode->eventId].value;
00656 if (eventSize > 0)
00657 {
00658 parseReadVarArrayAccess(&emitNode->arrayAddr, &emitNode->arraySize);
00659 if (emitNode->arraySize != eventSize)
00660 throw Error(pos, FormatableString("Event %0 needs an array of size %1, but one of size %2 is passed").arg(commonDefinitions->events[emitNode->eventId].name).arg(eventSize).arg(emitNode->arraySize));
00661 }
00662 else
00663 {
00664 emitNode->arrayAddr = 0;
00665 emitNode->arraySize = 0;
00666 }
00667
00668 return emitNode.release();
00669 }
00670
00672 Node* Compiler::parseSubDecl()
00673 {
00674 SourcePos pos = tokens.front().pos;
00675 tokens.pop_front();
00676
00677 expect(Token::TOKEN_STRING_LITERAL);
00678
00679 const std::string& name = tokens.front().sValue;
00680 SubroutineReverseTable::const_iterator it = subroutineReverseTable.find(name);
00681 if (it != subroutineReverseTable.end())
00682 throw Error(tokens.front().pos, FormatableString("Subroutine %0 is already defined").arg(name));
00683
00684 unsigned subroutineId = subroutineTable.size();
00685 subroutineTable.push_back(SubroutineDescriptor(name, 0, pos.row));
00686 subroutineReverseTable[name] = subroutineId;
00687
00688 tokens.pop_front();
00689
00690 return new SubDeclNode(pos, subroutineId);
00691 }
00692
00694 Node* Compiler::parseCallSub()
00695 {
00696 SourcePos pos = tokens.front().pos;
00697 tokens.pop_front();
00698
00699 expect(Token::TOKEN_STRING_LITERAL);
00700
00701 const std::string& name = tokens.front().sValue;
00702 SubroutineReverseTable::const_iterator it = subroutineReverseTable.find(name);
00703 if (it == subroutineReverseTable.end())
00704 throw Error(tokens.front().pos, FormatableString("Subroutine %0 does not exists").arg(name));
00705
00706 tokens.pop_front();
00707
00708 return new CallSubNode(pos, it->second);
00709 }
00710
00712 void Compiler::parseReadVarArrayAccess(unsigned* addr, unsigned* size)
00713 {
00714 expect(Token::TOKEN_STRING_LITERAL);
00715
00716
00717 SourcePos varPos = tokens.front().pos;
00718 std::string varName = tokens.front().sValue;
00719 VariablesMap::const_iterator varIt = variablesMap.find(varName);
00720 if (varIt == variablesMap.end())
00721 throw Error(varPos, FormatableString("%0 is not a defined variable").arg(varName));
00722
00723
00724 *addr = varIt->second.first;
00725
00726
00727 tokens.pop_front();
00728 if (tokens.front() == Token::TOKEN_BRACKET_OPEN)
00729 {
00730 tokens.pop_front();
00731
00732 int value = expectPositiveInt16LiteralOrConstant();
00733 unsigned startIndex = (unsigned)value;
00734 unsigned len = 1;
00735
00736
00737 if (startIndex >= varIt->second.second)
00738 throw Error(tokens.front().pos, FormatableString("access of array %0 out of bounds").arg(varName));
00739 tokens.pop_front();
00740
00741
00742 if (tokens.front() == Token::TOKEN_COLON)
00743 {
00744 tokens.pop_front();
00745
00746 value = expectPositiveInt16LiteralOrConstant();
00747
00748
00749 unsigned endIndex = (unsigned)value;
00750 if (endIndex >= varIt->second.second)
00751 throw Error(tokens.front().pos, FormatableString("access of array %0 out of bounds").arg(varName));
00752 if (endIndex < startIndex)
00753 throw Error(tokens.front().pos, FormatableString("end of range index must be lower or equal to start of range index"));
00754 tokens.pop_front();
00755
00756 len = endIndex - startIndex + 1;
00757 }
00758
00759 expect(Token::TOKEN_BRACKET_CLOSE);
00760 tokens.pop_front();
00761
00762 *addr += startIndex;
00763 *size = len;
00764 }
00765 else
00766 {
00767
00768 *size = varIt->second.second;
00769 }
00770 }
00771
00773 Node* Compiler::parseOr()
00774 {
00775 std::auto_ptr<Node> node(parseAnd());
00776
00777 while (tokens.front() == Token::TOKEN_OP_OR)
00778 {
00779 SourcePos pos = tokens.front().pos;
00780 tokens.pop_front();
00781 Node *subExpression = parseAnd();
00782 node.reset(new BinaryArithmeticNode(pos, ASEBA_OP_OR, node.release(), subExpression));
00783 }
00784
00785 return node.release();
00786 }
00787
00789 Node* Compiler::parseAnd()
00790 {
00791 std::auto_ptr<Node> node(parseNot());
00792
00793 while (tokens.front() == Token::TOKEN_OP_AND)
00794 {
00795 SourcePos pos = tokens.front().pos;
00796 tokens.pop_front();
00797 Node *subExpression = parseNot();
00798 node.reset(new BinaryArithmeticNode(pos, ASEBA_OP_AND, node.release(), subExpression));
00799 }
00800
00801 return node.release();
00802 }
00803
00805 Node* Compiler::parseNot()
00806 {
00807 SourcePos pos = tokens.front().pos;
00808
00809
00810 bool odd = false;
00811 while (tokens.front() == Token::TOKEN_OP_NOT)
00812 {
00813 odd = !odd;
00814 tokens.pop_front();
00815 }
00816
00817 if (odd)
00818 return new UnaryArithmeticNode(pos, ASEBA_UNARY_OP_NOT, parseCondition());
00819 else
00820 return parseCondition();
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845 }
00846
00848 Node* Compiler::parseCondition()
00849 {
00850 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 };
00851
00852 std::auto_ptr<Node> node(parseBinaryOrExpression());
00853
00854 while (IS_ONE_OF(conditionTypes))
00855 {
00856 Token::Type op = tokens.front();
00857 SourcePos pos = tokens.front().pos;
00858 tokens.pop_front();
00859 Node *subExpression = parseBinaryOrExpression();
00860 node.reset(BinaryArithmeticNode::fromComparison(pos, op, node.release(), subExpression));
00861 }
00862
00863 return node.release();
00864 }
00865
00867 Node *Compiler::parseBinaryOrExpression()
00868 {
00869 std::auto_ptr<Node> node(parseBinaryXorExpression());
00870
00871 while (tokens.front() == Token::TOKEN_OP_BIT_OR)
00872 {
00873 SourcePos pos = tokens.front().pos;
00874 tokens.pop_front();
00875 Node *subExpression = parseBinaryXorExpression();
00876 node.reset(new BinaryArithmeticNode(pos, ASEBA_OP_BIT_OR, node.release(), subExpression));
00877 }
00878
00879 return node.release();
00880 }
00881
00883 Node *Compiler::parseBinaryXorExpression()
00884 {
00885 std::auto_ptr<Node> node(parseBinaryAndExpression());
00886
00887 while (tokens.front() == Token::TOKEN_OP_BIT_XOR)
00888 {
00889 SourcePos pos = tokens.front().pos;
00890 tokens.pop_front();
00891 Node *subExpression = parseBinaryAndExpression();
00892 node.reset(new BinaryArithmeticNode(pos, ASEBA_OP_BIT_XOR, node.release(), subExpression));
00893 }
00894
00895 return node.release();
00896 }
00897
00899 Node *Compiler::parseBinaryAndExpression()
00900 {
00901 std::auto_ptr<Node> node(parseShiftExpression());
00902
00903 while (tokens.front() == Token::TOKEN_OP_BIT_AND)
00904 {
00905 SourcePos pos = tokens.front().pos;
00906 tokens.pop_front();
00907 Node *subExpression = parseShiftExpression();
00908 node.reset(new BinaryArithmeticNode(pos, ASEBA_OP_BIT_AND, node.release(), subExpression));
00909 }
00910
00911 return node.release();
00912 }
00913
00915 Node *Compiler::parseShiftExpression()
00916 {
00917 const Token::Type opTypes[] = { Token::TOKEN_OP_SHIFT_LEFT, Token::TOKEN_OP_SHIFT_RIGHT };
00918
00919 std::auto_ptr<Node> node(parseAddExpression());
00920
00921 while (IS_ONE_OF(opTypes))
00922 {
00923 Token::Type op = tokens.front();
00924 SourcePos pos = tokens.front().pos;
00925 tokens.pop_front();
00926 Node *subExpression = parseAddExpression();
00927 node.reset(BinaryArithmeticNode::fromShiftExpression(pos, op, node.release(), subExpression));
00928 }
00929
00930 return node.release();
00931 }
00932
00934 Node *Compiler::parseAddExpression()
00935 {
00936 const Token::Type opTypes[] = { Token::TOKEN_OP_ADD, Token::TOKEN_OP_NEG };
00937
00938 std::auto_ptr<Node> node(parseMultExpression());
00939
00940 while (IS_ONE_OF(opTypes))
00941 {
00942 Token::Type op = tokens.front();
00943 SourcePos pos = tokens.front().pos;
00944 tokens.pop_front();
00945 Node *subExpression = parseMultExpression();
00946 node.reset(BinaryArithmeticNode::fromAddExpression(pos, op, node.release(), subExpression));
00947 }
00948
00949 return node.release();
00950 }
00951
00953 Node *Compiler::parseMultExpression()
00954 {
00955 const Token::Type opTypes[] = { Token::TOKEN_OP_MULT, Token::TOKEN_OP_DIV, Token::TOKEN_OP_MOD };
00956
00957 std::auto_ptr<Node> node(parseUnaryExpression());
00958
00959 while (IS_ONE_OF(opTypes))
00960 {
00961 Token::Type op = tokens.front();
00962 SourcePos pos = tokens.front().pos;
00963 tokens.pop_front();
00964 Node *subExpression = parseUnaryExpression();
00965 node.reset(BinaryArithmeticNode::fromMultExpression(pos, op, node.release(), subExpression));
00966 }
00967
00968 return node.release();
00969 }
00970
00972 Node *Compiler::parseUnaryExpression()
00973 {
00974 const Token::Type acceptableTypes[] = { Token::TOKEN_PAR_OPEN, Token::TOKEN_OP_NEG, Token::TOKEN_OP_BIT_NOT, Token::TOKEN_STR_abs, Token::TOKEN_STRING_LITERAL, Token::TOKEN_INT_LITERAL };
00975
00976 EXPECT_ONE_OF(acceptableTypes);
00977 SourcePos pos = tokens.front().pos;
00978
00979 switch (tokens.front())
00980 {
00981 case Token::TOKEN_PAR_OPEN:
00982 {
00983 tokens.pop_front();
00984
00985 std::auto_ptr<Node> expression(parseOr());
00986
00987 expect(Token::TOKEN_PAR_CLOSE);
00988 tokens.pop_front();
00989
00990 return expression.release();
00991 }
00992
00993 case Token::TOKEN_OP_NEG:
00994 {
00995 tokens.pop_front();
00996
00997 return new UnaryArithmeticNode(pos, ASEBA_UNARY_OP_SUB, parseUnaryExpression());
00998 }
00999
01000 case Token::TOKEN_OP_BIT_NOT:
01001 {
01002 tokens.pop_front();
01003
01004 return new UnaryArithmeticNode(pos, ASEBA_UNARY_OP_BIT_NOT, parseUnaryExpression());
01005 };
01006
01007 case Token::TOKEN_STR_abs:
01008 {
01009 tokens.pop_front();
01010
01011 return new UnaryArithmeticNode(pos, ASEBA_UNARY_OP_ABS, parseUnaryExpression());
01012 }
01013
01014 case Token::TOKEN_INT_LITERAL:
01015 {
01016 int value = expectUInt16Literal();
01017 tokens.pop_front();
01018 return new ImmediateNode(pos, value);
01019 }
01020
01021 case Token::TOKEN_STRING_LITERAL:
01022 {
01023 std::string varName = tokens.front().sValue;
01024
01025 if (commonDefinitions->constants.contains(varName))
01026 {
01027 int value = expectConstant();
01028 tokens.pop_front();
01029 return new ImmediateNode(pos, value);
01030 }
01031 else
01032 {
01033 std::string varName = tokens.front().sValue;
01034 SourcePos varPos = tokens.front().pos;
01035 VariablesMap::const_iterator varIt = variablesMap.find(varName);
01036
01037
01038 if (varIt == variablesMap.end())
01039 throw Error(varPos, FormatableString("Variable %0 is not defined").arg(varName));
01040
01041 unsigned varAddr = varIt->second.first;
01042 unsigned varSize = varIt->second.second;
01043
01044 tokens.pop_front();
01045
01046
01047 if (tokens.front() == Token::TOKEN_BRACKET_OPEN)
01048 {
01049 tokens.pop_front();
01050
01051 std::auto_ptr<Node> array(new ArrayReadNode(pos, varAddr, varSize, varName));
01052
01053 array->children.push_back(parseBinaryOrExpression());
01054
01055 expect(Token::TOKEN_BRACKET_CLOSE);
01056 tokens.pop_front();
01057
01058 return array.release();
01059 }
01060 else
01061 {
01062 if (varSize != 1)
01063 throw Error(varPos, FormatableString("Accessing variable %0 as a scalar, but is an array of size %1 instead").arg(varName).arg(varSize));
01064
01065 return new LoadNode(pos, varAddr);
01066 }
01067 }
01068 }
01069
01070 default: internalCompilerError(); return NULL;
01071 }
01072 }
01073
01075 Node* Compiler::parseFunctionCall()
01076 {
01077 SourcePos pos = tokens.front().pos;
01078 tokens.pop_front();
01079
01080 expect(Token::TOKEN_STRING_LITERAL);
01081
01082 std::string funcName = tokens.front().sValue;
01083 FunctionsMap::const_iterator funcIt = functionsMap.find(funcName);
01084
01085
01086 if (funcIt == functionsMap.end())
01087 throw Error(tokens.front().pos, FormatableString("Target does not provide function %0").arg(funcName));
01088 const TargetDescription::NativeFunction &function = targetDescription->nativeFunctions[funcIt->second];
01089 std::auto_ptr<CallNode> callNode(new CallNode(pos, funcIt->second));
01090
01091 tokens.pop_front();
01092
01093 expect(Token::TOKEN_PAR_OPEN);
01094 tokens.pop_front();
01095
01096 if (function.parameters.size() == 0)
01097 {
01098 if (tokens.front() != Token::TOKEN_PAR_CLOSE)
01099 throw Error(tokens.front().pos, FormatableString("Function %0 requires no argument, some are used").arg(funcName));
01100 tokens.pop_front();
01101 }
01102 else
01103 {
01104
01105 unsigned localConstsAddr = targetDescription->variablesSize;
01106
01107
01108 int minTemplateId = 0;
01109 for (unsigned i = 0; i < function.parameters.size(); i++)
01110 minTemplateId = std::min(function.parameters[i].size, minTemplateId);
01111 std::valarray<int> templateParameters(-1, -minTemplateId);
01112
01113
01114 for (unsigned i = 0; i < function.parameters.size(); i++)
01115 {
01116 const Token::Type argTypes[] = { Token::TOKEN_STRING_LITERAL, Token::TOKEN_INT_LITERAL, Token::TOKEN_OP_NEG };
01117
01118
01119 if (tokens.front() == Token::TOKEN_PAR_CLOSE)
01120 throw Error(tokens.front().pos, FormatableString("Function %0 requires %1 arguments, only %2 are provided").arg(funcName).arg(function.parameters.size()).arg(i));
01121 else
01122 EXPECT_ONE_OF(argTypes);
01123
01124
01125 unsigned varAddr;
01126 unsigned varSize;
01127 SourcePos varPos = tokens.front().pos;
01128
01129 if ((tokens.front() == Token::TOKEN_INT_LITERAL) || (tokens.front() == Token::TOKEN_OP_NEG) || (commonDefinitions->constants.contains(tokens.front().sValue)))
01130 {
01131 int value = expectInt16LiteralOrConstant();
01132
01133
01134 if (localConstsAddr <= freeVariableIndex)
01135 throw Error(varPos, "No more free variable space for constant");
01136 varAddr = --localConstsAddr;
01137 varSize = 1;
01138 callNode->children.push_back(new ImmediateNode(varPos, value));
01139 callNode->children.push_back(new StoreNode(varPos, varAddr));
01140 tokens.pop_front();
01141 }
01142 else
01143 {
01144 parseReadVarArrayAccess(&varAddr, &varSize);
01145 }
01146
01147
01148 if (function.parameters[i].size > 0)
01149 {
01150 if (varSize != (unsigned)function.parameters[i].size)
01151 throw Error(varPos, FormatableString("Argument %0 (%1) of function %2 is of size %3, function definition demands size %4").arg(i).arg(function.parameters[i].name).arg(funcName).arg(varSize).arg(function.parameters[i].size));
01152 }
01153 else if (function.parameters[i].size < 0)
01154 {
01155 int templateIndex = -function.parameters[i].size - 1;
01156 if (templateParameters[templateIndex] < 0)
01157 {
01158
01159 templateParameters[templateIndex] = varSize;
01160 }
01161 else if ((unsigned)templateParameters[templateIndex] != varSize)
01162 {
01163 throw Error(varPos, FormatableString("Argument %0 (%1) of function %2 is of size %3, while a previous instance of the template parameter was of size %4").arg(i).arg(function.parameters[i].name).arg(funcName).arg(varSize).arg(templateParameters[templateIndex]));
01164 }
01165 }
01166 else
01167 {
01168
01169 callNode->argumentsAddr.push_back(varSize);
01170 }
01171
01172
01173 callNode->argumentsAddr.push_back(varAddr);
01174
01175
01176 if (i + 1 == function.parameters.size())
01177 {
01178 if (tokens.front() == Token::TOKEN_COMMA)
01179 throw Error(tokens.front().pos, FormatableString("Function %0 requires %1 arguments, more are used").arg(funcName).arg(function.parameters.size()));
01180 else
01181 expect(Token::TOKEN_PAR_CLOSE);
01182 }
01183 else
01184 {
01185 if (tokens.front() == Token::TOKEN_PAR_CLOSE)
01186 throw Error(tokens.front().pos, FormatableString("Function %0 requires %1 arguments, only %2 are provided").arg(funcName).arg(function.parameters.size()).arg(i + 1));
01187 else
01188 expect(Token::TOKEN_COMMA);
01189 }
01190 tokens.pop_front();
01191 }
01192
01193
01194 for (unsigned i = 0; i < templateParameters.size(); i++)
01195 if (templateParameters[i] >= 0)
01196 callNode->argumentsAddr.push_back(templateParameters[i]);
01197 }
01198
01199
01200 return callNode.release();
01201 }
01202 };