Added documentation mostly for error reporting structures

This commit is contained in:
Robert Bendun 2022-05-30 00:18:48 +02:00
parent 2eee11e476
commit ada8e17d1b
2 changed files with 35 additions and 10 deletions

View File

@ -25,12 +25,16 @@ Error Error::with(Location loc) &&
return *this; return *this;
} }
/// Describes type of error
enum class Error_Level enum class Error_Level
{ {
Error, Error,
Bug Bug
}; };
/// Centralized production of error headings for consistent error style
///
/// @param short_description General description of an error that will be printed in the heading
static std::ostream& error_heading( static std::ostream& error_heading(
std::ostream &os, std::ostream &os,
std::optional<Location> location, std::optional<Location> location,
@ -62,6 +66,7 @@ static std::ostream& error_heading(
return os << '\n'; return os << '\n';
} }
/// Prints message that should encourage contact with developers
static void encourage_contact(std::ostream &os) static void encourage_contact(std::ostream &os)
{ {
os << pretty::begin_comment << "\n" os << pretty::begin_comment << "\n"

View File

@ -40,40 +40,44 @@ using usize = std::size_t;
using isize = std::ptrdiff_t; using isize = std::ptrdiff_t;
/// Error handling related functions and definitions /// Error handling related functions and definitions
///
/// Error handling mechanism inspired by Andrew Kelly approach, that was implemented
/// as first class feature in Zig programming language.
namespace errors namespace errors
{ {
/// When user puts emoji in the source code
struct Unrecognized_Character struct Unrecognized_Character
{ {
u32 invalid_character; u32 invalid_character;
}; };
/// When parser was expecting code but encountered end of file
struct Unexpected_Empty_Source struct Unexpected_Empty_Source
{ {
}; };
/// When user passed numeric literal too big for numeric type
struct Failed_Numeric_Parsing struct Failed_Numeric_Parsing
{ {
std::errc reason; std::errc reason;
}; };
/// When user forgot semicolon or brackets
struct Expected_Expression_Separator_Before struct Expected_Expression_Separator_Before
{ {
std::string_view what; std::string_view what;
}; };
/// When some keywords are not allowed in given context
struct Unexpected_Keyword struct Unexpected_Keyword
{ {
std::string_view keyword; std::string_view keyword;
}; };
/// When user tried to use operator that was not defined
struct Undefined_Operator struct Undefined_Operator
{ {
std::string_view op; std::string_view op;
}; };
/// When user tried to call something that can't be called
struct Not_Callable struct Not_Callable
{ {
std::string_view type; std::string_view type;
@ -82,12 +86,7 @@ namespace errors
/// Collection of messages that are considered internal and should not be printed to the end user. /// Collection of messages that are considered internal and should not be printed to the end user.
namespace internal namespace internal
{ {
struct Expected_Keyword /// When encountered token that was supposed to be matched in higher branch of the parser
{
std::string_view keyword;
std::string_view received_type = {};
};
struct Unexpected_Token struct Unexpected_Token
{ {
/// Type of the token /// Type of the token
@ -101,6 +100,7 @@ namespace errors
}; };
} }
/// All possible error types
using Details = std::variant< using Details = std::variant<
Expected_Expression_Separator_Before, Expected_Expression_Separator_Before,
Failed_Numeric_Parsing, Failed_Numeric_Parsing,
@ -113,18 +113,29 @@ namespace errors
>; >;
} }
/// All code related to pretty printing /// All code related to pretty printing. Default mode is no_color
namespace pretty namespace pretty
{ {
/// Mark start of printing an error
std::ostream& begin_error(std::ostream&); std::ostream& begin_error(std::ostream&);
/// Mark start of printing a path
std::ostream& begin_path(std::ostream&); std::ostream& begin_path(std::ostream&);
/// Mark start of printing a comment
std::ostream& begin_comment(std::ostream&); std::ostream& begin_comment(std::ostream&);
/// Mark end of any above
std::ostream& end(std::ostream&); std::ostream& end(std::ostream&);
/// Switch to colorful output via ANSI escape sequences
void terminal_mode(); void terminal_mode();
/// Switch to colorless output (default one)
void no_color_mode(); void no_color_mode();
} }
/// Combine several lambdas into one for visiting std::variant
template<typename ...Lambdas> template<typename ...Lambdas>
struct Overloaded : Lambdas... { using Lambdas::operator()...; }; struct Overloaded : Lambdas... { using Lambdas::operator()...; };
@ -178,25 +189,34 @@ void assert(bool condition, std::string message, Location loc = Location::caller
/// Marks location that should not be reached /// Marks location that should not be reached
[[noreturn]] void unreachable(Location loc = Location::caller()); [[noreturn]] void unreachable(Location loc = Location::caller());
/// Represents all recoverable error messages that interpreter can produce
struct Error struct Error
{ {
/// Specific message details
errors::Details details; errors::Details details;
/// Location that coused all this trouble
std::optional<Location> location = std::nullopt; std::optional<Location> location = std::nullopt;
/// Return self with new location
Error with(Location) &&; Error with(Location) &&;
}; };
/// Error pretty printing
std::ostream& operator<<(std::ostream& os, Error const& err); std::ostream& operator<<(std::ostream& os, Error const& err);
/// Returns if provided thingy is a given template
template<template<typename ...> typename Template, typename> template<template<typename ...> typename Template, typename>
struct is_template : std::false_type {}; struct is_template : std::false_type {};
template<template<typename ...> typename Template, typename ...T> template<template<typename ...> typename Template, typename ...T>
struct is_template<Template, Template<T...>> : std::true_type {}; struct is_template<Template, Template<T...>> : std::true_type {};
/// Returns if provided thingy is a given template
template<template<typename ...> typename Template, typename T> template<template<typename ...> typename Template, typename T>
constexpr auto is_template_v = is_template<Template, T>::value; constexpr auto is_template_v = is_template<Template, T>::value;
/// Holds either T or Error
template<typename T> template<typename T>
struct [[nodiscard("This value may contain critical error, so it should NOT be ignored")]] Result : tl::expected<T, Error> struct [[nodiscard("This value may contain critical error, so it should NOT be ignored")]] Result : tl::expected<T, Error>
{ {