Implement multiplication

This commit is contained in:
2024-03-03 13:11:39 +01:00
parent 3a6d89767b
commit d2516cb76c
25 changed files with 343 additions and 1989 deletions

View File

@ -1,7 +1,15 @@
#include "elna/lexer.hpp"
#include <cstring>
namespace elna
{
namespace lex
{
using source_position = elna::source::position;
using source_error = elna::source::error;
using source_result = elna::source::result<std::vector<Token>>;
source::source(const std::string& buffer)
: m_buffer(buffer)
{
@ -14,18 +22,18 @@ namespace elna
source::const_iterator source::end() const
{
Position end_position{ 0, 0 };
source_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 Position start_position)
const source_position start_position)
: m_buffer(buffer), m_position(start_position)
{
}
const Position& source::const_iterator::position() const noexcept
const source_position& source::const_iterator::position() const noexcept
{
return this->m_position;
}
@ -73,7 +81,7 @@ namespace elna
return !(*this == that);
}
Token::Token(const Type of, const char *value, Position position)
Token::Token(const type of, const char *value, source_position position)
: m_type(of), m_position(position)
{
std::size_t value_length = strlen(value);
@ -85,13 +93,13 @@ namespace elna
m_value.identifier = buffer;
}
Token::Token(const Type of, std::int32_t number, Position position)
Token::Token(const type of, std::int32_t number, source_position position)
: m_type(of), m_position(position)
{
m_value.number = number;
}
Token::Token(const Type of, Position position)
Token::Token(const type of, source_position position)
: m_type(of), m_position(position)
{
}
@ -110,7 +118,7 @@ namespace elna
Token::~Token()
{
if (m_type == TOKEN_IDENTIFIER || m_type == TOKEN_OPERATOR)
if (m_type == type::identifier || m_type == type::term_operator || m_type == type::factor_operator)
{
std::free(const_cast<char*>(m_value.identifier));
}
@ -120,7 +128,7 @@ namespace elna
{
m_type = that.of();
m_position = that.position();
if (that.of() == TOKEN_IDENTIFIER || that.of() == TOKEN_OPERATOR)
if (that.of() == type::identifier || that.of() == type::term_operator || m_type == type::factor_operator)
{
std::size_t value_length = strlen(that.identifier());
char *buffer = reinterpret_cast<char *>(malloc(value_length + 1));
@ -130,7 +138,7 @@ namespace elna
m_value.identifier = buffer;
}
else if (that.of() == TOKEN_NUMBER)
else if (that.of() == type::number)
{
m_value.number = that.number();
}
@ -141,19 +149,19 @@ namespace elna
{
m_type = that.of();
m_position = that.position();
if (that.of() == TOKEN_IDENTIFIER || that.of() == TOKEN_OPERATOR)
if (that.of() == type::identifier || that.of() == type::term_operator || that.of() == type::factor_operator)
{
m_value.identifier = that.identifier();
that.m_value.identifier = nullptr;
}
else if (that.of() == TOKEN_NUMBER)
else if (that.of() == type::number)
{
m_value.number = that.number();
}
return *this;
}
Token::Type Token::of() const noexcept
Token::type Token::of() const noexcept
{
return m_type;
}
@ -168,12 +176,12 @@ namespace elna
return m_value.number;
}
const Position& Token::position() const noexcept
const source_position& Token::position() const noexcept
{
return m_position;
}
Token *lex(const char *buffer, CompileError *compile_error, std::size_t *length)
source_result lex(const char *buffer)
{
std::vector<Token> tokens;
source input{ buffer };
@ -186,38 +194,38 @@ namespace elna
else if (std::isdigit(*iterator))
{
tokens.emplace_back(
Token::TOKEN_NUMBER,
Token::type::number,
static_cast<std::int32_t>(*iterator - '0'),
iterator.position()
);
}
else if (*iterator == '=')
{
tokens.emplace_back(Token::TOKEN_EQUALS, iterator.position());
tokens.emplace_back(Token::type::equals, iterator.position());
}
else if (*iterator == '(')
{
tokens.emplace_back(Token::TOKEN_LEFT_PAREN, iterator.position());
tokens.emplace_back(Token::type::left_paren, iterator.position());
}
else if (*iterator == ')')
{
tokens.emplace_back(Token::TOKEN_RIGHT_PAREN, iterator.position());
tokens.emplace_back(Token::type::right_paren, iterator.position());
}
else if (*iterator == ';')
{
tokens.emplace_back(Token::TOKEN_SEMICOLON, iterator.position());
tokens.emplace_back(Token::type::semicolon, iterator.position());
}
else if (*iterator == ',')
{
tokens.emplace_back(Token::TOKEN_COMMA, iterator.position());
tokens.emplace_back(Token::type::comma, iterator.position());
}
else if (*iterator == '!')
{
tokens.emplace_back(Token::TOKEN_BANG, iterator.position());
tokens.emplace_back(Token::type::bang, iterator.position());
}
else if (*iterator == '.')
{
tokens.emplace_back(Token::TOKEN_DOT, iterator.position());
tokens.emplace_back(Token::type::dot, iterator.position());
}
else if (std::isalpha(*iterator))
{
@ -230,15 +238,15 @@ namespace elna
}
if (word == "const")
{
tokens.emplace_back(Token::TOKEN_LET, iterator.position());
tokens.emplace_back(Token::type::let, iterator.position());
}
else if (word == "var")
{
tokens.emplace_back(Token::TOKEN_VAR, iterator.position());
tokens.emplace_back(Token::type::var, iterator.position());
}
else
{
tokens.emplace_back(Token::TOKEN_IDENTIFIER, word.c_str(), iterator.position());
tokens.emplace_back(Token::type::identifier, word.c_str(), iterator.position());
}
iterator = i;
continue;
@ -247,24 +255,21 @@ namespace elna
{
std::string _operator{ *iterator };
tokens.emplace_back(Token::TOKEN_OPERATOR, _operator.c_str(), iterator.position());
tokens.emplace_back(Token::type::term_operator, _operator.c_str(), iterator.position());
}
else if (*iterator == '*' || *iterator == '/')
{
std::string _operator{ *iterator };
tokens.emplace_back(Token::type::factor_operator, _operator.c_str(), iterator.position());
}
else
{
*compile_error = CompileError("Unexpected next character", iterator.position());
return nullptr;
return source_result("Unexpected next character", iterator.position());
}
++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 target;
return source_result(tokens);
}
}
}