diff --git a/CLexer.cpp b/CLexer.cpp index 35ed4f5..eafc62f 100644 --- a/CLexer.cpp +++ b/CLexer.cpp @@ -33,8 +33,8 @@ int CLexer::lex(char* start, char* end, TokenList& tokens) { CLexer::Token currentToken; start = _parseToken(start, end, currentToken); - if (currentToken.type != CLexer::COMMENT) - tokens.push_back(currentToken); + //if (currentToken.type != CLexer::COMMENT) + tokens.push_back(currentToken); if (start == end) return 0; } @@ -128,7 +128,7 @@ char* CLexer::_parseLineComment(char* start, char* end, CLexer::Token& out) ++start; if (start == end) return start; - out.value += start; + out.value += *start; if (*start == '\n') return start; } @@ -154,6 +154,7 @@ char* CLexer::_parseBlockComment(char* start, char* end, CLexer::Token& out) if (*start == '/') { out.value += *start; + ++start; break; } else diff --git a/CPreprocessor.cpp b/CPreprocessor.cpp index 0a72991..60547a5 100644 --- a/CPreprocessor.cpp +++ b/CPreprocessor.cpp @@ -72,6 +72,16 @@ void CPreprocessor::registerPragma(const std::string& name, std::function cb) +{ + std::string pre = "#" + name; + HookIterator iter = m_registeredHooks.find(pre); + if (iter != m_registeredHooks.end()) + m_registeredHooks.erase(iter); + + m_registeredHooks[pre] = cb; +} + std::string CPreprocessor::finalizedSource() { std::string ret; @@ -126,7 +136,7 @@ std::string CPreprocessor::_loadSource(const std::string& filename) return code; } -void CPreprocessor::_advanceList(CLexer::TokenList& tokens) +void CPreprocessor::advanceList(CLexer::TokenList& tokens) { tokens.pop_front(); while(true) @@ -243,6 +253,12 @@ void CPreprocessor::preprocessRecursive(const std::string& filename, const std:: _parseWarning(directive, defineTable); else if (value == "#error") _parseError(directive, defineTable); + else + { + HookIterator iter = m_registeredHooks.find(value); + if (iter != m_registeredHooks.end() && m_registeredHooks[value]) + m_registeredHooks[value](directive, defineTable); + } } else if (begin->type == CLexer::IDENTIFIER) { @@ -390,7 +406,7 @@ CLexer::TokenIterator CPreprocessor::_expandDefine(CLexer::TokenIterator begin, void CPreprocessor::_parseDefine(CPreprocessor::DefineTable& defineTable, CLexer::TokenList& tokens) { - _advanceList(tokens); + advanceList(tokens); if (tokens.empty()) { printErrorMessage("Define directive without arguments"); @@ -408,7 +424,7 @@ void CPreprocessor::_parseDefine(CPreprocessor::DefineTable& defineTable, CLexer printErrorMessage(name.value + " already defined."); return; } - _advanceList(tokens); + advanceList(tokens); DefineEntry def; @@ -417,14 +433,14 @@ void CPreprocessor::_parseDefine(CPreprocessor::DefineTable& defineTable, CLexer if (tokens.begin()->type == CLexer::PREPROCESSOR && tokens.begin()->value == "#") { // macro has arguments - _advanceList(tokens); + advanceList(tokens); if (tokens.empty() || tokens.begin()->value != "(") { printErrorMessage("Expected arguments"); return; } - _advanceList(tokens); + advanceList(tokens); int argCount = 0; while (!tokens.empty() && tokens.begin()->value != ")") @@ -436,9 +452,9 @@ void CPreprocessor::_parseDefine(CPreprocessor::DefineTable& defineTable, CLexer } def.arguments[tokens.begin()->value] = argCount; - _advanceList(tokens); + advanceList(tokens); if (!tokens.empty() && tokens.begin()->value == ",") - _advanceList(tokens); + advanceList(tokens); argCount++; } @@ -449,7 +465,7 @@ void CPreprocessor::_parseDefine(CPreprocessor::DefineTable& defineTable, CLexer printErrorMessage("Expected closing parentheses"); return; } - _advanceList(tokens); + advanceList(tokens); } else { @@ -500,7 +516,7 @@ CLexer::TokenIterator CPreprocessor::_parseIfDef(CLexer::TokenIterator begin, CL void CPreprocessor::_parseIf(CLexer::TokenList& directive, std::string& nameOut) { - _advanceList(directive); + advanceList(directive); if (directive.empty()) { printErrorMessage("Expected argument."); @@ -508,14 +524,14 @@ void CPreprocessor::_parseIf(CLexer::TokenList& directive, std::string& nameOut) } nameOut = directive.begin()->value; - _advanceList(directive); + advanceList(directive); if (!directive.empty()) printErrorMessage("Too many arguments."); } void CPreprocessor::_parsePragma(CLexer::TokenList& args) { - _advanceList(args); + advanceList(args); if (args.empty()) { printErrorMessage("Pragmas need arguments."); @@ -523,7 +539,7 @@ void CPreprocessor::_parsePragma(CLexer::TokenList& args) } std::string pragmaName = args.begin()->value; - _advanceList(args); + advanceList(args); std::string pragmaArgs; if (!args.empty()) @@ -531,7 +547,7 @@ void CPreprocessor::_parsePragma(CLexer::TokenList& args) if (args.begin()->type != CLexer::STRING) printErrorMessage("Pragma parameter should be a string literal"); pragmaArgs = removeQuotes(args.begin()->value); - _advanceList(args); + advanceList(args); } if (!args.empty()) printErrorMessage("Too many paremeters for pragma."); @@ -573,7 +589,7 @@ std::string CPreprocessor::_expandMessage(DefineTable& defineTable, CLexer::Toke void CPreprocessor::_parseWarning(CLexer::TokenList& args, DefineTable& defineTable) { - _advanceList(args); + advanceList(args); if (args.empty()) { printErrorMessage("Warnings need messages."); @@ -586,7 +602,7 @@ void CPreprocessor::_parseWarning(CLexer::TokenList& args, DefineTable& defineTa void CPreprocessor::_parseError(CLexer::TokenList& args, CPreprocessor::DefineTable& defineTable) { - _advanceList(args); + advanceList(args); if (args.empty()) { printErrorMessage("Errors need messages."); diff --git a/CPreprocessor.hpp b/CPreprocessor.hpp index 801c28d..562446a 100644 --- a/CPreprocessor.hpp +++ b/CPreprocessor.hpp @@ -32,14 +32,19 @@ public: typedef DefineTable::iterator DefineIterator; typedef std::map > PragmaMap; typedef PragmaMap::iterator PragmaIterator; + typedef std::map > HookMap; + typedef HookMap::iterator HookIterator; void define(const std::string& def); void undefine(const std::string& def); void registerPragma(const std::string& name, std::function cb); + void registerHook(const std::string& name, std::function cb); std::string finalizedSource(); int preprocessFile(const std::string& filename); int preprocessCode(const std::string& filename, const std::string& code); + + static void advanceList(CLexer::TokenList& tokens); private: std::string _loadSource(const std::string& filename); void printErrorMessage(const std::string& errMsg); @@ -48,7 +53,6 @@ private: void preprocessRecursive(const std::string& filename, const std::string& code, CLexer::TokenList& tokens, DefineTable& defineTable); void callPragma(const std::string& name, const PragmaInstance& parms); - void _advanceList(CLexer::TokenList& tokens); CLexer::TokenIterator _findToken(CLexer::TokenIterator begin, CLexer::TokenIterator end, CLexer::TokenType type); CLexer::TokenIterator _parseStatement(CLexer::TokenIterator begin, CLexer::TokenIterator end, CLexer::TokenList& dest); CLexer::TokenIterator _parseDefineArguments(CLexer::TokenIterator begin, CLexer::TokenIterator end, CLexer::TokenList& tokens, std::vector& args); @@ -63,6 +67,7 @@ private: DefineTable m_applicationDefined; PragmaMap m_registeredPragmas; + HookMap m_registeredHooks; CLineTranslator m_lineTranslator; CLexer::TokenList m_tokens; diff --git a/main.cpp b/main.cpp index 1ff764f..afa7c84 100644 --- a/main.cpp +++ b/main.cpp @@ -12,9 +12,21 @@ void printTokenList(CLexer::TokenList& out) std::cout << std::endl; } + +void linkInstancePreprocessor(CLexer::TokenList& tokens, CPreprocessor::DefineTable& defineTable) +{ + (void)(defineTable); + CPreprocessor::advanceList(tokens); + if (tokens.size() == 0) + return; + + std::cout << tokens.begin()->value << std::endl; +} + int main() { CPreprocessor preprocessor; + preprocessor.registerHook("link_instance", linkInstancePreprocessor); preprocessor.preprocessFile("main.as"); std::cout << preprocessor.finalizedSource() << std::endl; return 0;