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 \
|
location.o \
|
||||||
number.o \
|
number.o \
|
||||||
parser.o \
|
parser.o \
|
||||||
|
pretty.o \
|
||||||
unicode.o \
|
unicode.o \
|
||||||
unicode_tables.o \
|
unicode_tables.o \
|
||||||
value.o
|
value.o
|
||||||
|
@ -37,30 +37,37 @@ static std::ostream& error_heading(
|
|||||||
Error_Level lvl,
|
Error_Level lvl,
|
||||||
std::string_view short_description)
|
std::string_view short_description)
|
||||||
{
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
switch (lvl) {
|
switch (lvl) {
|
||||||
case Error_Level::Error:
|
case Error_Level::Error:
|
||||||
os << "ERROR " << short_description << ' ';
|
ss << pretty::begin_error << "ERROR " << pretty::end << short_description;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// This branch should be reached if we have Error_Level::Bug
|
// This branch should be reached if we have Error_Level::Bug
|
||||||
// or definetely where error level is outside of enum Error_Level
|
// or definetely where error level is outside of enum Error_Level
|
||||||
default:
|
default:
|
||||||
os << "IMPLEMENTATION BUG " << short_description << ' ';
|
ss << pretty::begin_error << "IMPLEMENTATION BUG " << pretty::end << short_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (location) {
|
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';
|
return os << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void encourage_contact(std::ostream &os)
|
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"
|
"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"
|
"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)
|
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");
|
error_heading(std::cerr, loc, Error_Level::Bug, "Assertion in interpreter");
|
||||||
|
|
||||||
if (not message.empty())
|
if (not message.empty())
|
||||||
std::cerr << "with message: " << message << std::endl;
|
std::cerr << message << std::endl;
|
||||||
|
|
||||||
encourage_contact(std::cerr);
|
encourage_contact(std::cerr);
|
||||||
|
|
||||||
@ -91,7 +98,6 @@ void assert(bool condition, std::string message, Location loc)
|
|||||||
|
|
||||||
[[noreturn]] void unreachable(Location loc)
|
[[noreturn]] void unreachable(Location loc)
|
||||||
{
|
{
|
||||||
|
|
||||||
error_heading(std::cerr, loc, Error_Level::Bug, "Reached unreachable state");
|
error_heading(std::cerr, loc, Error_Level::Bug, "Reached unreachable state");
|
||||||
encourage_contact(std::cerr);
|
encourage_contact(std::cerr);
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
@ -117,7 +123,7 @@ std::ostream& operator<<(std::ostream& os, Error const& err)
|
|||||||
visit(Overloaded {
|
visit(Overloaded {
|
||||||
[&os](errors::Unrecognized_Character const& err) {
|
[&os](errors::Unrecognized_Character const& err) {
|
||||||
os << "I encountered character in the source code that was not supposed to be here.\n";
|
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 << " Character printed: '" << utf8::Print{err.invalid_character} << "'\n";
|
||||||
os << "\n";
|
os << "\n";
|
||||||
os << "Musique only accepts characters that are unicode letters or ascii numbers and punctuation\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 type: " << ut.type << '\n';
|
||||||
os << " Token source: " << ut.source << '\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);
|
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)
|
/// Fancy main that supports Result forwarding on error (Try macro)
|
||||||
static Result<void> Main(std::span<char const*> args)
|
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
|
/// Describes all arguments that will be run
|
||||||
struct Run
|
struct Run
|
||||||
{
|
{
|
||||||
@ -211,7 +215,11 @@ static Result<void> Main(std::span<char const*> args)
|
|||||||
continue;
|
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
|
// 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>
|
template<typename ...Lambdas>
|
||||||
struct Overloaded : Lambdas... { using Lambdas::operator()...; };
|
struct Overloaded : Lambdas... { using Lambdas::operator()...; };
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user