1 #pragma once 2 #include "Tokenizer.h" 3 #include "Core/Expression.h" 4 #include "Commands/CommandSequence.h" 5 #include "DirectivesParser.h" 6 #include <set> 7 #include <map> 8 #include <unordered_map> 9 #include "Core/Common.h" 10 11 struct AssemblyTemplateArgument 12 { 13 const wchar_t* variableName; 14 std::wstring value; 15 }; 16 17 struct ParserMacro 18 { 19 std::wstring name; 20 std::vector<std::wstring> parameters; 21 std::set<std::wstring> labels; 22 std::vector<Token> content; 23 size_t counter; 24 }; 25 26 enum class ConditionalResult { Unknown, True, False }; 27 28 class Parser 29 { 30 public: 31 Parser(); atEnd()32 bool atEnd() { return entries.back().tokenizer->atEnd(); } 33 34 void addEquation(const Token& start, const std::wstring& name, const std::wstring& value); 35 36 Expression parseExpression(); 37 bool parseExpressionList(std::vector<Expression>& list, int min = -1, int max = -1); 38 bool parseIdentifier(std::wstring& dest); 39 std::unique_ptr<CAssemblerCommand> parseCommand(); 40 std::unique_ptr<CAssemblerCommand> parseCommandSequence(wchar_t indicator = 0, const std::initializer_list<const wchar_t*> terminators = {}); 41 std::unique_ptr<CAssemblerCommand> parseFile(TextFile& file, bool virtualFile = false); 42 std::unique_ptr<CAssemblerCommand> parseString(const std::wstring& text); 43 std::unique_ptr<CAssemblerCommand> parseTemplate(const std::wstring& text, const std::initializer_list<AssemblyTemplateArgument> variables = {}); 44 std::unique_ptr<CAssemblerCommand> parseDirective(const DirectiveMap &directiveSet); 45 bool matchToken(TokenType type, bool optional = false); 46 getTokenizer()47 Tokenizer* getTokenizer() { return entries.back().tokenizer; }; 48 const Token& peekToken(int ahead = 0) { return getTokenizer()->peekToken(ahead); }; nextToken()49 const Token& nextToken() { return getTokenizer()->nextToken(); }; eatToken()50 void eatToken() { getTokenizer()->eatToken(); }; eatTokens(int num)51 void eatTokens(int num) { getTokenizer()->eatTokens(num); }; 52 53 void pushConditionalResult(ConditionalResult cond); popConditionalResult()54 void popConditionalResult() { conditionStack.pop_back(); }; isInsideTrueBlock()55 bool isInsideTrueBlock() { return conditionStack.back().inTrueBlock; } isInsideUnknownBlock()56 bool isInsideUnknownBlock() { return conditionStack.back().inUnknownBlock; } 57 58 template <typename... Args> printError(const Token & token,const wchar_t * text,const Args &...args)59 void printError(const Token& token, const wchar_t* text, const Args&... args) 60 { 61 errorLine = token.line; 62 Global.FileInfo.LineNumber = (int) token.line; 63 std::wstring errorText = formatString(text,args...); 64 Logger::printError(Logger::Error,errorText); 65 error = true; 66 } 67 hasError()68 bool hasError() { return error; } 69 void updateFileInfo(); 70 protected: clearError()71 void clearError() { error = false; } 72 std::unique_ptr<CAssemblerCommand> handleError(); 73 74 std::unique_ptr<CAssemblerCommand> parse(Tokenizer* tokenizer, bool virtualFile, const std::wstring& name = L""); 75 std::unique_ptr<CAssemblerCommand> parseLabel(); 76 bool checkEquLabel(); 77 bool checkMacroDefinition(); 78 std::unique_ptr<CAssemblerCommand> parseMacroCall(); 79 80 struct FileEntry 81 { 82 Tokenizer* tokenizer; 83 bool virtualFile; 84 int fileNum; 85 int previousCommandLine; 86 }; 87 88 std::vector<FileEntry> entries; 89 std::map<std::wstring,ParserMacro> macros; 90 std::set<std::wstring> macroLabels; 91 bool initializingMacro; 92 bool error; 93 size_t errorLine; 94 95 bool overrideFileInfo; 96 int overrideFileNum; 97 int overrideLineNum; 98 99 struct ConditionInfo 100 { 101 bool inTrueBlock; 102 bool inUnknownBlock; 103 }; 104 105 std::vector<ConditionInfo> conditionStack; 106 }; 107 108 struct TokenSequenceValue 109 { TokenSequenceValueTokenSequenceValue110 TokenSequenceValue(const wchar_t* text) 111 { 112 type = TokenType::Identifier; 113 textValue = text; 114 } 115 TokenSequenceValueTokenSequenceValue116 TokenSequenceValue(int64_t num) 117 { 118 type = TokenType::Integer; 119 intValue = num; 120 } 121 TokenSequenceValueTokenSequenceValue122 TokenSequenceValue(double num) 123 { 124 type = TokenType::Float; 125 floatValue = num; 126 } 127 128 129 TokenType type; 130 union 131 { 132 const wchar_t* textValue; 133 int64_t intValue; 134 double floatValue; 135 }; 136 }; 137 138 using TokenSequence = std::initializer_list<TokenType>; 139 using TokenValueSequence = std::initializer_list<TokenSequenceValue>; 140 141 class TokenSequenceParser 142 { 143 public: 144 void addEntry(int result, TokenSequence tokens, TokenValueSequence values); 145 bool parse(Parser& parser, int& result); getEntryCount()146 size_t getEntryCount() { return entries.size(); } 147 private: 148 struct Entry 149 { 150 std::vector<TokenType> tokens; 151 std::vector<TokenSequenceValue> values; 152 int result; 153 }; 154 155 std::vector<Entry> entries; 156 }; 157