Improved interactive mode interaction with errors
This commit is contained in:
parent
cb5eedb2a5
commit
43555cbc1c
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
10
src/main.cc
10
src/main.cc
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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 (;;) {
|
||||
|
Loading…
Reference in New Issue
Block a user