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 {
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>
66 Error& msg(Loc loc, Tag tag, const char* s, Args&&... args) {
67 msgs_.emplace_back(loc, tag, fmt(s, std::forward<Args>(args)...));
68 return *this;
69 }
70
71 // clang-format off
72 template<class... Args> Error& error(Loc loc, const char* s, Args&&... args) { ++num_errors_; return msg(loc, Tag::Error, s, std::forward<Args>(args)...); }
73 template<class... Args> Error& warn (Loc loc, const char* s, Args&&... args) { ++num_warnings_; return msg(loc, Tag::Warn, s, std::forward<Args>(args)...); }
74 template<class... Args> Error& note (Loc loc, const char* s, Args&&... args) {
75 assert(num_errors() > 0 || num_warnings() > 0); /* */ ++num_notes_; return msg(loc, Tag::Note, s, std::forward<Args>(args)...);
76 }
77 // clang-format on
78 ///@}
79
80 /// @name Handle Errors/Warnings
81 ///@{
82 void clear();
83 /// If errors occured, claim them and throw; if warnings occured, claim them and report to @p os.
84 void ack(std::ostream& os = std::cerr);
85 ///@}
86
87 friend std::ostream& operator<<(std::ostream& o, Tag tag) {
88 // clang-format off
89 switch (tag) {
90 case Tag::Error: return o << rang::fg::red << "error";
91 case Tag::Warn: return o << rang::fg::magenta << "warning";
92 case Tag::Note: return o << rang::fg::green << "note";
93 default: fe::unreachable();
94 }
95 // clang-format on
96 }
97
98 friend std::ostream& operator<<(std::ostream& os, const Error& e) {
99 for (const auto& msg : e.msgs())
100 os << msg << std::endl;
101 return os;
102 }
103
104 friend void swap(Error& e1, Error& e2) noexcept {
105 using std::swap;
106 // clang-format off
107 swap(e1.msgs_, e2.msgs_);
108 swap(e1.num_errors_, e2.num_errors_);
109 swap(e1.num_warnings_, e2.num_warnings_);
110 swap(e1.num_notes_, e2.num_notes_);
111 // clang-format on
112 }
113
114private:
115 std::vector<Msg> msgs_;
116 size_t num_errors_ = 0;
117 size_t num_warnings_ = 0;
118 size_t num_notes_ = 0;
119};
120
121/// @name Formatted Output
122///@{
123/// Single Error that `throw`s immediately.
124template<class... Args>
125[[noreturn]] void error(Loc loc, const char* f, Args&&... args) {
126 throw Error(loc, fmt(f, std::forward<Args>(args)...));
127}
128///@}
129
130struct Dbg {
131public:
132 /// @name Constructors
133 ///@{
134 constexpr Dbg() noexcept = default;
135 constexpr Dbg(const Dbg&) noexcept = default;
136 constexpr Dbg(Loc loc, Sym sym) noexcept
137 : loc_(loc)
138 , sym_(sym) {}
139 constexpr Dbg(Loc loc) noexcept
140 : Dbg(loc, {}) {}
141 constexpr Dbg(Sym sym) noexcept
142 : Dbg({}, sym) {}
143 Dbg& operator=(const Dbg&) noexcept = default;
144 ///@}
145
146 /// @name Getters
147 ///@{
148 Sym sym() const { return sym_; }
149 Loc loc() const { return loc_; }
150 bool is_anon() const { return !sym() || sym() == '_'; }
151 explicit operator bool() const { return sym().operator bool(); }
152 ///@}
153
154 /// @name Setters
155 ///@{
156 Dbg& set(Sym sym) { return sym_ = sym, *this; }
157 Dbg& set(Loc loc) { return loc_ = loc, *this; }
158 ///@}
159
160private:
161 Loc loc_;
162 Sym sym_;
163
164 friend std::ostream& operator<<(std::ostream& os, const Dbg& dbg) { return os << dbg.sym(); }
165};
166
167} // namespace mim
size_t num_msgs() const
Definition dbg.h:54
friend void swap(Error &e1, Error &e2) noexcept
Definition dbg.h:104
Error & error(Loc loc, const char *s, Args &&... args)
Definition dbg.h:72
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:87
Error & note(Loc loc, const char *s, Args &&... args)
Definition dbg.h:74
friend std::ostream & operator<<(std::ostream &os, const Error &e)
Definition dbg.h:98
Error & warn(Loc loc, const char *s, Args &&... args)
Definition dbg.h:73
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:66
Definition ast.h:14
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:163
void error(Loc loc, const char *f, Args &&... args)
Definition dbg.h:125
Dbg & operator=(const Dbg &) noexcept=default
Sym sym() const
Definition dbg.h:148
Dbg & set(Loc loc)
Definition dbg.h:157
Loc loc() const
Definition dbg.h:149
Dbg & set(Sym sym)
Definition dbg.h:156
bool is_anon() const
Definition dbg.h:150
friend std::ostream & operator<<(std::ostream &os, const Dbg &dbg)
Definition dbg.h:164
constexpr Dbg(Loc loc) noexcept
Definition dbg.h:139
constexpr Dbg() noexcept=default
constexpr Dbg(Sym sym) noexcept
Definition dbg.h:141
friend std::ostream & operator<<(std::ostream &os, const Msg &msg)
Definition dbg.h:30
std::string str
Definition dbg.h:28