mirror of https://github.com/WerWolv/ImHex.git
Added pragmas to pattern language
This commit is contained in:
parent
28bb28b79c
commit
fb85f272a1
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -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');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue