Print test summary
This commit is contained in:
187
source/lexer.cpp
187
source/lexer.cpp
@@ -14,18 +14,18 @@ namespace elna
|
||||
|
||||
source::const_iterator source::end() const
|
||||
{
|
||||
source_position end_position{ 0, 0 };
|
||||
Position end_position{ 0, 0 };
|
||||
|
||||
return source::const_iterator(std::cend(m_buffer), end_position);
|
||||
}
|
||||
|
||||
source::const_iterator::const_iterator(std::string::const_iterator buffer,
|
||||
const source_position start_position)
|
||||
const Position start_position)
|
||||
: m_buffer(buffer), m_position(start_position)
|
||||
{
|
||||
}
|
||||
|
||||
const source_position& source::const_iterator::position() const noexcept
|
||||
const Position& source::const_iterator::position() const noexcept
|
||||
{
|
||||
return this->m_position;
|
||||
}
|
||||
@@ -73,29 +73,109 @@ namespace elna
|
||||
return !(*this == that);
|
||||
}
|
||||
|
||||
token::token(const type of, source::const_iterator begin, source::const_iterator end)
|
||||
: m_type(of), m_value(begin, end)
|
||||
Token::Token(const Type of, const char *value, Position position)
|
||||
: m_type(of), m_position(position)
|
||||
{
|
||||
std::size_t value_length = strlen(value);
|
||||
char *buffer = reinterpret_cast<char *>(malloc(value_length + 1));
|
||||
|
||||
std::memcpy(buffer, value, value_length);
|
||||
buffer[value_length] = 0;
|
||||
|
||||
m_value.identifier = buffer;
|
||||
}
|
||||
|
||||
Token::Token(const Type of, std::int32_t number, Position position)
|
||||
: m_type(of), m_position(position)
|
||||
{
|
||||
m_value.number = number;
|
||||
}
|
||||
|
||||
Token::Token(const Type of, Position position)
|
||||
: m_type(of), m_position(position)
|
||||
{
|
||||
}
|
||||
|
||||
token::type token::of() const noexcept
|
||||
Token::Token(const Token& that)
|
||||
: m_type(that.of()), m_position(that.position())
|
||||
{
|
||||
*this = that;
|
||||
}
|
||||
|
||||
Token::Token(Token&& that)
|
||||
: m_type(that.of()), m_position(that.position())
|
||||
{
|
||||
*this = std::move(that);
|
||||
}
|
||||
|
||||
Token::~Token()
|
||||
{
|
||||
if (m_type == TOKEN_IDENTIFIER || m_type == TOKEN_OPERATOR)
|
||||
{
|
||||
std::free(const_cast<char*>(m_value.identifier));
|
||||
}
|
||||
}
|
||||
|
||||
Token& Token::operator=(const Token& that)
|
||||
{
|
||||
m_type = that.of();
|
||||
m_position = that.position();
|
||||
if (that.of() == TOKEN_IDENTIFIER || that.of() == TOKEN_OPERATOR)
|
||||
{
|
||||
std::size_t value_length = strlen(that.identifier());
|
||||
char *buffer = reinterpret_cast<char *>(malloc(value_length + 1));
|
||||
|
||||
std::memcpy(buffer, that.identifier(), value_length);
|
||||
buffer[value_length] = 0;
|
||||
|
||||
m_value.identifier = buffer;
|
||||
}
|
||||
else if (that.of() == TOKEN_NUMBER)
|
||||
{
|
||||
m_value.number = that.number();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Token& Token::operator=(Token&& that)
|
||||
{
|
||||
m_type = that.of();
|
||||
m_position = that.position();
|
||||
if (that.of() == TOKEN_IDENTIFIER || that.of() == TOKEN_OPERATOR)
|
||||
{
|
||||
m_value.identifier = that.identifier();
|
||||
that.m_value.identifier = nullptr;
|
||||
}
|
||||
else if (that.of() == TOKEN_NUMBER)
|
||||
{
|
||||
m_value.number = that.number();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Token::Type Token::of() const noexcept
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
const token::value& token::identifier() const noexcept
|
||||
const char *Token::identifier() const noexcept
|
||||
{
|
||||
return m_value;
|
||||
return m_value.identifier;
|
||||
}
|
||||
|
||||
const source_position& token::position() const noexcept
|
||||
std::int32_t Token::number() const noexcept
|
||||
{
|
||||
return m_value.number;
|
||||
}
|
||||
|
||||
const Position& Token::position() const noexcept
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
result<std::vector<token>> lex(const std::string& buffer)
|
||||
Token *lex(const char *buffer, CompileError *compile_error, std::size_t *length)
|
||||
{
|
||||
std::vector<token> tokens;
|
||||
std::vector<Token> tokens;
|
||||
source input{ buffer };
|
||||
|
||||
for (auto iterator = input.begin(); iterator != input.end();)
|
||||
@@ -103,23 +183,88 @@ namespace elna
|
||||
if (*iterator == ' ' || *iterator == '\n')
|
||||
{
|
||||
}
|
||||
else if (std::isgraph(*iterator))
|
||||
else if (std::isdigit(*iterator))
|
||||
{
|
||||
auto current_position = iterator;
|
||||
do
|
||||
tokens.emplace_back(
|
||||
Token::TOKEN_NUMBER,
|
||||
static_cast<std::int32_t>(*iterator - '0'),
|
||||
iterator.position()
|
||||
);
|
||||
}
|
||||
else if (*iterator == '=')
|
||||
{
|
||||
tokens.emplace_back(Token::TOKEN_EQUALS, iterator.position());
|
||||
}
|
||||
else if (*iterator == '(')
|
||||
{
|
||||
tokens.emplace_back(Token::TOKEN_LEFT_PAREN, iterator.position());
|
||||
}
|
||||
else if (*iterator == ')')
|
||||
{
|
||||
tokens.emplace_back(Token::TOKEN_RIGHT_PAREN, iterator.position());
|
||||
}
|
||||
else if (*iterator == ';')
|
||||
{
|
||||
tokens.emplace_back(Token::TOKEN_SEMICOLON, iterator.position());
|
||||
}
|
||||
else if (*iterator == ',')
|
||||
{
|
||||
tokens.emplace_back(Token::TOKEN_COMMA, iterator.position());
|
||||
}
|
||||
else if (*iterator == '!')
|
||||
{
|
||||
tokens.emplace_back(Token::TOKEN_BANG, iterator.position());
|
||||
}
|
||||
else if (*iterator == '.')
|
||||
{
|
||||
tokens.emplace_back(Token::TOKEN_DOT, iterator.position());
|
||||
}
|
||||
else if (std::isalpha(*iterator))
|
||||
{
|
||||
std::string word;
|
||||
auto i = iterator;
|
||||
while (i != input.end() && std::isalpha(*i))
|
||||
{
|
||||
++current_position;
|
||||
word.push_back(*i);
|
||||
++i;
|
||||
}
|
||||
while (current_position != input.end() && std::isgraph(*current_position));
|
||||
token new_token{ token::type::word, iterator, current_position };
|
||||
|
||||
tokens.push_back(new_token);
|
||||
iterator = current_position;
|
||||
if (word == "const")
|
||||
{
|
||||
tokens.emplace_back(Token::TOKEN_LET, iterator.position());
|
||||
}
|
||||
else if (word == "var")
|
||||
{
|
||||
tokens.emplace_back(Token::TOKEN_VAR, iterator.position());
|
||||
}
|
||||
else
|
||||
{
|
||||
tokens.emplace_back(Token::TOKEN_IDENTIFIER, word.c_str(), iterator.position());
|
||||
}
|
||||
iterator = i;
|
||||
continue;
|
||||
}
|
||||
else if (*iterator == '+' || *iterator == '-')
|
||||
{
|
||||
std::string _operator{ *iterator };
|
||||
|
||||
tokens.emplace_back(Token::TOKEN_OPERATOR, _operator.c_str(), iterator.position());
|
||||
}
|
||||
else
|
||||
{
|
||||
*compile_error = CompileError("Unexpected next character", iterator.position());
|
||||
return nullptr;
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
Token *target = reinterpret_cast<Token *>(malloc(tokens.size() * sizeof(Token) + sizeof(Token)));
|
||||
int i = 0;
|
||||
for (auto& token : tokens)
|
||||
{
|
||||
target[i] = std::move(token);
|
||||
++i;
|
||||
}
|
||||
*length = i;
|
||||
|
||||
return tokens;
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user