MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
dbg.h
Go to the documentation of this file.
1#pragma once
2
3#include <absl/container/flat_hash_map.h>
4#include <absl/container/flat_hash_set.h>
5#include <fe/loc.h>
6#include <fe/sym.h>
7#include <rang.hpp>
8
9#include "mim/util/print.h"
10
11namespace mim {
12
13using fe::Loc;
14using fe::Pos;
15using fe::Sym;
16
17class Error : std::exception {
18public:
19 enum class Tag {
20 Error,
21 Warn,
22 Note,
23 };
24
25 struct Msg {
26 Loc loc;
28 std::string str;
29
30 friend std::ostream& operator<<(std::ostream& os, const Msg& msg) {
31 return print(os, "{}{}: {}: {}{}", rang::fg::yellow, msg.loc, msg.tag, rang::fg::reset, msg.str);
32 return print(os, "{}{}: {}: {}{}", rang::fg::yellow, msg.loc, msg.tag, rang::fg::reset, msg.str);
33 }
34 };
35
36 /// @name Constructors
37 ///@{
38 Error() = default;
39 Error(const Error&) = default;
40 Error(Error&& other)
41 : Error() {
42 swap(*this, other);
43 }
44 /// Creates a single Tag::Error message.
45 Error(Loc loc, const std::string& str)
46 : msgs_{
47 {loc, Tag::Error, str}
48 } {}
49 ///@}
50
51 /// @name Getters
52 ///@{
53 const auto& msgs() const { return msgs_; }
54 size_t num_msgs() const {
55 assert(num_errors() + num_warnings() + num_notes() == msgs_.size());
56 return msgs_.size();
57 }
58 size_t num_errors() const { return num_errors_; }
59 size_t num_warnings() const { return num_warnings_; }
60 size_t num_notes() const { return num_notes_; }
61 ///@}
62
63 /// @name Add formatted message
64 ///@{
65 template<class... Args> Error& msg(Loc loc, Tag tag, const char* s, Args&&... args) {
66 msgs_.emplace_back(loc, tag, fmt(s, std::forward<Args&&>(args)...));
67 return *this;
68 }
69
70 // clang-format off
71 template<class... Args> Error& error(Loc loc, const char* s, Args&&... args) { ++num_errors_; return msg(loc, Tag::Error, s, std::forward<Args&&>(args)...); }
72 template<class... Args> Error& warn (Loc loc, const char* s, Args&&... args) { ++num_warnings_; return msg(loc, Tag::Warn, s, std::forward<Args&&>(args)...); }
73 template<class... Args> Error& note (Loc loc, const char* s, Args&&... args) {
74 assert(num_errors() > 0 || num_warnings() > 0); /* */ ++num_notes_; return msg(loc, Tag::Note, s, std::forward<Args&&>(args)...);
75 }
76 // clang-format on
77 ///@}
78
79 /// @name Handle Errors/Warnings
80 ///@{
81 void clear();
82 /// If errors occured, claim them and throw; if warnings occured, claim them and report to @p os.
83 void ack(std::ostream& os = std::cerr);
84 ///@}
85
86 friend std::ostream& operator<<(std::ostream& o, Tag tag) {
87 // clang-format off
88 switch (tag) {
89 case Tag::Error: return o << rang::fg::red << "error";
90 case Tag::Warn: return o << rang::fg::magenta << "warning";
91 case Tag::Note: return o << rang::fg::green << "note";
92 default: fe::unreachable();
93 }
94 // clang-format on
95 }
96
97 friend std::ostream& operator<<(std::ostream& os, const Error& e) {
98 for (const auto& msg : e.msgs()) os << msg << std::endl;
99 return os;
100 }
101
102 friend void swap(Error& e1, Error& e2) noexcept {
103 using std::swap;
104 // clang-format off
105 swap(e1.msgs_, e2.msgs_);
106 swap(e1.num_errors_, e2.num_errors_);
107 swap(e1.num_warnings_, e2.num_warnings_);
108 swap(e1.num_notes_, e2.num_notes_);
109 // clang-format on
110 }
111
112private:
113 std::vector<Msg> msgs_;
114 size_t num_errors_ = 0;
115 size_t num_warnings_ = 0;
116 size_t num_notes_ = 0;
117};
118
119/// @name Formatted Output
120///@{
121/// Single Error that `throw`s immediately.
122template<class... Args> [[noreturn]] void error(Loc loc, const char* f, Args&&... args) {
123 throw Error(loc, fmt(f, std::forward<Args&&>(args)...));
124}
125///@}
126
127struct Dbg {
128public:
129 /// @name Constructors
130 ///@{
131 constexpr Dbg() noexcept = default;
132 constexpr Dbg(const Dbg&) noexcept = default;
133 constexpr Dbg(Loc loc, Sym sym) noexcept
134 : loc_(loc)
135 , sym_(sym) {}
136 constexpr Dbg(Loc loc) noexcept
137 : Dbg(loc, {}) {}
138 constexpr Dbg(Sym sym) noexcept
139 : Dbg({}, sym) {}
140 Dbg& operator=(const Dbg&) noexcept = default;
141 ///@}
142
143 /// @name Getters
144 ///@{
145 Sym sym() const { return sym_; }
146 Loc loc() const { return loc_; }
147 bool is_anon() const { return !sym() || sym() == '_'; }
148 explicit operator bool() const { return sym().operator bool(); }
149 ///@}
150
151 /// @name Setters
152 ///@{
153 Dbg& set(Sym sym) { return sym_ = sym, *this; }
154 Dbg& set(Loc loc) { return loc_ = loc, *this; }
155 ///@}
156
157private:
158 Loc loc_;
159 Sym sym_;
160
161 friend std::ostream& operator<<(std::ostream& os, const Dbg& dbg) { return os << dbg.sym(); }
162};
163
164} // namespace mim
size_t num_msgs() const
Definition dbg.h:54
friend void swap(Error &e1, Error &e2) noexcept
Definition dbg.h:102
Error & error(Loc loc, const char *s, Args &&... args)
Definition dbg.h:71
size_t num_notes() const
Definition dbg.h:60
const auto & msgs() const
Definition dbg.h:53
Error()=default
Error(const Error &)=default
friend std::ostream & operator<<(std::ostream &o, Tag tag)
Definition dbg.h:86
Error & note(Loc loc, const char *s, Args &&... args)
Definition dbg.h:73
friend std::ostream & operator<<(std::ostream &os, const Error &e)
Definition dbg.h:97
Error & warn(Loc loc, const char *s, Args &&... args)
Definition dbg.h:72
Error(Error &&other)
Definition dbg.h:40
size_t num_errors() const
Definition dbg.h:58
Error(Loc loc, const std::string &str)
Creates a single Tag::Error message.
Definition dbg.h:45
size_t num_warnings() const
Definition dbg.h:59
Error & msg(Loc loc, Tag tag, const char *s, Args &&... args)
Definition dbg.h:65
Definition cfg.h:11
std::ostream & print(std::ostream &os, const char *s)
Base case.
Definition print.cpp:5
std::string fmt(const char *s, Args &&... args)
Wraps mim::print to output a formatted std:string.
Definition print.h:155
Dbg & operator=(const Dbg &) noexcept=default
Sym sym() const
Definition dbg.h:145
Dbg & set(Loc loc)
Definition dbg.h:154
Loc loc() const
Definition dbg.h:146
Dbg & set(Sym sym)
Definition dbg.h:153
bool is_anon() const
Definition dbg.h:147
friend std::ostream & operator<<(std::ostream &os, const Dbg &dbg)
Definition dbg.h:161
constexpr Dbg(Loc loc) noexcept
Definition dbg.h:136
constexpr Dbg() noexcept=default
constexpr Dbg(Sym sym) noexcept
Definition dbg.h:138
friend std::ostream & operator<<(std::ostream &os, const Msg &msg)
Definition dbg.h:30
std::string str
Definition dbg.h:28