00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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,
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,
00299 TOKEN_OP_NEG,
00300 TOKEN_OP_MULT,
00301 TOKEN_OP_DIV,
00302 TOKEN_OP_MOD,
00303 TOKEN_OP_SHIFT_LEFT,
00304 TOKEN_OP_SHIFT_RIGHT,
00305 TOKEN_OP_BIT_OR,
00306 TOKEN_OP_BIT_XOR,
00307 TOKEN_OP_BIT_AND,
00308 TOKEN_OP_BIT_NOT,
00309
00310 TOKEN_OP_ADD_EQUAL,
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 };
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 };
00490
00491 #endif
00492