$search
00001 /* 00002 Aseba - an event-based framework for distributed robot control 00003 Copyright (C) 2007--2012: 00004 Stephane Magnenat <stephane at magnenat dot net> 00005 (http://stephane.magnenat.net) 00006 and other contributors, see authors.txt for details 00007 00008 This program is free software: you can redistribute it and/or modify 00009 it under the terms of the GNU Lesser General Public License as published 00010 by the Free Software Foundation, version 3 of the License. 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 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 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 // search for global 00191 if (eventId < commonDefinitions->events.size()) 00192 return commonDefinitions->events[eventId].name; 00193 00194 // then for local 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 // allocate space at the end of the variables' memory 00240 unsigned endOfMemory = targetDescription->variablesSize - endVariableIndex; 00241 varAddr = endOfMemory - size; 00242 endVariableIndex += size; 00243 00244 // free space check 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 // allocate the temporary variable 00254 const unsigned size = rValue->getVectorSize(); 00255 unsigned addr = Node::E_NOVAL; 00256 allocateTemporaryMemory(varPos, size, addr); 00257 00258 // create assignment 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 // parse all vars declarations 00270 while (tokens.front() == Token::TOKEN_STR_var) 00271 { 00272 // we may receive NULL pointers because non initialized variables produce no code 00273 Node *child = parseVarDef(); 00274 if (child) 00275 block->children.push_back(child); 00276 } 00277 // parse the rest of the code 00278 while (tokens.front() != Token::TOKEN_END_OF_STREAM) 00279 { 00280 // only var declaration are allowed to return NULL node, so we assert on node 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 // reset temporary variables 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 // check for string literal 00334 if (tokens.front() != Token::TOKEN_STRING_LITERAL) 00335 throw TranslatableError(tokens.front().pos, 00336 ERROR_EXPECTING_IDENTIFIER).arg(tokens.front().toWString()); 00337 00338 // save variable 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 // optional array 00347 varSize = parseVariableDefSize(); 00348 00349 // check if variable exists 00350 if (variablesMap.find(varName) != variablesMap.end()) 00351 throw TranslatableError(varPos, ERROR_VAR_ALREADY_DEFINED).arg(varName); 00352 00353 // check if variable conflicts with a constant 00354 if(commonDefinitions->constants.contains(varName)) 00355 throw TranslatableError(varPos, ERROR_VAR_CONST_COLLISION).arg(varName); 00356 00357 // optional assignation 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 // valid 00364 varSize = me->getVectorSize(); 00365 me.release(); 00366 } 00367 00368 // sanity check for array 00369 if (varSize == 0 || varSize == Node::E_NOVAL) 00370 throw TranslatableError(varPos, ERROR_UNDEFINED_SIZE).arg(varName); 00371 00372 // save variable 00373 variablesMap[varName] = std::make_pair(varAddr, varSize); 00374 freeVariableIndex += varSize; 00375 00376 // check space 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 // try old style initialization 1,2,3 00394 std::auto_ptr<Node> rValue(parseTupleVector(true)); 00395 if (rValue.get() == NULL) 00396 { 00397 // no -> other type of initialization 00398 rValue.reset(parseBinaryOrExpression()); 00399 } 00400 00401 if (lValue->getVectorSize() == Node::E_NOVAL) 00402 { 00403 // infere the variable's size based on the initilization 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 // parse left value 00428 std::auto_ptr<Node> lValue(parseBinaryOrExpression()); 00429 00430 // parse right value 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 // eat "if" / "when" 00483 ifNode->edgeSensitive = edgeSensitive; 00484 tokens.pop_front(); 00485 00486 // condition 00487 ifNode->children.push_back(parseOr()); 00488 00489 // then keyword 00490 if (edgeSensitive) 00491 expect(Token::TOKEN_STR_do); 00492 else 00493 expect(Token::TOKEN_STR_then); 00494 tokens.pop_front(); 00495 00496 // parse true condition 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 /*// parse false condition (only for if) 00502 if (!edgeSensitive && (tokens.front() == Token::TOKEN_STR_else)) 00503 { 00504 tokens.pop_front(); 00505 00506 ifNode->children.push_back(new BlockNode(tokens.front().pos)); 00507 while (tokens.front() != Token::TOKEN_STR_end) 00508 ifNode->children[2]->children.push_back(parseBlockStatement()); 00509 }*/ 00510 00511 // parse false condition (only for if) 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 // if elseif, queue new if directly after and return before parsing trailing end 00523 if (tokens.front() == Token::TOKEN_STR_elseif) 00524 { 00525 ifNode->children.push_back(parseIfWhen(false)); 00526 return ifNode.release(); 00527 } 00528 } 00529 00530 // end keyword 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 // eat "for" 00542 SourcePos whilePos = tokens.front().pos; 00543 tokens.pop_front(); 00544 00545 // variable 00546 std::auto_ptr<MemoryVectorNode> variable(parseVariable()); 00547 MemoryVectorNode* variableRef = variable.get(); // used to create copies 00548 SourcePos varPos = variable->sourcePos; 00549 00550 // in keyword 00551 expect(Token::TOKEN_STR_in); 00552 tokens.pop_front(); 00553 00554 // range start index 00555 int rangeStartIndex = expectInt16LiteralOrConstant(); 00556 SourcePos rangeStartIndexPos = tokens.front().pos; 00557 tokens.pop_front(); 00558 00559 // : keyword 00560 expect(Token::TOKEN_COLON); 00561 tokens.pop_front(); 00562 00563 // range end index 00564 int rangeEndIndex = expectInt16LiteralOrConstant(); 00565 SourcePos rangeEndIndexPos = tokens.front().pos; 00566 tokens.pop_front(); 00567 00568 // check for step 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 // check conditions 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 // do keyword 00592 expect(Token::TOKEN_STR_do); 00593 tokens.pop_front(); 00594 00595 // create enclosing block and initial variable state 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 // create while and condition 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 // block and end keyword 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 // increment variable 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 // eat "while" 00636 tokens.pop_front(); 00637 00638 // condition 00639 whileNode->children.push_back(parseOr()); 00640 00641 // do keyword 00642 expect(Token::TOKEN_STR_do); 00643 tokens.pop_front(); 00644 00645 // block and end keyword 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 // event id 00680 emitNode->eventId = expectGlobalEventId(); 00681 tokens.pop_front(); 00682 00683 // event argument 00684 unsigned eventSize = commonDefinitions->events[emitNode->eventId].value; 00685 if (eventSize > 0) 00686 { 00687 std::auto_ptr<Node> preNode(parseBinaryOrExpression()); 00688 00689 // allocate memory? 00690 if (!dynamic_cast<MemoryVectorNode*>(preNode.get()) || preNode->getVectorAddr() == Node::E_NOVAL) 00691 { 00692 preNode.reset(allocateTemporaryVariable(pos, preNode.release())); 00693 } 00694 00695 //allocateTemporaryVariable(pos) 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 // eat all trailing not 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 std::auto_ptr<BinaryArithmeticNode> expression(parseCondition()); 00802 00803 // recurse on parenthesis 00804 if (tokens.front() == Token::TOKEN_PAR_OPEN) 00805 { 00806 tokens.pop_front(); 00807 00808 expression.reset(parseOr()); 00809 00810 expect(Token::TOKEN_PAR_CLOSE); 00811 tokens.pop_front(); 00812 } 00813 else 00814 { 00815 expression.reset(parseCondition()); 00816 } 00817 // apply de Morgan to remove the not 00818 if (odd) 00819 expression->deMorganNotRemoval(); 00820 00821 return expression.release(); 00822 */ 00823 } 00824 00826 Node* Compiler::parseCondition() 00827 { 00828 /*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 }; 00829 00830 std::auto_ptr<Node> leftExprNode(parseBinaryOrExpression()); 00831 00832 EXPECT_ONE_OF(conditionTypes); 00833 00834 Token::Type op = tokens.front(); 00835 SourcePos pos = tokens.front().pos; 00836 tokens.pop_front(); 00837 Node *rightExprNode = parseBinaryOrExpression(); 00838 return BinaryArithmeticNode::fromComparison(pos, op, leftExprNode.release(), rightExprNode);*/ 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 // immediate 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 // check if 2nd token is a comma 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 // no 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 // nested tuples 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 // check if it is a const array access 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 // constant index 01123 std::auto_ptr<TupleVectorNode> index(new TupleVectorNode(pos)); 01124 index->addImmediateValue(start); 01125 01126 // do we have array subscript? 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 // check if second index is within bounds 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 // general expression as index 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 // what?? 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 // not an array 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 // oops, tree cannot be resolved to a constant, return it 01210 return tree.release(); 01211 } 01212 } 01213 01217 int Compiler::expectConstantExpression(SourcePos pos, Node* tree) 01218 { 01219 int result = 0; 01220 01221 // create a temporary "var = expr" tree 01222 // used to access the facility offered by the AssignmentNode (size check,...) 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 //tempTree1->children.push_back(parseBinaryOrExpression()); 01228 01229 //unsigned indent = 0; 01230 //std::cerr << "Tree before expanding" << std::endl; 01231 //tempTree1->dump(std::wcerr, indent); 01232 01233 std::auto_ptr<Node> tempTree2(tempTree1->expandToAsebaTree(NULL)); 01234 01235 //std::cerr << "Tree after expanding" << std::endl; 01236 //tempTree2->dump(std::wcerr, indent); 01237 01238 tempTree1.release(); // tree already deleted by expandToAsebaTree() 01239 tempTree2->optimize(NULL); 01240 01241 //std::cerr << "Tree after optimization" << std::endl; 01242 //tempTree2->dump(std::wcerr, indent); 01243 //std::cerr << std::endl; 01244 01245 // valid optimization? 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 // resolve to an ImmediateNode? 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 // delete the tree 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 // count the number of template parameters and build array 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 // trees for arguments 01299 for (unsigned i = 0; i < function.parameters.size(); i++) 01300 { 01301 // check if it is an argument 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 // we need to fill those two variables 01306 unsigned varAddr; 01307 unsigned varSize; 01308 SourcePos varPos = tokens.front().pos; 01309 01310 std::auto_ptr<Node> preNode(parseBinaryOrExpression()); 01311 // get the address and size 01312 varAddr = preNode->getVectorAddr(); 01313 varSize = preNode->getVectorSize(); 01314 01315 // allocate memory? 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 // check if variable size is correct 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 // template not initialised, store 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 // any size, store variable size 01345 callNode->argumentsAddr.push_back(varSize); 01346 } 01347 01348 // store variable address 01349 callNode->argumentsAddr.push_back(varAddr); 01350 01351 // parse comma or end parenthesis 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 } // for 01368 01369 // store template parameters size when initialized 01370 for (unsigned i = 0; i < templateParameters.size(); i++) 01371 if (templateParameters[i] >= 0) 01372 callNode->argumentsAddr.push_back(templateParameters[i]); 01373 } // if 01374 01375 // return the node for the function call 01376 return callNode.release(); 01377 } 01378 }; // Aseba