#ifndef FORTH_KATA_TOKEN_H #define FORTH_KATA_TOKEN_H #include #include #include #include #include namespace forth { namespace token { /** * Structure representing a number token (An integer literal). */ struct Number final { std::int16_t value; ///< The numeric value of the token. bool operator==(Number const &rhs) const noexcept; bool operator!=(Number const &rhs) const noexcept; }; /** * Overloaded output operator for Number tokens. * @param os The output stream. * @param number The number. * @return The output stream. */ std::ostream &operator<<(std::ostream &os, Number const &number); /** * Structure representing a keyword token (Special words with fixed meaning). */ struct Keyword final { /* * This value holds the value of the key word. */ std::string value; bool operator==(Keyword const &rhs) const noexcept; bool operator!=(Keyword const &rhs) const noexcept; }; /** * Overloaded output operator for Keyword tokens. * @param os The output stream. * @param keyword The keyword. * @return The output stream. */ std::ostream &operator<<(std::ostream &os, Keyword const &keyword); /** * Structure representing a word token (Words that are neither keywords nor numbers). */ struct Word final { std::string value; bool operator==(Word const &rhs) const noexcept; bool operator!=(Word const &rhs) const noexcept; }; /** * Overloaded output operator for Word tokens. * @param os The output stream. * @param word The word. * @return The output stream. */ std::ostream &operator<<(std::ostream &os, Word const &word); } // namespace token struct WrongTokenException : std::runtime_error { using std::runtime_error::runtime_error; using std::runtime_error::operator=; }; class Token final { enum class Type { Number, Keyword, Word, }; public: Token(token::Number value) noexcept; Token(token::Keyword value) noexcept; Token(token::Word value) noexcept; Token(Token const &src); Token(Token &&src) noexcept; Token &operator=(Token const &src); Token &operator=(Token &&src) noexcept; ~Token() noexcept; bool IsNumber() const noexcept; bool IsKeyword() const noexcept; bool IsWord() const noexcept; token::Number const &GetNumber() const; token::Keyword const &GetKeyword() const; token::Word const &GetWord() const; bool operator==(Token const &rhs) const noexcept; bool operator!=(Token const &rhs) const noexcept; private: void destroy() noexcept; template void destroy(TType *p) { Expects(p != nullptr); p->~TType(); } Type type; union { token::Number number; token::Keyword keyword; token::Word word; }; }; /** * Overloaded output operator for Tokens. * @param os The output stream. * @param token The token. * @return The output stream. */ std::ostream &operator<<(std::ostream &os, Token const &token); } // namespace forth #endif // !FORTH_KATA_TOKEN_H