compiler.h
Go to the documentation of this file.
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 


aseba
Author(s): Stéphane Magnenat
autogenerated on Thu Jan 2 2014 11:17:16