#include #include namespace Token { Token::Token(TokenType _type, bool validness, int const _lineNumber, int const _lineColumn) : lineNumber(_lineNumber), lineColumn(_lineColumn), type(_type), valueType(TokenValueType::None), isValid(validness), data(0), errorMessage() { } Token::Token(TokenType _type, std::string const & string, bool validness, int const _lineNumber, int const _lineColumn) : lineNumber(_lineNumber), lineColumn(_lineColumn), type(_type), valueType(TokenValueType::String), isValid(validness), data(string), errorMessage() { } Token::Token(TokenType _type, int value, bool validness, int const _lineNumber, int const _lineColumn) : lineNumber(_lineNumber), lineColumn(_lineColumn), type(_type), valueType(TokenValueType::Integer), isValid(validness), data(value), errorMessage() { } Token::Token(TokenType _type, RegisterType const registerType, bool validness, int const _lineNumber, int const _lineColumn) : lineNumber(_lineNumber), lineColumn(_lineColumn), type(_type), valueType(TokenValueType::Register), isValid(validness), data(registerType), errorMessage() { } Token::Token(TokenType _type, OperandType const operandType, bool validness, int const _lineNumber, int const _lineColumn) : lineNumber(_lineNumber), lineColumn(_lineColumn), type(_type), valueType(TokenValueType::Operand), isValid(validness), data(operandType), errorMessage() { } Token::Token(Token const & other) : lineNumber(other.lineNumber), lineColumn(other.lineColumn), type(other.type), valueType(other.valueType), isValid(other.isValid), data(other.data), errorMessage(other.errorMessage) { } Token Token::CreateEmptyToken(int const lineNumber, int const lineColumn) { return Token(TokenType::Unknown, false, lineNumber, lineColumn); } Token Token::CreateErrorToken(std::string const & message, TokenType const type, int const lineNumber, int const lineColumn) { Token token(type, false, lineNumber, lineColumn); token.errorMessage = message; return token; } Token Token::CreateStatementEndToken(int const lineNumber, int const lineColumn) { return Token(TokenType::StatementEnd, true, lineNumber, lineColumn); } Token Token::CreateLabelToken(std::string const & string, int const lineNumber, int const lineColumn) { return Token(TokenType::Label, string, true, lineNumber, lineColumn); } Token Token::CreateImmediateValueToken(int const value, int const lineNumber, int const lineColumn) { return Token(TokenType::ImmediateInteger, value, true, lineNumber, lineColumn); } Token Token::CreateRegisterToken(RegisterType const registerType, int const lineNumber, int const lineColumn) { return Token(TokenType::Register, registerType, registerType != RegisterType::Unknown, lineNumber, lineColumn); } Token Token::CreateOperandToken(OperandType const operandType, int const lineNumber, int const lineColumn) { return Token(TokenType::Operand, operandType, operandType != OperandType::Unknown, lineNumber, lineColumn); } Token Token::CreateMemoryToken(RegisterType const registerType, int const lineNumber, int const lineColumn) { return Token(TokenType::Memory, registerType, registerType != RegisterType::Unknown, lineNumber, lineColumn); } Token Token::CreateMemoryToken(int const value, int const lineNumber, int const lineColumn) { return Token(TokenType::Memory, value, true, lineNumber, lineColumn); } void Token::DebugPrint() const { std::putc(' ', stdout); switch(type) { case TokenType::ImmediateInteger: if (isValid) { std::printf("%i", std::get(data)); } else { std::printf("BAD_IMM"); } break; case TokenType::Operand: if (isValid) { OperandType const opType = std::get(data); switch(opType) { case OperandType::Unknown: std::printf("unknown_op"); break; default: std::printf("op%i", static_cast(opType)); break; } } else { std::printf("BAD_OP"); } break; case TokenType::Register: if (isValid) { RegisterType const regType = std::get(data); switch(regType) { default: std::printf("%%%i", static_cast(regType)); break; case RegisterType::Unknown: std::printf("%%unknown_reg"); break; } } else { std::printf("BAD_REG"); } break; case TokenType::StatementEnd: std::printf("EOS"); break; case TokenType::Label: std::printf("LABEL=%s", std::get(data).c_str()); break; case TokenType::Memory: { switch(valueType) { case TokenValueType::Integer: std::printf("[$%i]", std::get(data)); break; case TokenValueType::Register: std::printf("[%%%i]", static_cast(std::get(data))); break; default: std::printf("[UNKNOWN_TYPE]"); break; } } break; case TokenType::Unknown: default: std::printf("UNKNOWN_TOKEN"); break; } } void PrintTokens(std::vector const & tokens) { std::puts("*** Tokenization result ***"); unsigned statementNumber = 0u; std::printf("%02u - ", statementNumber); for(unsigned i = 0u; i < tokens.size(); ++i) { auto const & token = tokens[i]; token.DebugPrint(); if (token.type == TokenType::StatementEnd) { ++statementNumber; if (i + 1 < tokens.size()) { std::printf("\n%02u - ", statementNumber); } else { std::puts(""); } } } } }