Branch data Line data Source code
1 : : #pragma once 2 : : 3 : : 4 : : #include <cstdarg> 5 : : #include <cstdio> 6 : : #include <mutable/util/Position.hpp> 7 : : 8 : : 9 : : namespace m { 10 : : 11 : : struct Diagnostic 12 : : { 13 : : static constexpr const char *RESET = "\033[0m"; 14 : : static constexpr const char *BOLD = "\033[1;37m"; 15 : : static constexpr const char *ITALIC = "\033[3;37m"; 16 : : static constexpr const char *NOTE = "\033[1;2;37m"; 17 : : static constexpr const char *WARNING = "\033[1;35m"; 18 : : static constexpr const char *ERROR = "\033[1;31m"; 19 : : 20 : 1335 : Diagnostic(const bool color, std::ostream &out, std::ostream &err) 21 : 1335 : : color_(color) 22 : 1335 : , out_(out) 23 : 1335 : , err_(err) 24 : 1335 : { } 25 : : 26 : 0 : std::ostream & operator()(const Position pos) { 27 : 0 : print_pos(out_, pos, K_None); 28 : 0 : return out_; 29 : : } 30 : : 31 : 2 : std::ostream & n(const Position pos) { 32 : 2 : print_pos(out_, pos, K_Note); 33 : 2 : return out_; 34 : : } 35 : : 36 : 12 : std::ostream & w(const Position pos) { 37 : 12 : print_pos(err_, pos, K_Warning); 38 : 12 : return err_; 39 : : } 40 : : 41 : 596 : std::ostream & e(const Position pos) { 42 : 596 : ++num_errors_; 43 : 596 : print_pos(err_, pos, K_Error); 44 : 596 : return err_; 45 : : } 46 : : 47 : : /** Returns the number of errors emitted since the last call to `clear()`. */ 48 : 7779 : unsigned num_errors() const { return num_errors_; } 49 : : /** Resets the error counter. */ 50 : 772 : void clear() { num_errors_ = 0; } 51 : : 52 : 0 : std::ostream & out() const { return out_; } 53 : 6 : std::ostream & err() { 54 : 6 : ++num_errors_; 55 : 6 : err_ << ERROR << "error: " << RESET; 56 : 6 : return err_; 57 : : } 58 : : 59 : : private: 60 : : const bool color_; 61 : : std::ostream &out_; 62 : : std::ostream &err_; 63 : 1335 : unsigned num_errors_ = 0; 64 : : 65 : : enum Kind { 66 : : K_None, 67 : : K_Note, 68 : : K_Warning, 69 : : K_Error 70 : : }; 71 : : 72 : 610 : void print_pos(std::ostream &out, const Position pos, const Kind kind) { 73 [ + - ]: 610 : if (color_) out << BOLD; 74 : 610 : out << pos.name << ':' << pos.line << ':' << pos.column << ": "; 75 [ + - ]: 610 : if (color_) out << RESET; 76 [ - - + + : 610 : switch (kind) { + ] 77 : 0 : case K_None: break; 78 [ + - ]: 2 : case K_Note: if (color_) { out << NOTE; } out << "note: "; break; 79 [ + - ]: 12 : case K_Warning: if (color_) { out << WARNING; } out << "warning: "; break; 80 [ + - ]: 596 : case K_Error: if (color_) { out << ERROR; } out << "error: "; break; 81 : : } 82 [ + - ]: 610 : if (color_) out << RESET; 83 : 610 : } 84 : : }; 85 : : 86 : : }