$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 #ifndef __ASEBA_COMPILER_H 00022 #define __ASEBA_COMPILER_H 00023 00024 #include <vector> 00025 #include <deque> 00026 #include <string> 00027 #include <map> 00028 #include <set> 00029 #include <utility> 00030 #include <istream> 00031 00032 #include "errors_code.h" 00033 #include "../common/types.h" 00034 #include "../utils/FormatableString.h" 00035 00036 namespace Aseba 00037 { 00042 00043 // pre-declaration 00044 struct Node; 00045 struct ProgramNode; 00046 struct StatementNode; 00047 struct BinaryArithmeticNode; 00048 struct AssignmentNode; 00049 struct TupleVectorNode; 00050 struct MemoryVectorNode; 00051 00053 struct TargetDescription 00054 { 00056 struct NamedVariable 00057 { 00058 NamedVariable(const std::wstring &name, unsigned size) : size(size), name(name) {} 00059 NamedVariable() {} 00060 00061 unsigned size; 00062 std::wstring name; 00063 }; 00064 00066 struct LocalEvent 00067 { 00068 std::wstring name; 00069 std::wstring description; 00070 }; 00071 00073 struct NativeFunctionParameter 00074 { 00075 NativeFunctionParameter(const std::wstring &name, int size) : size(size), name(name) {} 00076 NativeFunctionParameter() {} 00077 00078 int size; 00079 std::wstring name; 00080 }; 00081 00083 struct NativeFunction 00084 { 00085 NativeFunction(const std::wstring &name, const std::wstring &description) : name(name), description(description) {} 00086 NativeFunction() {} 00087 00088 std::wstring name; 00089 std::wstring description; 00090 std::vector<NativeFunctionParameter> parameters; 00091 }; 00092 00093 std::wstring name; 00094 unsigned protocolVersion; 00095 00096 unsigned bytecodeSize; 00097 unsigned variablesSize; 00098 unsigned stackSize; 00099 00100 std::vector<NamedVariable> namedVariables; 00101 std::vector<LocalEvent> localEvents; 00102 std::vector<NativeFunction> nativeFunctions; 00103 00104 TargetDescription() { variablesSize = bytecodeSize = stackSize = 0; } 00105 uint16 crc() const; 00106 }; 00107 00109 struct BytecodeElement 00110 { 00111 BytecodeElement(); 00112 BytecodeElement(unsigned short bytecode) : bytecode(bytecode), line(0) { } 00113 BytecodeElement(unsigned short bytecode, unsigned short line) : bytecode(bytecode), line(line) { } 00114 operator unsigned short () const { return bytecode; } 00115 unsigned getWordSize() const; 00116 00117 unsigned short bytecode; 00118 unsigned short line; 00119 }; 00120 00122 struct BytecodeVector: std::deque<BytecodeElement> 00123 { 00125 BytecodeVector() : maxStackDepth(0), callDepth(0), lastLine(0) { } 00126 00127 unsigned maxStackDepth; 00128 unsigned callDepth; 00129 unsigned lastLine; 00130 00131 void push_back(const BytecodeElement& be) 00132 { 00133 std::deque<BytecodeElement>::push_back(be); 00134 lastLine = be.line; 00135 } 00136 00137 void changeStopToRetSub(); 00138 unsigned short getTypeOfLast() const; 00139 00141 typedef std::map<unsigned, unsigned> EventAddressesToIdsMap; 00142 EventAddressesToIdsMap getEventAddressesToIds() const; 00143 }; 00144 00145 // predeclaration 00146 struct PreLinkBytecode; 00147 00149 struct SourcePos 00150 { 00151 unsigned character; 00152 unsigned row; 00153 unsigned column; 00154 bool valid; 00155 00156 SourcePos(unsigned character, unsigned row, unsigned column) : character(character - 1), row(row), column(column - 1) { valid = true; } 00157 SourcePos() { valid = false; } 00158 std::wstring toWString() const; 00159 }; 00160 00162 class ErrorMessages 00163 { 00164 public: 00165 ErrorMessages(); 00166 00168 typedef const std::wstring (*ErrorCallback)(ErrorCode error); 00170 static const std::wstring defaultCallback(ErrorCode error); 00171 }; 00172 00174 struct Error 00175 { 00176 SourcePos pos; 00177 std::wstring message; 00178 00179 Error(const SourcePos& pos, const std::wstring& message) : pos(pos), message(message) { } 00181 Error() { message = L"not defined"; } 00182 00184 std::wstring toWString() const; 00185 }; 00186 00187 struct TranslatableError : public Error 00188 { 00189 TranslatableError() : Error() {} 00190 TranslatableError(const SourcePos& pos, ErrorCode error); 00191 TranslatableError &arg(int value, int fieldWidth = 0, int base = 10, wchar_t fillChar = ' '); 00192 TranslatableError &arg(unsigned value, int fieldWidth = 0, int base = 10, wchar_t fillChar = ' '); 00193 TranslatableError &arg(float value, int fieldWidth = 0, int precision = 6, wchar_t fillChar = ' '); 00194 TranslatableError &arg(const std::wstring& value); 00195 00196 Error toError(void); 00197 static void setTranslateCB(ErrorMessages::ErrorCallback newCB); 00198 00199 static ErrorMessages::ErrorCallback translateCB; 00200 WFormatableString message; 00201 }; 00202 00204 typedef std::vector<std::wstring> VariablesNamesVector; 00205 00207 struct NamedValue 00208 { 00210 NamedValue(const std::wstring& name, int value) : name(name), value(value) {} 00211 00212 std::wstring name; 00213 int value; 00214 }; 00215 00217 typedef NamedValue EventDescription; 00218 00220 typedef NamedValue ConstantDefinition; 00221 00223 struct NamedValuesVector: public std::vector<NamedValue> 00224 { 00225 bool contains(const std::wstring& s, size_t* position = 0) const; 00226 }; 00227 00229 typedef NamedValuesVector EventsDescriptionsVector; 00230 00232 typedef NamedValuesVector ConstantsDefinitions; 00233 00235 struct CommonDefinitions 00236 { 00238 EventsDescriptionsVector events; 00240 ConstantsDefinitions constants; 00241 00243 void clear() { events.clear(); constants.clear(); } 00244 }; 00245 00247 typedef std::vector<short int> VariablesDataVector; 00248 00250 class Compiler 00251 { 00252 public: 00254 struct Token 00255 { 00256 enum Type 00257 { 00258 TOKEN_END_OF_STREAM = 0, 00259 TOKEN_STR_when, 00260 TOKEN_STR_emit, 00261 TOKEN_STR_for, 00262 TOKEN_STR_in, 00263 TOKEN_STR_step, 00264 TOKEN_STR_while, 00265 TOKEN_STR_do, 00266 TOKEN_STR_if, 00267 TOKEN_STR_then, 00268 TOKEN_STR_else, 00269 TOKEN_STR_elseif, 00270 TOKEN_STR_end, 00271 TOKEN_STR_var, 00272 TOKEN_STR_call, 00273 TOKEN_STR_sub, 00274 TOKEN_STR_callsub, 00275 TOKEN_STR_onevent, 00276 TOKEN_STR_abs, 00277 TOKEN_STR_return, 00278 TOKEN_STRING_LITERAL, 00279 TOKEN_INT_LITERAL, 00280 TOKEN_PAR_OPEN, 00281 TOKEN_PAR_CLOSE, 00282 TOKEN_BRACKET_OPEN, 00283 TOKEN_BRACKET_CLOSE, 00284 TOKEN_COLON, 00285 TOKEN_COMMA, 00286 TOKEN_ASSIGN, 00287 TOKEN_OP_OR, 00288 TOKEN_OP_AND, 00289 TOKEN_OP_NOT, 00290 00291 TOKEN_OP_EQUAL, // group of tokens, don't split or mess up 00292 TOKEN_OP_NOT_EQUAL, // 00293 TOKEN_OP_BIGGER, // 00294 TOKEN_OP_BIGGER_EQUAL, // 00295 TOKEN_OP_SMALLER, // 00296 TOKEN_OP_SMALLER_EQUAL, // 00297 00298 TOKEN_OP_ADD, // group of 2 tokens, don't split or mess up 00299 TOKEN_OP_NEG, // 00300 TOKEN_OP_MULT, // group of 3 tokens, don't split or mess up 00301 TOKEN_OP_DIV, // 00302 TOKEN_OP_MOD, // 00303 TOKEN_OP_SHIFT_LEFT, // group of 2 tokens, don't split or mess up 00304 TOKEN_OP_SHIFT_RIGHT, // 00305 TOKEN_OP_BIT_OR, // group of 4 tokens, don't split or mess up 00306 TOKEN_OP_BIT_XOR, // 00307 TOKEN_OP_BIT_AND, // 00308 TOKEN_OP_BIT_NOT, // 00309 00310 TOKEN_OP_ADD_EQUAL, // group of 12 tokens, don't split or mess up 00311 TOKEN_OP_NEG_EQUAL, // 00312 TOKEN_OP_MULT_EQUAL, // 00313 TOKEN_OP_DIV_EQUAL, // 00314 TOKEN_OP_MOD_EQUAL, // 00315 TOKEN_OP_SHIFT_LEFT_EQUAL, // 00316 TOKEN_OP_SHIFT_RIGHT_EQUAL, // 00317 TOKEN_OP_BIT_OR_EQUAL, // 00318 TOKEN_OP_BIT_XOR_EQUAL, // 00319 TOKEN_OP_BIT_AND_EQUAL, // 00320 00321 TOKEN_OP_PLUS_PLUS, 00322 TOKEN_OP_MINUS_MINUS 00323 00324 } type; 00325 std::wstring sValue; 00326 int iValue; 00327 SourcePos pos; 00328 00329 Token() : type(TOKEN_END_OF_STREAM), iValue(0) {} 00330 Token(Type type, SourcePos pos = SourcePos(), const std::wstring& value = L""); 00331 const std::wstring typeName() const; 00332 std::wstring toWString() const; 00333 operator Type () const { return type; } 00334 }; 00335 00337 typedef std::map<std::wstring, std::pair<unsigned, unsigned> > VariablesMap; 00339 typedef std::map<std::wstring, unsigned> FunctionsMap; 00341 struct SubroutineDescriptor 00342 { 00343 std::wstring name; 00344 unsigned address; 00345 unsigned line; 00346 00347 SubroutineDescriptor(const std::wstring& name, unsigned address, unsigned line) : name(name), address(address), line(line) {} 00348 }; 00350 typedef std::vector<SubroutineDescriptor> SubroutineTable; 00352 typedef std::map<std::wstring, unsigned> SubroutineReverseTable; 00354 typedef std::set<unsigned> ImplementedEvents; 00356 typedef std::map<std::wstring, int> ConstantsMap; 00358 typedef std::map<std::wstring, unsigned> EventsMap; 00359 00360 public: 00361 Compiler(); 00362 void setTargetDescription(const TargetDescription *description); 00363 const TargetDescription *getTargetDescription() const { return targetDescription;} 00364 const VariablesMap *getVariablesMap() const { return &variablesMap; } 00365 void setCommonDefinitions(const CommonDefinitions *definitions); 00366 bool compile(std::wistream& source, BytecodeVector& bytecode, unsigned& allocatedVariablesCount, Error &errorDescription, std::wostream* dump = 0); 00367 void setTranslateCallback(ErrorMessages::ErrorCallback newCB) { TranslatableError::setTranslateCB(newCB); } 00368 static std::wstring translate(ErrorCode error) { return TranslatableError::translateCB(error); } 00369 00370 protected: 00371 void internalCompilerError() const; 00372 void expect(const Token::Type& type) const; 00373 unsigned expectUInt12Literal() const; 00374 unsigned expectUInt16Literal() const; 00375 unsigned expectPositiveInt16Literal() const; 00376 int expectAbsoluteInt16Literal(bool negative) const; 00377 unsigned expectPositiveConstant() const; 00378 int expectConstant() const; 00379 unsigned expectPositiveInt16LiteralOrConstant() const; 00380 int expectInt16LiteralOrConstant(); 00381 unsigned expectGlobalEventId() const; 00382 unsigned expectAnyEventId() const; 00383 std::wstring eventName(unsigned eventId) const; 00384 template <int length> 00385 bool isOneOf(const Token::Type types[length]) const; 00386 template <int length> 00387 void expectOneOf(const Token::Type types[length]) const; 00388 00389 void freeTemporaryMemory(); 00390 void allocateTemporaryMemory(const SourcePos varPos, const unsigned size, unsigned& varAddr); 00391 AssignmentNode* allocateTemporaryVariable(const SourcePos varPos, Node* rValue); 00392 00393 VariablesMap::const_iterator findVariable(const std::wstring& name, const SourcePos& pos) const; 00394 FunctionsMap::const_iterator findFunction(const std::wstring& name, const SourcePos& pos) const; 00395 ConstantsMap::const_iterator findConstant(const std::wstring& name, const SourcePos& pos) const; 00396 EventsMap::const_iterator findGlobalEvent(const std::wstring& name, const SourcePos& pos) const; 00397 EventsMap::const_iterator findAnyEvent(const std::wstring& name, const SourcePos& pos) const; 00398 SubroutineReverseTable::const_iterator findSubroutine(const std::wstring& name, const SourcePos& pos) const; 00399 bool constantExists(const std::wstring& name) const; 00400 void buildMaps(); 00401 void tokenize(std::wistream& source); 00402 wchar_t getNextCharacter(std::wistream& source, SourcePos& pos); 00403 bool testNextCharacter(std::wistream& source, SourcePos& pos, wchar_t test, Token::Type tokenIfTrue); 00404 void dumpTokens(std::wostream &dest) const; 00405 bool verifyStackCalls(PreLinkBytecode& preLinkBytecode); 00406 bool link(const PreLinkBytecode& preLinkBytecode, BytecodeVector& bytecode); 00407 void disassemble(BytecodeVector& bytecode, const PreLinkBytecode& preLinkBytecode, std::wostream& dump) const; 00408 00409 protected: 00410 Node* parseProgram(); 00411 00412 Node* parseStatement(); 00413 00414 Node* parseBlockStatement(); 00415 00416 Node* parseReturn(); 00417 Node* parseVarDef(); 00418 AssignmentNode* parseVarDefInit(MemoryVectorNode* lValue); 00419 Node* parseAssignment(); 00420 Node* parseIfWhen(bool edgeSensitive); 00421 Node* parseFor(); 00422 Node* parseWhile(); 00423 Node* parseOnEvent(); 00424 Node* parseEmit(); 00425 Node* parseSubDecl(); 00426 Node* parseCallSub(); 00427 00428 Node* parseOr(); 00429 Node* parseAnd(); 00430 Node* parseNot(); 00431 00432 Node* parseCondition(); 00433 00434 Node *parseBinaryOrExpression(); 00435 Node *parseBinaryXorExpression(); 00436 Node *parseBinaryAndExpression(); 00437 00438 Node* parseShiftExpression(); 00439 Node* parseAddExpression(); 00440 Node* parseMultExpression(); 00441 Node* parseUnaryExpression(); 00442 Node* parseFunctionCall(); 00443 00444 TupleVectorNode* parseTupleVector(bool compatibility = false); 00445 Node* parseConstantAndVariable(); 00446 MemoryVectorNode* parseVariable(); 00447 unsigned parseVariableDefSize(); 00448 Node* tryParsingConstantExpression(SourcePos pos, int& constantResult); 00449 int expectConstantExpression(SourcePos pos, Node* tree); 00450 00451 protected: 00452 std::deque<Token> tokens; 00453 VariablesMap variablesMap; 00454 ImplementedEvents implementedEvents; 00455 FunctionsMap functionsMap; 00456 ConstantsMap constantsMap; 00457 EventsMap globalEventsMap; 00458 EventsMap allEventsMap; 00459 SubroutineTable subroutineTable; 00460 SubroutineReverseTable subroutineReverseTable; 00461 unsigned freeVariableIndex; 00462 unsigned endVariableIndex; 00463 const TargetDescription *targetDescription; 00464 const CommonDefinitions *commonDefinitions; 00465 00466 ErrorMessages translator; 00467 }; // Compiler 00468 00470 struct PreLinkBytecode 00471 { 00473 typedef std::map<unsigned, BytecodeVector> EventsBytecode; 00474 EventsBytecode events; 00475 00477 typedef std::map<unsigned, BytecodeVector> SubroutinesBytecode; 00478 SubroutinesBytecode subroutines; 00479 00480 BytecodeVector *current; 00481 00482 PreLinkBytecode(); 00483 00484 void fixup(const Compiler::SubroutineTable &subroutineTable); 00485 }; 00486 00489 }; // Aseba 00490 00491 #endif 00492