diff --git a/lib/external/pattern_language b/lib/external/pattern_language index 82cce312e..188a8089a 160000 --- a/lib/external/pattern_language +++ b/lib/external/pattern_language @@ -1 +1 @@ -Subproject commit 82cce312ec0845cb2f31f0653beddcb69f077364 +Subproject commit 188a8089a8f23d0cdacc0f6c38384e4f8fe93ef1 diff --git a/plugins/builtin/include/content/views/view_pattern_editor.hpp b/plugins/builtin/include/content/views/view_pattern_editor.hpp index 691f89709..da53202a4 100644 --- a/plugins/builtin/include/content/views/view_pattern_editor.hpp +++ b/plugins/builtin/include/content/views/view_pattern_editor.hpp @@ -204,6 +204,7 @@ namespace hex::plugin::builtin { std::mutex m_logMutex; PerProvider> m_lastEvaluationError; + PerProvider> m_lastCompileError; PerProvider> m_lastEvaluationOutVars; PerProvider> m_patternVariables; PerProvider> m_sections; diff --git a/plugins/builtin/source/content/views/view_data_inspector.cpp b/plugins/builtin/source/content/views/view_data_inspector.cpp index 7510b3912..970e105a7 100644 --- a/plugins/builtin/source/content/views/view_data_inspector.cpp +++ b/plugins/builtin/source/content/views/view_data_inspector.cpp @@ -135,7 +135,7 @@ namespace hex::plugin::builtin { // Execute the inspector file if (!inspectorCode.empty()) { - if (m_runtime.executeString(inspectorCode, {}, inVariables, true)) { + if (m_runtime.executeString(inspectorCode, pl::api::Source::DefaultSource, {}, inVariables, true)) { // Loop over patterns produced by the runtime const auto &patterns = m_runtime.getPatterns(); diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 8e30b44d1..d8446d470 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -43,7 +43,7 @@ namespace hex::plugin::builtin { static TextEditor::LanguageDefinition langDef; if (!initialized) { constexpr static std::array keywords = { - "using", "struct", "union", "enum", "bitfield", "be", "le", "if", "else", "match", "false", "true", "this", "parent", "addressof", "sizeof", "typenameof", "$", "while", "for", "fn", "return", "break", "continue", "namespace", "in", "out", "ref", "null", "const", "unsigned", "signed", "try", "catch" + "using", "struct", "union", "enum", "bitfield", "be", "le", "if", "else", "match", "false", "true", "this", "parent", "addressof", "sizeof", "typenameof", "$", "while", "for", "fn", "return", "break", "continue", "namespace", "in", "out", "ref", "null", "const", "unsigned", "signed", "try", "catch", "import", "as" }; for (auto &k : keywords) langDef.mKeywords.insert(k); @@ -1255,26 +1255,31 @@ namespace hex::plugin::builtin { if (!m_lastEvaluationProcessed) { if (!m_lastEvaluationResult) { + const auto processMessage = [](const auto &message) { + auto lines = wolv::util::splitString(message, "\n"); + + std::ranges::transform(lines, lines.begin(), [](auto line) { + if (line.size() >= 128) + line = wolv::util::trim(line); + + return hex::limitStringLength(line, 128); + }); + + return wolv::util::combineStrings(lines, "\n"); + }; + + TextEditor::ErrorMarkers errorMarkers; if (m_lastEvaluationError->has_value()) { - const auto message = [this]{ - const auto &message = (*m_lastEvaluationError)->message; - auto lines = wolv::util::splitString(message, "\n"); - - std::ranges::transform(lines, lines.begin(), [](auto line) { - if (line.size() >= 128) - line = wolv::util::trim(line); - - return hex::limitStringLength(line, 128); - }); - - return wolv::util::combineStrings(lines, "\n"); - }(); - - const TextEditor::ErrorMarkers errorMarkers = { - { (*m_lastEvaluationError)->line, message } - }; - m_textEditor.SetErrorMarkers(errorMarkers); + errorMarkers[(*m_lastEvaluationError)->line] = processMessage((*m_lastEvaluationError)->message); } + + if (!m_lastCompileError->empty()) { + for (const auto &error : *m_lastCompileError) { + errorMarkers[error.getLocation().line] = processMessage(error.getMessage()); + } + } + + m_textEditor.SetErrorMarkers(errorMarkers); } else { for (auto &[name, variable] : *m_patternVariables) { if (variable.outVariable && m_lastEvaluationOutVars->contains(name)) @@ -1385,14 +1390,13 @@ namespace hex::plugin::builtin { if (!file.isValid()) continue; - try { - auto &preprocessor = runtime.getInternals().preprocessor; - auto ret = preprocessor->preprocess(runtime, file.readString()); - if (!ret.has_value()) { - log::warn("Failed to preprocess file {} during MIME analysis: {}", entry.path().string(), preprocessor->getError()->what()); - } - } catch (pl::core::err::PreprocessorError::Exception &e) { - log::warn("Failed to preprocess file {} during MIME analysis: {}", entry.path().string(), e.what()); + auto &preprocessor = runtime.getInternals().preprocessor; + + pl::api::Source source(file.readString()); + + auto ret = preprocessor->preprocess(&runtime, &source); + if (ret.hasErrs()) { + log::warn("Failed to preprocess file {} during MIME analysis", entry.path().string()); } if (foundCorrectType) @@ -1488,7 +1492,7 @@ namespace hex::plugin::builtin { m_runningParsers += 1; ContentRegistry::PatternLanguage::configureRuntime(*m_editorRuntime, nullptr); - const auto &ast = m_editorRuntime->parseString(code); + const auto &ast = m_editorRuntime->parseString(code, pl::api::Source::DefaultSource); auto &patternVariables = m_patternVariables.get(provider); auto oldPatternVariables = std::move(patternVariables); @@ -1616,9 +1620,10 @@ namespace hex::plugin::builtin { }; - m_lastEvaluationResult = runtime.executeString(code, envVars, inVariables); + m_lastEvaluationResult = runtime.executeString(code, pl::api::Source::DefaultSource, envVars, inVariables); if (!m_lastEvaluationResult) { *m_lastEvaluationError = runtime.getError(); + *m_lastCompileError = runtime.getCompileErrors(); } TaskManager::doLater([code] { diff --git a/plugins/ui/source/ui/pattern_drawer.cpp b/plugins/ui/source/ui/pattern_drawer.cpp index 31d824ffd..3728ed76b 100644 --- a/plugins/ui/source/ui/pattern_drawer.cpp +++ b/plugins/ui/source/ui/pattern_drawer.cpp @@ -162,22 +162,19 @@ namespace hex::ui { char c = filter[i]; if (i < filter.size() - 1 && c == '=' && filter[i + 1] == '=') { - try { - pl::core::Lexer lexer; + pl::core::Lexer lexer; - auto source = filter.substr(i + 2); - auto tokens = lexer.lex(filter.substr(i + 2), filter.substr(i + 2)); + pl::api::Source source(filter.substr(i + 2)); + auto tokens = lexer.lex(&source); - if (!tokens.has_value() || tokens->size() != 2) - return std::nullopt; - - auto literal = std::get_if(&tokens->front().value); - if (literal == nullptr) - return std::nullopt; - result.value = *literal; - } catch (pl::core::err::LexerError &) { + if (!tokens.isOk() || tokens.unwrap().size() != 2) return std::nullopt; - } + + auto literal = std::get_if(&tokens.unwrap().front().value); + if (literal == nullptr) + return std::nullopt; + result.value = *literal; + break; } else if (c == '.') { result.path.emplace_back();