6#include <absl/container/flat_hash_map.h>
7#include <absl/container/flat_hash_set.h>
19class Error :
public std::exception {
39 Error(Loc loc,
const std::string& str)
47 const auto&
msgs()
const {
return msgs_; }
48 size_t num_msgs()
const {
return msgs_.size(); }
56 template<
class... Args>
57 Error&
msg(Loc loc,
Tag tag, std::format_string<Args...> s, Args&&... args) {
58 msgs_.emplace_back(loc, tag, std::format(s, std::forward<Args>(args)...));
63 template<
class... Args>
Error&
error(Loc loc, std::format_string<Args...> s, Args&&... args) {
return msg(loc,
Tag::Error, s, std::forward<Args>(args)...); }
64 template<
class... Args>
Error&
warn (Loc loc, std::format_string<Args...> s, Args&&... args) {
return msg(loc,
Tag::Warn, s, std::forward<Args>(args)...); }
65 template<
class... Args>
Error&
note (Loc loc, std::format_string<Args...> s, Args&&... args) {
67 return msg(loc,
Tag::Note, s, std::forward<Args>(args)...);
76 void ack(std::ostream& os = std::cerr);
79 const char*
what() const noexcept
override {
81 std::ostringstream oss;
91 case Tag::Error:
return o << fe::term::FG::Red <<
"error";
92 case Tag::Warn:
return o << fe::term::FG::Magenta <<
"warning";
93 case Tag::Note:
return o << fe::term::FG::Green <<
"note";
94 default: fe::unreachable();
100 for (
const auto&
msg : e.msgs())
101 os <<
msg << std::endl;
106 std::vector<Msg> msgs_;
107 mutable std::string what_;
113template<
class... Args>
114[[noreturn]]
void error(Loc loc, std::format_string<Args...> f, Args&&... args) {
115 throw Error(loc, std::format(f, std::forward<Args>(args)...));
123 constexpr Dbg() noexcept = default;
124 constexpr
Dbg(const
Dbg&) noexcept = default;
137 Sym
sym()
const {
return sym_; }
138 Loc
loc()
const {
return loc_; }
140 explicit operator bool()
const {
return sym().operator bool(); }
153 friend std::ostream&
operator<<(std::ostream& os,
const Dbg& dbg) {
return os << dbg.sym(); }
159template<>
struct std::formatter<
mim::Dbg > : fe::ostream_formatter {};
160template<>
struct std::formatter<
mim::Error > : fe::ostream_formatter {};
161template<>
struct std::formatter<
mim::Error::Tag> : fe::ostream_formatter {};
162template<>
struct std::formatter<
mim::Error::Msg> : fe::ostream_formatter {};
168 return os << std::format(
"{}{}: {}: {}{}", fe::term::FG::Yellow,
msg.loc,
msg.tag, fe::term::FG::Reset,
msg.str);
Error & msg(Loc loc, Tag tag, std::format_string< Args... > s, Args &&... args)
const char * what() const noexcept override
Error & error(Loc loc, std::format_string< Args... > s, Args &&... args)
Error & warn(Loc loc, std::format_string< Args... > s, Args &&... args)
const auto & msgs() const
friend std::ostream & operator<<(std::ostream &o, Tag tag)
friend std::ostream & operator<<(std::ostream &os, const Error &e)
size_t num_errors() const
Error(Loc loc, const std::string &str)
Creates a single Tag::Error message.
Error & note(Loc loc, std::format_string< Args... > s, Args &&... args)
size_t num_warnings() const
std::ostream & operator<<(std::ostream &os, const Error::Msg &msg)
void error(Loc loc, std::format_string< Args... > f, Args &&... args)
Dbg & operator=(const Dbg &) noexcept=default
friend std::ostream & operator<<(std::ostream &os, const Dbg &dbg)
constexpr Dbg(Loc loc) noexcept
constexpr Dbg() noexcept=default
constexpr Dbg(Sym sym) noexcept
friend std::ostream & operator<<(std::ostream &, const Msg &)