Fixed pattern language being basically completely broken

This commit is contained in:
WerWolv 2021-01-23 14:00:09 +01:00
parent 8e46751e98
commit 51d9d37d1a
5 changed files with 56 additions and 61 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}
}
}