Skip to content

Commit

Permalink
feat(name resolution): improving unbound error messages by suggesting…
Browse files Browse the repository at this point in the history
… names from the language too
  • Loading branch information
SuperFola committed Dec 4, 2024
1 parent 28060af commit 98a3126
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 19 deletions.
2 changes: 1 addition & 1 deletion lib/std
Submodule std updated 1 files
+5 −5 Math.ark
31 changes: 18 additions & 13 deletions src/arkreactor/Compiler/NameResolution/NameResolutionPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,15 +269,14 @@ namespace Ark::internal
// remove the old name node, to avoid false positive when looking for unbound symbols
if (!old_name.empty())
{
const auto it = std::ranges::find_if(m_symbol_nodes, [&old_name, &symbol](const Node& sym_node) -> bool {
auto it = std::ranges::find_if(m_symbol_nodes, [&old_name, &symbol](const Node& sym_node) -> bool {
return sym_node.string() == old_name &&
sym_node.col() == symbol.col() &&
sym_node.line() == symbol.line() &&
sym_node.filename() == symbol.filename();
});
if (it != m_symbol_nodes.end())
{
m_logger.info("Found {}, replacing it with {}", old_name, name);
it->setString(name);
return;
}
Expand Down Expand Up @@ -329,20 +328,26 @@ namespace Ark::internal

std::string NameResolutionPass::offerSuggestion(const std::string& str) const
{
std::string suggestion;
// our suggestion shouldn't require more than half the string to change
std::size_t suggestion_distance = str.size() / 2;

for (const std::string& symbol : m_defined_symbols)
{
const std::size_t current_distance = Utils::levenshteinDistance(str, symbol);
if (current_distance <= suggestion_distance)
auto iterate = [](const std::string& word, const std::unordered_set<std::string>& dict) -> std::string {
std::string suggestion;
// our suggestion shouldn't require more than half the string to change
std::size_t suggestion_distance = word.size() / 2;
for (const std::string& symbol : dict)
{
suggestion_distance = current_distance;
suggestion = symbol;
const std::size_t current_distance = Utils::levenshteinDistance(word, symbol);
if (current_distance <= suggestion_distance)
{
suggestion_distance = current_distance;
suggestion = symbol;
}
}
}
return suggestion;
};

std::string suggestion = iterate(str, m_defined_symbols);
// look for a suggestion related to language builtins
if (suggestion.empty())
suggestion = iterate(str, m_language_symbols);
// look for a suggestion related to a namespace change
if (suggestion.empty())
{
Expand Down
4 changes: 2 additions & 2 deletions tests/unittests/DiagnosticsSuite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ ut::suite<"Diagnostics"> diagnostics_suite = [] {
should("generate an error message at compile time for compileTime/" + data.stem) = [&] {
try
{
mut(state).doFile(data.path, features);
expect(0 == 1); // we shouldn't be here, the compilation has to fail
const bool ok = mut(state).doFile(data.path, features);
expect(!ok) << fatal; // we shouldn't be here, the compilation has to fail
}
catch (const Ark::CodeError& e)
{
Expand Down
12 changes: 9 additions & 3 deletions tests/unittests/LangSuite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@ ut::suite<"Lang"> lang_suite = [] {
"[run arkscript unittests]"_test = [] {
Ark::State state({ std::filesystem::path(ARK_TESTS_ROOT "/lib/") });

should("compile the resource without any error") = [&] {
expect(mut(state).doFile(get_resource_path("LangSuite/unittests.ark")));
};
try
{
const bool ok = mut(state).doFile(get_resource_path("LangSuite/unittests.ark"));
expect(ok) << fatal << "compilation failed";
}
catch (const Ark::CodeError&)
{
expect(false) << fatal << "encountered an exception while compiling";
}

Ark::VM vm(state);
should("return exit code 0") = [&] {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(let a b)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
At b @ 1:9
1 | (let a b)
| ^~~~~~~~~
2 |
Unbound variable error "b" (variable is used but not defined)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
(let bar 12)
(let a ber)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
At ber @ 2:12
1 | (let bar 12)
2 | (let a ber)
| ^~~~~~~~~~~
3 |
Unbound variable error "ber" (did you mean "bar"?)

0 comments on commit 98a3126

Please sign in to comment.