Added direct memory access

This commit is contained in:
2019-11-23 16:47:16 +01:00
parent 22bb974a05
commit 1148682324
14 changed files with 329 additions and 92 deletions

View File

@@ -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)