ErrorReporting.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #ifndef QLOW_ERROR_REPORTING
  2. #define QLOW_ERROR_REPORTING
  3. #include "Printer.h"
  4. namespace qlow
  5. {
  6. struct CodePosition;
  7. class InternalError;
  8. class CompileError;
  9. class SyntaxError;
  10. class SemanticError;
  11. class NotLValue;
  12. void reportError(const CompileError& ce) noexcept;
  13. void reportError(const std::string& message) noexcept;
  14. void printError(Printer& printer, const std::string& message) noexcept;
  15. void printError(Printer& printer, const std::string& message, const CodePosition& where) noexcept;
  16. }
  17. /*!
  18. * \brief bison-compatible location struct
  19. */
  20. struct qlow::CodePosition
  21. {
  22. std::string filename = "";
  23. int first_line;
  24. int last_line;
  25. int first_column;
  26. int last_column;
  27. inline bool isMultiline(void) const { return first_line != last_line; }
  28. std::string getReportFormat(void) const noexcept;
  29. };
  30. class qlow::InternalError
  31. {
  32. public:
  33. enum ErrorCode
  34. {
  35. OUT_OF_MEMORY,
  36. /// initialization of the flex lexer failed
  37. PARSER_INIT_FAILED,
  38. /// destruction of the flex lexer failed
  39. PARSER_DEST_FAILED,
  40. /// bison routine returned error value
  41. PARSER_FAILED,
  42. /// tried to determine the kind of an invalid type
  43. INVALID_TYPE
  44. };
  45. private:
  46. ErrorCode errorCode;
  47. public:
  48. InternalError(ErrorCode ec) :
  49. errorCode{ ec } {}
  50. void print(Printer& printer = Printer::getInstance()) const noexcept;
  51. const std::string& getMessage(void) const noexcept;
  52. };
  53. class qlow::CompileError
  54. {
  55. protected:
  56. CodePosition where;
  57. public:
  58. inline CompileError(const CodePosition& where) :
  59. where{ where }
  60. {
  61. }
  62. virtual ~CompileError(void);
  63. virtual void print(Printer& printer = Printer::getInstance()) const noexcept = 0;
  64. void underlineError(Printer& printer = Printer::getInstance()) const noexcept;
  65. };
  66. class qlow::SyntaxError : public CompileError
  67. {
  68. std::string message;
  69. public:
  70. inline SyntaxError(const CodePosition& where) :
  71. CompileError{ where }
  72. {
  73. }
  74. inline SyntaxError(const std::string& message, const CodePosition& where) :
  75. CompileError{ where },
  76. message{ message }
  77. {
  78. }
  79. virtual void print(Printer&) const noexcept override;
  80. };
  81. class qlow::SemanticError : public CompileError
  82. {
  83. std::string message;
  84. public:
  85. enum ErrorCode
  86. {
  87. UNKNOWN_TYPE,
  88. DUPLICATE_CLASS_DEFINITION,
  89. DUPLICATE_FIELD_DECLARATION,
  90. DUPLICATE_METHOD_DEFINITION,
  91. OPERATOR_NOT_FOUND,
  92. FEATURE_NOT_FOUND,
  93. WRONG_NUMBER_OF_ARGUMENTS,
  94. TYPE_MISMATCH,
  95. INVALID_RETURN_TYPE,
  96. };
  97. ErrorCode errorCode;
  98. public:
  99. inline SemanticError(ErrorCode ec, const std::string& arg, const
  100. qlow::CodePosition& where) :
  101. CompileError{ where },
  102. message{ arg },
  103. errorCode{ ec }
  104. {
  105. }
  106. inline SemanticError(const CodePosition& where) :
  107. CompileError{ where }
  108. {
  109. }
  110. virtual void print(Printer& p = Printer::getInstance()) const noexcept override;
  111. virtual std::string getMessage(void) const noexcept;
  112. };
  113. class qlow::NotLValue : public SemanticError
  114. {
  115. std::string type;
  116. public:
  117. inline NotLValue(const std::string& type, const CodePosition& where) noexcept :
  118. SemanticError{ where },
  119. type{ type }
  120. {
  121. }
  122. inline virtual std::string getMessage(void) const noexcept override
  123. {
  124. return "Can't take address of non-lvalue value of type '" +
  125. type + "'";
  126. }
  127. };
  128. #endif // QLOW_ERROR_REPORTING