Improved interactive mode interaction with errors

This commit is contained in:
Robert Bendun 2022-08-21 20:24:49 +02:00
parent cb5eedb2a5
commit 43555cbc1c
5 changed files with 22 additions and 9 deletions

View File

@ -457,7 +457,7 @@ struct Lines
void add_file(std::string filename, std::string_view source);
/// Add single line into file (REPL usage)
void add_line(std::string const& filename, std::string_view source);
void add_line(std::string const& filename, std::string_view source, unsigned line_number);
/// Print selected region
void print(std::ostream& os, std::string const& file, unsigned first_line, unsigned last_line) const;
@ -604,7 +604,7 @@ struct Parser
/// Parses whole source code producing Ast or Error
/// using Parser structure internally
static Result<Ast> parse(std::string_view source, std::string_view filename);
static Result<Ast> parse(std::string_view source, std::string_view filename, unsigned line_number = 0);
/// Parse sequence, collection of expressions
Result<Ast> parse_sequence();

View File

@ -312,7 +312,12 @@ std::ostream& operator<<(std::ostream& os, Error const& err)
}
}
},
[&](errors::Undefined_Operator const&) { unimplemented(); },
[&](errors::Undefined_Operator const& err) {
os << "I encountered '" << err.op << "' that looks like operator but it isn't one.\n";
os << '\n';
print_error_line(loc);
},
[&](errors::Unexpected_Keyword const&) { unimplemented(); },
}, err.details);

View File

@ -21,9 +21,12 @@ void Lines::add_file(std::string filename, std::string_view source)
}
}
void Lines::add_line(std::string const& filename, std::string_view source)
void Lines::add_line(std::string const& filename, std::string_view source, unsigned line_number)
{
lines[filename].push_back(source);
assert(line_number != 0, "Line number = 0 is invalid");
if (lines[filename].size() <= line_number)
lines[filename].resize(line_number);
lines[filename][line_number - 1] = source;
}
void Lines::print(std::ostream &os, std::string const& filename, unsigned first_line, unsigned last_line) const

View File

@ -17,6 +17,7 @@ namespace fs = std::filesystem;
static bool ast_only_mode = false;
static bool enable_repl = false;
static unsigned repl_line_number = 1;
#define Ignore(Call) do { auto const ignore_ ## __LINE__ = (Call); (void) ignore_ ## __LINE__; } while(0)
@ -150,7 +151,7 @@ struct Runner
/// Run given source
Result<void> run(std::string_view source, std::string_view filename, bool output = false)
{
auto ast = Try(Parser::parse(source, filename));
auto ast = Try(Parser::parse(source, filename, repl_line_number));
if (ast_only_mode) {
dump(ast);
@ -264,8 +265,9 @@ static Result<void> Main(std::span<char const*> args)
for (auto const& [is_file, argument] : runnables) {
if (!is_file) {
Lines::the.add_line("<arguments>", argument);
Lines::the.add_line("<arguments>", argument, repl_line_number);
Try(runner.run(argument, "<arguments>"));
repl_line_number++;
continue;
}
auto path = argument;
@ -286,6 +288,7 @@ static Result<void> Main(std::span<char const*> args)
}
if (runnables.empty() || enable_repl) {
repl_line_number = 1;
enable_repl = true;
bestlineSetCompletionCallback(completion);
for (;;) {
@ -317,12 +320,13 @@ static Result<void> Main(std::span<char const*> args)
continue;
}
Lines::the.add_line("<repl>", raw);
Lines::the.add_line("<repl>", raw, repl_line_number);
auto result = runner.run(raw, "<repl>", true);
if (not result.has_value()) {
std::cout << std::flush;
std::cerr << result.error() << std::flush;
}
repl_line_number++;
// We don't free input line since there could be values that still relay on it
}
}

View File

@ -44,10 +44,11 @@ static Result<std::vector<Ast>> parse_many(
std::optional<Token::Type> separator,
At_Least at_least);
Result<Ast> Parser::parse(std::string_view source, std::string_view filename)
Result<Ast> Parser::parse(std::string_view source, std::string_view filename, unsigned line_number)
{
Lexer lexer{source};
lexer.location.filename = filename;
lexer.location.line = line_number;
Parser parser;
for (;;) {