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

@ -40,17 +40,22 @@ namespace elna
this->lhs = lhs;
this->rhs = rhs;
if (_operator == '+')
switch (_operator)
{
this->_operator = BinaryOperator::sum;
}
else if (_operator == '-')
{
this->_operator = BinaryOperator::subtraction;
}
else
{
throw std::logic_error("Invalid binary operator");
case '+':
this->_operator = BinaryOperator::sum;
break;
case '-':
this->_operator = BinaryOperator::subtraction;
break;
case '*':
this->_operator = BinaryOperator::multiplication;
break;
case '/':
this->_operator = BinaryOperator::division;
break;
default:
throw std::logic_error("Invalid binary operator");
}
}
@ -64,14 +69,14 @@ namespace elna
visitor->visit(this);
}
Block *parse(Token *tokenStream, std::size_t length)
Block *parse(lex::Token *tokenStream, std::size_t length)
{
return parseBlock(&tokenStream, &length);
}
Expression *parseFactor(Token **tokens, size_t *length)
Expression *parseFactor(lex::Token **tokens, size_t *length)
{
if ((*tokens)[0].of() == Token::TOKEN_IDENTIFIER)
if ((*tokens)[0].of() == lex::Token::type::identifier)
{
auto variable = new Variable();
variable->identifier = (*tokens)[0].identifier();
@ -79,7 +84,7 @@ namespace elna
--(*length);
return variable;
}
else if ((*tokens)[0].of() == Token::TOKEN_NUMBER)
else if ((*tokens)[0].of() == lex::Token::Token::type::number)
{
auto number = new Number();
number->value = (*tokens)[0].number();
@ -87,7 +92,7 @@ namespace elna
--(*length);
return number;
}
else if ((*tokens)[0].of() == Token::TOKEN_LEFT_PAREN)
else if ((*tokens)[0].of() == lex::Token::type::left_paren)
{
++(*tokens);
--(*length);
@ -102,15 +107,29 @@ namespace elna
return nullptr;
}
Expression *parseTerm(Token **tokens, size_t *length)
Expression *parseTerm(lex::Token **tokens, size_t *length)
{
return parseFactor(tokens, length);
auto lhs = parseFactor(tokens, length);
if (lhs == nullptr || *length == 0 || (*tokens)[0].of() != lex::Token::type::factor_operator)
{
return lhs;
}
auto _operator = (*tokens)[0].identifier()[0];
++(*tokens);
--(*length);
auto rhs = parseFactor(tokens, length);
if (rhs != nullptr)
{
return new BinaryExpression(lhs, rhs, _operator);
}
return nullptr;
}
Expression *parseExpression(Token **tokens, size_t *length)
Expression *parseExpression(lex::Token **tokens, size_t *length)
{
auto term = parseTerm(tokens, length);
if (term == nullptr || *length == 0 || (*tokens)[0].of() != Token::TOKEN_OPERATOR)
if (term == nullptr || *length == 0 || (*tokens)[0].of() != lex::Token::type::term_operator)
{
return term;
}
@ -122,17 +141,12 @@ namespace elna
if (expression != nullptr)
{
auto binaryExpression = new BinaryExpression(term, expression, _operator);
return binaryExpression;
}
else
{
return nullptr;
return new BinaryExpression(term, expression, _operator);
}
return nullptr;
}
Definition *parseDefinition(Token **tokens, size_t *length)
Definition *parseDefinition(lex::Token **tokens, size_t *length)
{
auto definition = new Definition();
definition->identifier = (*tokens)[0].identifier(); // Copy.
@ -141,7 +155,7 @@ namespace elna
++(*tokens); // Skip the equals sign.
*length -= 2;
if ((*tokens)[0].of() == Token::TOKEN_NUMBER)
if ((*tokens)[0].of() == lex::Token::type::number)
{
auto number = new Number();
number->value = (*tokens)[0].number();
@ -153,9 +167,9 @@ namespace elna
return nullptr;
}
Statement *parseStatement(Token **tokens, std::size_t *length)
Statement *parseStatement(lex::Token **tokens, std::size_t *length)
{
if ((*tokens)[0].of() == Token::TOKEN_BANG)
if ((*tokens)[0].of() == lex::Token::type::bang)
{
++(*tokens);
--(*length);
@ -174,7 +188,7 @@ namespace elna
return nullptr;
}
Definition **parseDefinitions(Token **tokens, size_t *length, size_t *resultLength)
Definition **parseDefinitions(lex::Token **tokens, size_t *length, size_t *resultLength)
{
++(*tokens); // Skip const.
--(*length);
@ -193,11 +207,11 @@ namespace elna
realloc(definitions, (*resultLength + 1) * sizeof(Definition*)));
definitions[(*resultLength)++] = definition;
if ((*tokens)[0].of() == Token::TOKEN_SEMICOLON)
if ((*tokens)[0].of() == lex::Token::type::semicolon)
{
break;
}
if ((*tokens)[0].of() == Token::TOKEN_COMMA)
if ((*tokens)[0].of() == lex::Token::type::comma)
{
++(*tokens);
--(*length);
@ -207,10 +221,10 @@ namespace elna
return definitions;
}
Block *parseBlock(Token **tokens, std::size_t *length)
Block *parseBlock(lex::Token **tokens, std::size_t *length)
{
auto block = new Block();
if ((*tokens)[0].of() == Token::TOKEN_LET)
if ((*tokens)[0].of() == lex::Token::type::let)
{
size_t length_ = 0;
auto constDefinitions = parseDefinitions(tokens, length, &length_);