Introduce simple character literal
This commit is contained in:
@@ -1,20 +1,21 @@
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <token/errors.hpp>
|
||||
#include <token/tokenizer.hpp>
|
||||
|
||||
namespace Token
|
||||
{
|
||||
std::tuple<int, bool> TryParseInt(std::string const & string)
|
||||
std::optional<int> TryParseInt(std::string const & string)
|
||||
{
|
||||
try
|
||||
{
|
||||
int value = std::stoi(string);
|
||||
return std::make_tuple(value, true);
|
||||
return std::make_optional<int>(value);
|
||||
}
|
||||
catch(std::invalid_argument &)
|
||||
{
|
||||
return std::make_tuple(0, false);
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,9 +43,19 @@ namespace Token
|
||||
case '$':
|
||||
{
|
||||
auto const result = TryParseInt(string.substr(1, string.size()));
|
||||
|
||||
if (result.has_value())
|
||||
{
|
||||
return Token::CreateImmediateValueToken(
|
||||
result.value(),
|
||||
true,
|
||||
lineNumber,
|
||||
lineColumn);
|
||||
}
|
||||
|
||||
return Token::CreateImmediateValueToken(
|
||||
std::get<0>(result),
|
||||
std::get<1>(result),
|
||||
0,
|
||||
false,
|
||||
lineNumber,
|
||||
lineColumn);
|
||||
}
|
||||
@@ -85,9 +96,19 @@ namespace Token
|
||||
if (memoryPrefix == '$')
|
||||
{
|
||||
auto const result = TryParseInt(valueString);
|
||||
|
||||
if (result.has_value())
|
||||
{
|
||||
return Token::CreateMemoryToken(
|
||||
result.value(),
|
||||
true,
|
||||
lineNumber,
|
||||
lineColumn);
|
||||
}
|
||||
|
||||
return Token::CreateMemoryToken(
|
||||
std::get<0>(result),
|
||||
std::get<1>(result),
|
||||
0,
|
||||
false,
|
||||
lineNumber,
|
||||
lineColumn);
|
||||
}
|
||||
@@ -224,6 +245,51 @@ end_state_loop:
|
||||
}
|
||||
}
|
||||
|
||||
// Modifies the lineColumn parameter to point at the character literal end
|
||||
void Tokenizer::ParseCharacterLiteral(
|
||||
std::string const & line,
|
||||
int const lineNumber,
|
||||
unsigned & lineColumn,
|
||||
std::vector<Token> & tokens) const
|
||||
{
|
||||
for(unsigned int i = lineColumn + 1; i < line.size(); ++i)
|
||||
{
|
||||
if (line[i] == '\'')
|
||||
{
|
||||
// Character literal must be exactly length 3 for now (2x ' + 1
|
||||
// character in between)
|
||||
if (lineColumn + 2u != i)
|
||||
{
|
||||
tokens.emplace_back(Token::CreateImmediateValueToken(
|
||||
0,
|
||||
false,
|
||||
lineNumber,
|
||||
lineColumn));
|
||||
}
|
||||
else
|
||||
{
|
||||
tokens.emplace_back(Token::CreateImmediateValueToken(
|
||||
line[i - 1],
|
||||
true,
|
||||
lineNumber,
|
||||
lineColumn));
|
||||
}
|
||||
|
||||
lineColumn = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Non terminated character literal!
|
||||
tokens.emplace_back(Token::CreateImmediateValueToken(
|
||||
0,
|
||||
false,
|
||||
lineNumber,
|
||||
lineColumn));
|
||||
|
||||
lineColumn = line.size();
|
||||
}
|
||||
|
||||
void Tokenizer::Tokenize(
|
||||
std::string const & line,
|
||||
int const lineNumber,
|
||||
@@ -250,6 +316,12 @@ end_state_loop:
|
||||
return;
|
||||
}
|
||||
|
||||
if (line[column] == '\'')
|
||||
{
|
||||
ParseCharacterLiteral(line, lineNumber, column, tokens);
|
||||
break;
|
||||
}
|
||||
|
||||
columnTokenStart = column;
|
||||
|
||||
switch(line[column])
|
||||
|
||||
Reference in New Issue
Block a user