summaryrefslogtreecommitdiff
path: root/tiger-compiler/lib/misc/error.cc
blob: 565760b2fd73e74e0fb5e4262ae90d6dcf206578 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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