#ifndef DEF_ERRORS_H #define DEF_ERRORS_H #include using namespace std; #include "tokenize.h" /** * Errors */ enum class ErrorType { // Generic NotImplemented, // Lexing UnknownToken, IntegerTooLarge, // Parsing EmptyInput, InvalidSyntax, ExceptedLParen, ExpectedRParen, ExpectedRCurlyBracket, ExpectedSemicolon, DependentDeclaration, // Analysis UnknownType, TypeNotCastable, TypesNotComparable, ExpectedIntegralType, ExpectedArithmeticType, // Runtime UnknownIdentifier, AlreadyDeclaredIdentifier, UninitializedIdentifier, DivisionByZero, ModuloByZero, BreakNotWithinLoop, ContinueNotWithinLoop, }; using ErrorData = variant; class UserError : public exception { public: explicit UserError(ErrorType type, CodePosition pos, ErrorData data = {}) : pos(pos), type(type), data(data) {} const char* what() const noexcept override { return "User error occured."; } string get_message(void) const; const CodePosition pos; const ErrorType type; const ErrorData data; }; class SyntaxError : public UserError { public: explicit SyntaxError(ErrorType type, CodePosition pos, ErrorData data = {}) : UserError(type, pos, data) {} }; class TypeError : public UserError { public: explicit TypeError(ErrorType type, CodePosition pos, ErrorData data = {}) : UserError(type, pos, data) {} }; class RuntimeError : public UserError { public: explicit RuntimeError(ErrorType type, CodePosition pos, ErrorData data = {}) : UserError(type, pos, data) {} }; class InternalError : public exception { public: explicit InternalError(CodePosition pos = {}) : pos(pos) {} const char* what() const noexcept override { return "Internal error occurred."; } const CodePosition pos; }; /** * Display the line of code associated with an error, and highlight the associated part */ void print_error_position(vector history, CodePosition pos); /** * Returns the error message associated with a user error */ string get_error_message(const UserError& e); #endif