Introduce simple character literal

This commit is contained in:
2020-08-28 20:00:49 +02:00
parent d396628310
commit 593506a907
4 changed files with 102 additions and 14 deletions

View File

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