#include #include #include #include namespace LXC::Lexer { // Constructor to assign the members of the token class // Token::Token(const LexerContext& ctx, unsigned __int32 start, unsigned short len, TokenType _type) : type(_type), length(len), index(start), contents(nullptr) { // Only user defined class tokens need to store c-string // if (Token::IsTypeClass(type)) { // Copies the memory to a c-string // contents = new char[len + 1]; // +1 for null terminator std::memcpy(contents, ctx.source.data() + start, len); contents[len] = '\0'; } } // Destructor to clean up the memory of the token that can be allocated // Token::~Token() { // Frees any allocated memory // //if (contents != nullptr) // delete[] contents; contents = nullptr; } // Helper macro for converting type to string // #define TOKEN_TYPE_CASE(type) case type: return #type; static constexpr const char* TokenTypeToCStr(Token::TokenType type) { switch (type) { // All the different types of tokens // TOKEN_TYPE_CASE(Token::Add); TOKEN_TYPE_CASE(Token::Sub); TOKEN_TYPE_CASE(Token::Mul); TOKEN_TYPE_CASE(Token::Div); TOKEN_TYPE_CASE(Token::Mod); TOKEN_TYPE_CASE(Token::For); TOKEN_TYPE_CASE(Token::While); TOKEN_TYPE_CASE(Token::If); TOKEN_TYPE_CASE(Token::ElseIf); TOKEN_TYPE_CASE(Token::Else); TOKEN_TYPE_CASE(Token::Return); TOKEN_TYPE_CASE(Token::StringLiteral); TOKEN_TYPE_CASE(Token::NumLiteral); TOKEN_TYPE_CASE(Token::Identifier); TOKEN_TYPE_CASE(Token::Assign); TOKEN_TYPE_CASE(Token::CloseBracket); TOKEN_TYPE_CASE(Token::OpenBracket); TOKEN_TYPE_CASE(Token::CloseBrace); TOKEN_TYPE_CASE(Token::OpenBrace); TOKEN_TYPE_CASE(Token::CloseParen); TOKEN_TYPE_CASE(Token::OpenParen); TOKEN_TYPE_CASE(Token::Comma); TOKEN_TYPE_CASE(Token::End_of_file); TOKEN_TYPE_CASE(Token::UNDEFINED); // When the case has not been defined yet // default: return "UNKNOWN"; } } std::string LXC::Lexer::Token::LogStr() const { // Output stream to log to // std::ostringstream os; os << std::setw(25) << std::left << TokenTypeToCStr(type) << " | "; if (contents != nullptr) os << std::setw(25) << std::left << std::string('"' + std::string(contents) + '"'); else os << std::setw(25) << std::left << "EMPTY"; return os.str(); } }