diff options
Diffstat (limited to 'tiger-compiler/lib/misc/error.cc')
| -rw-r--r-- | tiger-compiler/lib/misc/error.cc | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/tiger-compiler/lib/misc/error.cc b/tiger-compiler/lib/misc/error.cc new file mode 100644 index 0000000..565760b --- /dev/null +++ b/tiger-compiler/lib/misc/error.cc @@ -0,0 +1,107 @@ +/** + ** \file misc/error.cc + ** \brief Implement error. + */ + +#include <iostream> +#include <stdexcept> + +#include <misc/contract.hh> +#include <misc/error.hh> + +namespace misc +{ + /*--------. + | error. | + `--------*/ + + error::error() + : status_(error_type::success) + {} + + error::error(const error& e) { *this = e; } + + error& error::operator=(const error& rhs) + { + status_ = rhs.status_get(); + stream_.str(rhs.stream_get().str()); + return *this; + } + + /*----------------------------. + | Filling the error handler. | + `----------------------------*/ + + error& error::operator<<(error_type e) + { + auto status_value = static_cast<unsigned>(status_); + auto e_value = static_cast<unsigned>(e); + if ((e_value && e_value < status_value) || (!status_value)) + status_ = e; + return *this; + } + + // Import errors. + error& error::operator<<(const error& rhs) + { + *this << rhs.status_get() << rhs.stream_get().str(); + return *this; + } + + error& error::operator<<(std::ostream& (*f)(std::ostream&)) + { + stream_ << f; + return *this; + } + + /*---------------. + | Manipulators. | + `---------------*/ + + void error::exit() const { throw *this; } + + void error::exit_on_error() const + { + if (static_cast<unsigned>(status_)) + exit(); + } + + void error::ice(const char* file, int line) const + { + std::cerr << stream_.str(); + __Terminate(file, line, "Internal Compiler error"); + } + + void error::ice_on_error(const char* file, int line) const + { + if (static_cast<unsigned>(status_)) + ice(file, line); + } + + void error::clear() + { + status_ = error_type::success; + stream_.clear(); + } + + /*------------. + | Accessors. | + `------------*/ + + error::operator bool() const { return status_ != error_type::success; } + + error::error_type error::status_get() const { return status_; } + + unsigned error::status_get_value() const + { + return static_cast<unsigned>(status_); + } + + const std::ostringstream& error::stream_get() const { return stream_; } + + std::ostream& operator<<(std::ostream& o, const error& e) + { + return o << e.stream_get().str(); + } + +} // namespace misc |
