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);
|
void add_file(std::string filename, std::string_view source);
|
||||||
|
|
||||||
/// Add single line into file (REPL usage)
|
/// 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
|
/// Print selected region
|
||||||
void print(std::ostream& os, std::string const& file, unsigned first_line, unsigned last_line) const;
|
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
|
/// Parses whole source code producing Ast or Error
|
||||||
/// using Parser structure internally
|
/// 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
|
/// Parse sequence, collection of expressions
|
||||||
Result<Ast> parse_sequence();
|
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(); },
|
[&](errors::Unexpected_Keyword const&) { unimplemented(); },
|
||||||
}, err.details);
|
}, 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
|
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 ast_only_mode = false;
|
||||||
static bool enable_repl = 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)
|
#define Ignore(Call) do { auto const ignore_ ## __LINE__ = (Call); (void) ignore_ ## __LINE__; } while(0)
|
||||||
|
|
||||||
@ -150,7 +151,7 @@ struct Runner
|
|||||||
/// Run given source
|
/// Run given source
|
||||||
Result<void> run(std::string_view source, std::string_view filename, bool output = false)
|
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) {
|
if (ast_only_mode) {
|
||||||
dump(ast);
|
dump(ast);
|
||||||
@ -264,8 +265,9 @@ static Result<void> Main(std::span<char const*> args)
|
|||||||
|
|
||||||
for (auto const& [is_file, argument] : runnables) {
|
for (auto const& [is_file, argument] : runnables) {
|
||||||
if (!is_file) {
|
if (!is_file) {
|
||||||
Lines::the.add_line("<arguments>", argument);
|
Lines::the.add_line("<arguments>", argument, repl_line_number);
|
||||||
Try(runner.run(argument, "<arguments>"));
|
Try(runner.run(argument, "<arguments>"));
|
||||||
|
repl_line_number++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto path = argument;
|
auto path = argument;
|
||||||
@ -286,6 +288,7 @@ static Result<void> Main(std::span<char const*> args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (runnables.empty() || enable_repl) {
|
if (runnables.empty() || enable_repl) {
|
||||||
|
repl_line_number = 1;
|
||||||
enable_repl = true;
|
enable_repl = true;
|
||||||
bestlineSetCompletionCallback(completion);
|
bestlineSetCompletionCallback(completion);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -317,12 +320,13 @@ static Result<void> Main(std::span<char const*> args)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lines::the.add_line("<repl>", raw);
|
Lines::the.add_line("<repl>", raw, repl_line_number);
|
||||||
auto result = runner.run(raw, "<repl>", true);
|
auto result = runner.run(raw, "<repl>", true);
|
||||||
if (not result.has_value()) {
|
if (not result.has_value()) {
|
||||||
std::cout << std::flush;
|
std::cout << std::flush;
|
||||||
std::cerr << result.error() << 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
|
// 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,
|
std::optional<Token::Type> separator,
|
||||||
At_Least at_least);
|
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 lexer{source};
|
||||||
lexer.location.filename = filename;
|
lexer.location.filename = filename;
|
||||||
|
lexer.location.line = line_number;
|
||||||
Parser parser;
|
Parser parser;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
Loading…
Reference in New Issue
Block a user