Optionally colorful errors part 2; repl dont exit on errors
This commit is contained in:
parent
3c4da4a226
commit
016e48570e
1
Makefile
1
Makefile
@ -17,6 +17,7 @@ Obj= \
|
||||
location.o \
|
||||
number.o \
|
||||
parser.o \
|
||||
pretty.o \
|
||||
unicode.o \
|
||||
unicode_tables.o \
|
||||
value.o
|
||||
|
@ -37,30 +37,37 @@ static std::ostream& error_heading(
|
||||
Error_Level lvl,
|
||||
std::string_view short_description)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
switch (lvl) {
|
||||
case Error_Level::Error:
|
||||
os << "ERROR " << short_description << ' ';
|
||||
ss << pretty::begin_error << "ERROR " << pretty::end << short_description;
|
||||
break;
|
||||
|
||||
// This branch should be reached if we have Error_Level::Bug
|
||||
// or definetely where error level is outside of enum Error_Level
|
||||
default:
|
||||
os << "IMPLEMENTATION BUG " << short_description << ' ';
|
||||
ss << pretty::begin_error << "IMPLEMENTATION BUG " << pretty::end << short_description;
|
||||
}
|
||||
|
||||
if (location) {
|
||||
os << " at " << *location;
|
||||
ss << " at " << pretty::begin_path << *location << pretty::end;
|
||||
}
|
||||
|
||||
auto heading = std::move(ss).str();
|
||||
os << heading << '\n';
|
||||
|
||||
auto const line_length = heading.size();
|
||||
std::fill_n(std::ostreambuf_iterator<char>(os), line_length, '-');
|
||||
return os << '\n';
|
||||
}
|
||||
|
||||
static void encourage_contact(std::ostream &os)
|
||||
{
|
||||
os <<
|
||||
os << pretty::begin_comment << "\n"
|
||||
"Interpreter got in state that was not expected by it's developers.\n"
|
||||
"Contact them providing code that coused it and error message above to resolve this trouble\n"
|
||||
<< std::flush;
|
||||
<< pretty::end << std::flush;
|
||||
}
|
||||
|
||||
void assert(bool condition, std::string message, Location loc)
|
||||
@ -69,7 +76,7 @@ void assert(bool condition, std::string message, Location loc)
|
||||
error_heading(std::cerr, loc, Error_Level::Bug, "Assertion in interpreter");
|
||||
|
||||
if (not message.empty())
|
||||
std::cerr << "with message: " << message << std::endl;
|
||||
std::cerr << message << std::endl;
|
||||
|
||||
encourage_contact(std::cerr);
|
||||
|
||||
@ -91,7 +98,6 @@ void assert(bool condition, std::string message, Location loc)
|
||||
|
||||
[[noreturn]] void unreachable(Location loc)
|
||||
{
|
||||
|
||||
error_heading(std::cerr, loc, Error_Level::Bug, "Reached unreachable state");
|
||||
encourage_contact(std::cerr);
|
||||
std::exit(1);
|
||||
@ -117,7 +123,7 @@ std::ostream& operator<<(std::ostream& os, Error const& err)
|
||||
visit(Overloaded {
|
||||
[&os](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: " << std::hex << err.invalid_character << '\n';
|
||||
os << " Character Unicode code: U+" << std::hex << err.invalid_character << '\n';
|
||||
os << " Character printed: '" << utf8::Print{err.invalid_character} << "'\n";
|
||||
os << "\n";
|
||||
os << "Musique only accepts characters that are unicode letters or ascii numbers and punctuation\n";
|
||||
@ -138,7 +144,7 @@ std::ostream& operator<<(std::ostream& os, Error const& err)
|
||||
os << " Token type: " << ut.type << '\n';
|
||||
os << " Token source: " << ut.source << '\n';
|
||||
|
||||
os << "\nThis error is considered an internal one. It should not be displayed to the end user.\n";
|
||||
os << pretty::begin_comment << "\nThis error is considered an internal one. It should not be displayed to the end user.\n" << pretty::end;
|
||||
encourage_contact(os);
|
||||
},
|
||||
|
||||
|
10
src/main.cc
10
src/main.cc
@ -111,6 +111,10 @@ std::vector<std::string> eternal_sources;
|
||||
/// Fancy main that supports Result forwarding on error (Try macro)
|
||||
static Result<void> Main(std::span<char const*> args)
|
||||
{
|
||||
if (isatty(STDOUT_FILENO) && getenv("NO_COLOR") == nullptr) {
|
||||
pretty::terminal_mode();
|
||||
}
|
||||
|
||||
/// Describes all arguments that will be run
|
||||
struct Run
|
||||
{
|
||||
@ -211,7 +215,11 @@ static Result<void> Main(std::span<char const*> args)
|
||||
continue;
|
||||
}
|
||||
|
||||
Try(runner.run(raw, "<repl>"));
|
||||
auto result = runner.run(raw, "<repl>");
|
||||
if (not result.has_value()) {
|
||||
std::cout << std::flush;
|
||||
std::cerr << result.error() << std::flush;
|
||||
}
|
||||
// We don't free input line since there could be values that still relay on it
|
||||
}
|
||||
}
|
||||
|
@ -122,6 +122,18 @@ namespace errors
|
||||
>;
|
||||
}
|
||||
|
||||
/// All code related to pretty printing
|
||||
namespace pretty
|
||||
{
|
||||
std::ostream& begin_error(std::ostream&);
|
||||
std::ostream& begin_path(std::ostream&);
|
||||
std::ostream& begin_comment(std::ostream&);
|
||||
std::ostream& end(std::ostream&);
|
||||
|
||||
void terminal_mode();
|
||||
void no_color_mode();
|
||||
}
|
||||
|
||||
template<typename ...Lambdas>
|
||||
struct Overloaded : Lambdas... { using Lambdas::operator()...; };
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user