Added direct memory access
This commit is contained in:
@@ -3,47 +3,53 @@
|
||||
|
||||
namespace Token
|
||||
{
|
||||
Token::Token(int const _lineNumber, int const _lineColumn)
|
||||
Token::Token(TokenType _type, bool validness, int const _lineNumber, int const _lineColumn)
|
||||
: lineNumber(_lineNumber),
|
||||
lineColumn(_lineColumn),
|
||||
type(TokenType::Unknown),
|
||||
isValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
Token::Token(int const _lineNumber, int const _lineColumn, OperandType _operatorType, bool validness)
|
||||
: lineNumber(_lineNumber),
|
||||
lineColumn(_lineColumn),
|
||||
type(TokenType::Operand),
|
||||
type(_type),
|
||||
valueType(TokenValueType::None),
|
||||
isValid(validness),
|
||||
data(_operatorType)
|
||||
data(0)
|
||||
{
|
||||
}
|
||||
|
||||
Token::Token(int const _lineNumber, int const _lineColumn, RegisterType _registerType, bool validness)
|
||||
Token::Token(TokenType _type, std::string const & string, bool validness, int const _lineNumber, int const _lineColumn)
|
||||
: lineNumber(_lineNumber),
|
||||
lineColumn(_lineColumn),
|
||||
type(TokenType::Register),
|
||||
type(_type),
|
||||
valueType(TokenValueType::String),
|
||||
isValid(validness),
|
||||
data(_registerType)
|
||||
data(string)
|
||||
{
|
||||
}
|
||||
|
||||
Token::Token(int const _lineNumber, int const _lineColumn, int value, bool validness)
|
||||
Token::Token(TokenType _type, int value, bool validness, int const _lineNumber, int const _lineColumn)
|
||||
: lineNumber(_lineNumber),
|
||||
lineColumn(_lineColumn),
|
||||
type(TokenType::ImmediateInteger),
|
||||
type(_type),
|
||||
valueType(TokenValueType::Integer),
|
||||
isValid(validness),
|
||||
data(value)
|
||||
{
|
||||
}
|
||||
|
||||
Token::Token(int const _lineNumber, int const _lineColumn, std::string const & value, bool validness)
|
||||
Token::Token(TokenType _type, RegisterType const registerType, bool validness, int const _lineNumber, int const _lineColumn)
|
||||
: lineNumber(_lineNumber),
|
||||
lineColumn(_lineColumn),
|
||||
type(TokenType::Label),
|
||||
type(_type),
|
||||
valueType(TokenValueType::Register),
|
||||
isValid(validness),
|
||||
data(value)
|
||||
data(registerType)
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -52,10 +58,51 @@ namespace Token
|
||||
lineColumn(other.lineColumn),
|
||||
type(other.type),
|
||||
isValid(other.isValid),
|
||||
valueType(other.valueType),
|
||||
data(other.data)
|
||||
{
|
||||
}
|
||||
|
||||
Token Token::CreateUnknownToken(int const lineNumber, int const lineColumn)
|
||||
{
|
||||
return Token(TokenType::Unknown, false, lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
Token Token::CreateStatementEndToken(int const lineNumber, int const lineColumn)
|
||||
{
|
||||
return Token(TokenType::StatementEnd, true, lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
Token Token::CreateLabelToken(std::string const & string, bool isValid, int const lineNumber, int const lineColumn)
|
||||
{
|
||||
return Token(TokenType::Label, string, isValid, lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
Token Token::CreateImmediateValueToken(int const value, bool isValid, int const lineNumber, int const lineColumn)
|
||||
{
|
||||
return Token(TokenType::ImmediateInteger, value, isValid, 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, bool isValid, int const lineNumber, int const lineColumn)
|
||||
{
|
||||
return Token(TokenType::Memory, value, isValid, lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
void Token::DebugPrint() const
|
||||
{
|
||||
std::putc(' ', stdout);
|
||||
@@ -122,6 +169,25 @@ namespace Token
|
||||
std::printf("LABEL=%s", std::get<std::string>(data).c_str());
|
||||
break;
|
||||
|
||||
case TokenType::Memory:
|
||||
{
|
||||
switch(valueType)
|
||||
{
|
||||
case TokenValueType::Integer:
|
||||
std::printf("[$%i]", std::get<int>(data));
|
||||
break;
|
||||
|
||||
case TokenValueType::Register:
|
||||
std::printf("[%%%i]", static_cast<int>(std::get<RegisterType>(data)));
|
||||
break;
|
||||
|
||||
default:
|
||||
std::printf("[UNKNOWN_TYPE]");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TokenType::Unknown:
|
||||
default:
|
||||
std::printf("UNKNOWN_TOKEN");
|
||||
|
||||
@@ -8,58 +8,87 @@ namespace Token
|
||||
return c == '\n' || c == ' ' || c == '\t' || c == '\r';
|
||||
}
|
||||
|
||||
std::tuple<int, bool> TryParse(std::string const & string)
|
||||
{
|
||||
try
|
||||
{
|
||||
int value = std::stoi(string);
|
||||
return std::make_tuple(value, true);
|
||||
}
|
||||
catch(std::invalid_argument &)
|
||||
{
|
||||
return std::make_tuple(0, false);
|
||||
}
|
||||
}
|
||||
|
||||
Token ExtractToken(std::string const & string, int const lineNumber, int const lineColumn)
|
||||
{
|
||||
if (string.size() == 0)
|
||||
{
|
||||
return Token(lineNumber, lineColumn);
|
||||
return Token::CreateUnknownToken(lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
char const prefix = string[0];
|
||||
if (prefix == '$')
|
||||
{
|
||||
int value = 0;
|
||||
try
|
||||
{
|
||||
value = std::stoi(string.substr(1, string.size()));
|
||||
}
|
||||
catch(std::invalid_argument &)
|
||||
{
|
||||
return Token(lineNumber, lineColumn, 0, false);
|
||||
}
|
||||
|
||||
return Token(lineNumber, lineColumn, value, true);
|
||||
auto const result = TryParse(string.substr(1, string.size()));
|
||||
return Token::CreateImmediateValueToken(std::get<0>(result), std::get<1>(result), lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
if (prefix == '%')
|
||||
{
|
||||
RegisterType const rtype = GetRegisterType(string.substr(1, string.size()));
|
||||
return Token(lineNumber, lineColumn, rtype, rtype != RegisterType::Unknown);
|
||||
return Token::CreateRegisterToken(GetRegisterType(string.substr(1, string.size())), lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
if (prefix == ';')
|
||||
{
|
||||
Token token(lineNumber, lineColumn);
|
||||
token.type = TokenType::StatementEnd;
|
||||
token.isValid = true;
|
||||
return token;
|
||||
return Token::CreateStatementEndToken(lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
char const postfix = string[string.size() - 1];
|
||||
if (postfix == ':')
|
||||
{
|
||||
// TODO check if label is an Operand?
|
||||
return Token(lineNumber, lineColumn, string.substr(0, string.size() - 1), true);
|
||||
return Token::CreateLabelToken(string.substr(0, string.size() - 1), true, lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
if (prefix == '[' && postfix == ']')
|
||||
{
|
||||
if(string.size() < 4)
|
||||
{
|
||||
return Token::CreateMemoryToken(0, false, lineNumber, lineColumn + 2u);
|
||||
}
|
||||
|
||||
char const memoryPrefix = string[1];
|
||||
std::string const valueString = string.substr(2, string.size() - 3u);
|
||||
if (memoryPrefix == '$')
|
||||
{
|
||||
auto const result = TryParse(valueString);
|
||||
return Token::CreateMemoryToken(std::get<0>(result), std::get<1>(result), lineNumber, lineColumn);
|
||||
}
|
||||
else if (memoryPrefix == '%')
|
||||
{
|
||||
return Token::CreateMemoryToken(GetRegisterType(valueString), lineNumber, lineColumn);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Token::CreateMemoryToken(0, false, lineNumber, lineColumn + 1u);
|
||||
}
|
||||
}
|
||||
else if (prefix == '[' || postfix == ']')
|
||||
{
|
||||
int const errorLineColumn = (prefix == '[') ? lineColumn : (lineColumn + string.size() - 1u);
|
||||
return Token::CreateMemoryToken(0, false, lineNumber, errorLineColumn);
|
||||
}
|
||||
|
||||
OperandType const opType = GetOperandType(string);
|
||||
if (opType != OperandType::Unknown)
|
||||
{
|
||||
return Token(lineNumber, lineColumn, opType, true);
|
||||
return Token::CreateOperandToken(opType, lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
// Last resort: it must be a label
|
||||
return Token(lineNumber, lineColumn, string, true);
|
||||
return Token::CreateLabelToken(string, true, lineNumber, lineColumn);
|
||||
}
|
||||
|
||||
void Tokenizer::Tokenize(std::string const & line, int const lineNumber, std::vector<Token> & tokens)
|
||||
|
||||
Reference in New Issue
Block a user