From 881dc8975a3dab2e2182e9b1ead508594a7a0582 Mon Sep 17 00:00:00 2001 From: Robert Bendun Date: Thu, 18 Aug 2022 20:38:21 +0200 Subject: [PATCH] Missing variable error implementation --- src/errors.cc | 12 ++++++++++++ src/interpreter.cc | 11 +++++++++-- src/musique.hh | 8 ++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/errors.cc b/src/errors.cc index 04cb52f..35f48f7 100644 --- a/src/errors.cc +++ b/src/errors.cc @@ -134,6 +134,7 @@ void unreachable(Location loc) std::ostream& operator<<(std::ostream& os, Error const& err) { std::string_view short_description = visit(Overloaded { + [](errors::Missing_Variable const&) { return "Cannot find variable"; }, [](errors::Failed_Numeric_Parsing const&) { return "Failed to parse a number"; }, [](errors::Not_Callable const&) { return "Value not callable"; }, [](errors::Undefined_Operator const&) { return "Undefined operator"; }, @@ -154,6 +155,17 @@ std::ostream& operator<<(std::ostream& os, Error const& err) auto const loc = err.location; visit(Overloaded { + [&](errors::Missing_Variable const& err) { + os << "I encountered '" << err.name << "' that looks like variable but\n"; + os << "I can't find it in surrounding scope or in one of parent's scopes\n"; + os << "\n"; + + Lines::the.print(os, std::string(loc->filename), loc->line, loc->line); + + os << "\n"; + os << "Variables can only be references in scope (block) where they been created\n"; + os << "or from parent blocks to variable block\n"; + }, [&](errors::Unrecognized_Character const& err) { os << "I encountered character in the source code that was not supposed to be here.\n"; os << " Character Unicode code: U+" << std::hex << err.invalid_character << '\n'; diff --git a/src/interpreter.cc b/src/interpreter.cc index 31bd055..3d32863 100644 --- a/src/interpreter.cc +++ b/src/interpreter.cc @@ -749,8 +749,15 @@ Result Interpreter::eval(Ast &&ast) return Value::from(std::move(ast.token.source).substr(1)); } - auto const value = env->find(std::string(ast.token.source)); - assert(value, "Missing variable error is not implemented yet: variable: "s + std::string(ast.token.source)); + auto name = std::string(ast.token.source); + + auto const value = env->find(name); + if (!value) { + return Error { + .details = errors::Missing_Variable { .name = std::move(name) }, + .location = ast.location + }; + } return *value; } return Value{}; diff --git a/src/musique.hh b/src/musique.hh index 59914b7..70ae4eb 100644 --- a/src/musique.hh +++ b/src/musique.hh @@ -104,6 +104,13 @@ namespace errors std::vector possibilities; }; + /// When user tries to use variable that has not been defined yet. + struct Missing_Variable + { + /// Name of variable + std::string name; + }; + /// Collection of messages that are considered internal and should not be printed to the end user. namespace internal { @@ -126,6 +133,7 @@ namespace errors Expected_Expression_Separator_Before, Failed_Numeric_Parsing, Literal_As_Identifier, + Missing_Variable, Not_Callable, Undefined_Operator, Unexpected_Empty_Source,