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