Added pragmas to pattern language

This commit is contained in:
WerWolv 2020-11-21 14:39:01 +01:00
parent 28bb28b79c
commit fb85f272a1
2 changed files with 79 additions and 14 deletions

View File

@ -4,9 +4,11 @@
#include "token.hpp" #include "token.hpp"
#include <string> #include <functional>
#include <utility>
#include <set> #include <set>
#include <string>
#include <unordered_map>
#include <utility>
namespace hex::lang { namespace hex::lang {
@ -14,10 +16,16 @@ namespace hex::lang {
public: public:
Preprocessor(); Preprocessor();
std::pair<Result, std::string> preprocess(const std::string& code, bool applyDefines = true); std::pair<Result, std::string> preprocess(const std::string& code, bool initialRun = true);
void addPragmaHandler(std::string pragmaType, std::function<bool(std::string)> function);
void addDefaultPragramHandlers();
private: private:
std::unordered_map<std::string, std::function<bool(std::string)>> m_pragmaHandlers;
std::set<std::pair<std::string, std::string>> m_defines; std::set<std::pair<std::string, std::string>> m_defines;
std::set<std::pair<std::string, std::string>> m_pragmas;
}; };
} }

View File

@ -6,11 +6,13 @@ namespace hex::lang {
} }
std::pair<Result, std::string> Preprocessor::preprocess(const std::string& code, bool applyDefines) { std::pair<Result, std::string> Preprocessor::preprocess(const std::string& code, bool initialRun) {
u32 offset = 0; u32 offset = 0;
if (applyDefines) if (initialRun) {
this->m_defines.clear(); this->m_defines.clear();
this->m_pragmas.clear();
}
std::string output; std::string output;
output.reserve(code.length()); output.reserve(code.length());
@ -76,45 +78,100 @@ namespace hex::lang {
std::string defineName; std::string defineName;
while (!std::isblank(code[offset])) { while (!std::isblank(code[offset])) {
defineName += code[offset]; defineName += code[offset];
offset += 1;
if (offset >= code.length() || code[offset] == '\n' || code[offset] == '\r') if (offset >= code.length() || code[offset] == '\n' || code[offset] == '\r')
return { ResultPreprocessingError, "" }; return { ResultPreprocessingError, "" };
offset += 1;
} }
while (std::isblank(code[offset])) while (std::isblank(code[offset]))
offset += 1; offset += 1;
std::string replaceValue; std::string replaceValue;
do { while (code[offset] != '\n' && code[offset] != '\r') {
if (offset >= code.length()) if (offset >= code.length())
return { ResultPreprocessingError, "" }; return { ResultPreprocessingError, "" };
replaceValue += code[offset]; replaceValue += code[offset];
offset += 1; offset += 1;
} while (code[offset] != '\n' && code[offset] != '\r'); }
if (replaceValue.empty())
return { ResultPreprocessingError, "" };
this->m_defines.emplace(defineName, replaceValue); this->m_defines.emplace(defineName, replaceValue);
} } else if (code.substr(offset, 6) == "pragma") {
offset += 6;
while (std::isblank(code[offset]))
offset += 1;
std::string pragmaKey;
while (!std::isblank(code[offset])) {
pragmaKey += code[offset];
if (offset >= code.length() || code[offset] == '\n' || code[offset] == '\r')
return { ResultPreprocessingError, "" };
offset += 1;
}
while (std::isblank(code[offset]))
offset += 1;
std::string pragmaValue;
while (code[offset] != '\n' && code[offset] != '\r') {
if (offset >= code.length())
return { ResultPreprocessingError, "" };
pragmaValue += code[offset];
offset += 1;
}
if (pragmaValue.empty())
return { ResultPreprocessingError, "" };
this->m_pragmas.emplace(pragmaKey, pragmaValue);
} else
return { ResultPreprocessingError, "" };
} }
output += code[offset]; output += code[offset];
offset += 1; offset += 1;
} }
if (applyDefines) { if (initialRun) {
// Apply defines
for (const auto &[define, value] : this->m_defines) { for (const auto &[define, value] : this->m_defines) {
s32 index = 0; s32 index = 0;
while((index = output.find(define, index)) != std::string::npos) { while((index = output.find(define, index)) != std::string::npos) {
if (index > 0) { output.replace(index, define.length(), value);
output.replace(index, define.length(), value); index += value.length();
index += value.length();
}
} }
} }
// Handle pragmas
for (const auto &[type, value] : this->m_pragmas) {
if (this->m_pragmaHandlers.contains(type)) {
if (!this->m_pragmaHandlers[type](value))
return { ResultPreprocessingError, { } };
} else
return { ResultPreprocessingError, { } };
}
} }
return { ResultSuccess, output }; return { ResultSuccess, output };
} }
void Preprocessor::addPragmaHandler(std::string pragmaType, std::function<bool(std::string)> function) {
if (!this->m_pragmaHandlers.contains(pragmaType))
this->m_pragmaHandlers.emplace(pragmaType, function);
}
void Preprocessor::addDefaultPragramHandlers() {
this->addPragmaHandler("MIME", [](std::string value) {
return !std::all_of(value.begin(), value.end(), isspace) && !value.ends_with('\n') && !value.ends_with('\r');
});
}
} }