Fixed pattern language being basically completely broken
This commit is contained in:
parent
8e46751e98
commit
51d9d37d1a
@ -17,13 +17,14 @@ namespace hex::lang {
|
||||
|
||||
class Evaluator {
|
||||
public:
|
||||
Evaluator(prv::Provider* &provider, std::endian defaultDataEndian = std::endian::native);
|
||||
Evaluator() = default;
|
||||
|
||||
std::optional<std::vector<PatternData*>> evaluate(const std::vector<ASTNode*>& ast);
|
||||
|
||||
LogConsole& getConsole() { return this->m_console; }
|
||||
|
||||
void setDefaultEndian(std::endian endian) { this->m_defaultDataEndian = endian; }
|
||||
void setProvider(prv::Provider *provider) { this->m_provider = provider; }
|
||||
[[nodiscard]] std::endian getCurrentEndian() const { return this->m_endianStack.back(); }
|
||||
|
||||
PatternData* patternFromName(const std::vector<std::string> &name);
|
||||
@ -38,8 +39,8 @@ namespace hex::lang {
|
||||
|
||||
private:
|
||||
std::map<std::string, ASTNode*> m_types;
|
||||
prv::Provider* &m_provider;
|
||||
std::endian m_defaultDataEndian;
|
||||
prv::Provider* m_provider = nullptr;
|
||||
std::endian m_defaultDataEndian = std::endian::native;
|
||||
u64 m_currOffset = 0;
|
||||
std::vector<std::endian> m_endianStack;
|
||||
std::vector<PatternData*> m_globalMembers;
|
||||
|
@ -23,14 +23,14 @@ namespace hex::lang {
|
||||
|
||||
class PatternLanguage {
|
||||
public:
|
||||
PatternLanguage(prv::Provider *provider);
|
||||
PatternLanguage();
|
||||
~PatternLanguage();
|
||||
|
||||
std::optional<std::vector<PatternData*>> executeString(std::string_view string);
|
||||
std::optional<std::vector<PatternData*>> executeFile(std::string_view path);
|
||||
std::optional<std::vector<PatternData*>> executeString(prv::Provider *provider, std::string_view string);
|
||||
std::optional<std::vector<PatternData*>> executeFile(prv::Provider *provider, std::string_view path);
|
||||
|
||||
std::vector<std::pair<LogConsole::Level, std::string>> getConsoleLog();
|
||||
std::optional<std::pair<u32, std::string>> getError();
|
||||
const std::vector<std::pair<LogConsole::Level, std::string>>& getConsoleLog();
|
||||
const std::optional<std::pair<u32, std::string>>& getError();
|
||||
|
||||
private:
|
||||
Preprocessor *m_preprocessor;
|
||||
|
@ -11,10 +11,6 @@
|
||||
|
||||
namespace hex::lang {
|
||||
|
||||
Evaluator::Evaluator(prv::Provider* &provider, std::endian defaultDataEndian)
|
||||
: m_provider(provider), m_defaultDataEndian(defaultDataEndian) {
|
||||
}
|
||||
|
||||
ASTNodeIntegerLiteral* Evaluator::evaluateScopeResolution(ASTNodeScopeResolution *node) {
|
||||
ASTNode *currScope = nullptr;
|
||||
for (const auto &identifier : node->getPath()) {
|
||||
@ -743,6 +739,12 @@ namespace hex::lang {
|
||||
|
||||
std::optional<std::vector<PatternData*>> Evaluator::evaluate(const std::vector<ASTNode *> &ast) {
|
||||
|
||||
this->m_globalMembers.clear();
|
||||
this->m_currMembers.clear();
|
||||
this->m_types.clear();
|
||||
this->m_endianStack.clear();
|
||||
this->m_currOffset = 0;
|
||||
|
||||
try {
|
||||
for (const auto& node : ast) {
|
||||
this->m_endianStack.push_back(this->m_defaultDataEndian);
|
||||
@ -764,13 +766,10 @@ namespace hex::lang {
|
||||
}
|
||||
} catch (LogConsole::EvaluateError &e) {
|
||||
this->getConsole().log(LogConsole::Level::Error, e);
|
||||
this->m_endianStack.clear();
|
||||
|
||||
return { };
|
||||
}
|
||||
|
||||
this->m_endianStack.clear();
|
||||
|
||||
return this->m_globalMembers;
|
||||
}
|
||||
|
||||
|
@ -13,12 +13,27 @@
|
||||
|
||||
namespace hex::lang {
|
||||
|
||||
PatternLanguage::PatternLanguage(prv::Provider *provider) : m_provider(provider) {
|
||||
PatternLanguage::PatternLanguage() {
|
||||
this->m_preprocessor = new Preprocessor();
|
||||
this->m_lexer = new Lexer();
|
||||
this->m_parser = new Parser();
|
||||
this->m_validator = new Validator();
|
||||
this->m_evaluator = new Evaluator(provider);
|
||||
this->m_evaluator = new Evaluator();
|
||||
|
||||
this->m_preprocessor->addPragmaHandler("endian", [this](std::string value) {
|
||||
if (value == "big") {
|
||||
this->m_defaultEndian = std::endian::big;
|
||||
return true;
|
||||
} else if (value == "little") {
|
||||
this->m_defaultEndian = std::endian::little;
|
||||
return true;
|
||||
} else if (value == "native") {
|
||||
this->m_defaultEndian = std::endian::native;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
});
|
||||
this->m_preprocessor->addDefaultPragmaHandlers();
|
||||
}
|
||||
|
||||
PatternLanguage::~PatternLanguage() {
|
||||
@ -30,68 +45,45 @@ namespace hex::lang {
|
||||
}
|
||||
|
||||
|
||||
std::optional<std::vector<PatternData*>> PatternLanguage::executeString(std::string_view string) {
|
||||
std::optional<std::vector<PatternData*>> PatternLanguage::executeString(prv::Provider *provider, std::string_view string) {
|
||||
this->m_currError.reset();
|
||||
this->m_evaluator->getConsole().clear();
|
||||
this->m_evaluator->setProvider(provider);
|
||||
|
||||
hex::lang::Preprocessor preprocessor;
|
||||
|
||||
std::endian defaultEndian;
|
||||
preprocessor.addPragmaHandler("endian", [&defaultEndian](std::string value) {
|
||||
if (value == "big") {
|
||||
defaultEndian = std::endian::big;
|
||||
return true;
|
||||
} else if (value == "little") {
|
||||
defaultEndian = std::endian::little;
|
||||
return true;
|
||||
} else if (value == "native") {
|
||||
defaultEndian = std::endian::native;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
});
|
||||
preprocessor.addDefaultPragmaHandlers();
|
||||
|
||||
auto preprocessedCode = preprocessor.preprocess(string.data());
|
||||
auto preprocessedCode = this->m_preprocessor->preprocess(string.data());
|
||||
if (!preprocessedCode.has_value()) {
|
||||
this->m_currError = preprocessor.getError();
|
||||
this->m_currError = this->m_preprocessor->getError();
|
||||
return { };
|
||||
}
|
||||
|
||||
hex::lang::Lexer lexer;
|
||||
auto tokens = lexer.lex(preprocessedCode.value());
|
||||
auto tokens = this->m_lexer->lex(preprocessedCode.value());
|
||||
if (!tokens.has_value()) {
|
||||
this->m_currError = lexer.getError();
|
||||
this->m_currError = this->m_lexer->getError();
|
||||
return { };
|
||||
}
|
||||
|
||||
hex::lang::Parser parser;
|
||||
auto ast = parser.parse(tokens.value());
|
||||
auto ast = this->m_parser->parse(tokens.value());
|
||||
if (!ast.has_value()) {
|
||||
this->m_currError = parser.getError();
|
||||
this->m_currError = this->m_parser->getError();
|
||||
return { };
|
||||
}
|
||||
|
||||
SCOPE_EXIT( for(auto &node : ast.value()) delete node; );
|
||||
|
||||
hex::lang::Validator validator;
|
||||
auto validatorResult = validator.validate(ast.value());
|
||||
auto validatorResult = this->m_validator->validate(ast.value());
|
||||
if (!validatorResult) {
|
||||
this->m_currError = validator.getError();
|
||||
this->m_currError = this->m_validator->getError();
|
||||
return { };
|
||||
}
|
||||
|
||||
auto provider = SharedData::currentProvider;
|
||||
hex::lang::Evaluator evaluator(provider, defaultEndian);
|
||||
|
||||
auto patternData = evaluator.evaluate(ast.value());
|
||||
auto patternData = this->m_evaluator->evaluate(ast.value());
|
||||
if (!patternData.has_value())
|
||||
return { };
|
||||
|
||||
return patternData.value();
|
||||
}
|
||||
|
||||
std::optional<std::vector<PatternData*>> PatternLanguage::executeFile(std::string_view path) {
|
||||
std::optional<std::vector<PatternData*>> PatternLanguage::executeFile(prv::Provider *provider, std::string_view path) {
|
||||
FILE *file = fopen(path.data(), "r");
|
||||
if (file == nullptr)
|
||||
return { };
|
||||
@ -105,15 +97,15 @@ namespace hex::lang {
|
||||
|
||||
fclose(file);
|
||||
|
||||
return this->executeString(code);
|
||||
return this->executeString(provider, code);
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::pair<LogConsole::Level, std::string>> PatternLanguage::getConsoleLog() {
|
||||
const std::vector<std::pair<LogConsole::Level, std::string>>& PatternLanguage::getConsoleLog() {
|
||||
return this->m_evaluator->getConsole().getLog();
|
||||
}
|
||||
|
||||
std::optional<std::pair<u32, std::string>> PatternLanguage::getError() {
|
||||
const std::optional<std::pair<u32, std::string>>& PatternLanguage::getError() {
|
||||
return this->m_currError;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ namespace hex {
|
||||
|
||||
|
||||
ViewPattern::ViewPattern(std::vector<lang::PatternData*> &patternData) : View("Pattern"), m_patternData(patternData) {
|
||||
this->m_patternLanguageRuntime = new lang::PatternLanguage(SharedData::currentProvider);
|
||||
this->m_patternLanguageRuntime = new lang::PatternLanguage();
|
||||
|
||||
this->m_textEditor.SetLanguageDefinition(PatternLanguage());
|
||||
this->m_textEditor.SetShowWhitespaces(false);
|
||||
@ -335,16 +335,19 @@ namespace hex {
|
||||
this->m_console.clear();
|
||||
this->postEvent(Events::PatternChanged);
|
||||
|
||||
auto result = this->m_patternLanguageRuntime->executeString(buffer);
|
||||
auto result = this->m_patternLanguageRuntime->executeString(SharedData::currentProvider, buffer);
|
||||
|
||||
if (!result.has_value()) {
|
||||
this->m_textEditor.SetErrorMarkers({ this->m_patternLanguageRuntime->getError().value() });
|
||||
auto error = this->m_patternLanguageRuntime->getError();
|
||||
if (error.has_value()) {
|
||||
this->m_textEditor.SetErrorMarkers({ error.value() });
|
||||
}
|
||||
|
||||
this->m_console = this->m_patternLanguageRuntime->getConsoleLog();
|
||||
|
||||
this->m_patternData = result.value();
|
||||
View::postEvent(Events::PatternChanged);
|
||||
if (result.has_value()) {
|
||||
this->m_patternData = std::move(result.value());
|
||||
View::postEvent(Events::PatternChanged);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user