Parse reference and dereference operators
This commit is contained in:
@ -78,6 +78,11 @@ namespace elna::source
|
||||
expression->rhs().accept(this);
|
||||
}
|
||||
|
||||
void empty_visitor::visit(unary_expression *expression)
|
||||
{
|
||||
expression->operand().accept(this);
|
||||
}
|
||||
|
||||
void empty_visitor::visit(type_expression *variable)
|
||||
{
|
||||
}
|
||||
@ -343,6 +348,33 @@ namespace elna::source
|
||||
return m_operator;
|
||||
}
|
||||
|
||||
unary_expression::unary_expression(const struct position position, std::unique_ptr<expression>&& operand,
|
||||
const unsigned char operation)
|
||||
: expression(position), m_operand(std::move(operand))
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case '@':
|
||||
this->m_operator = unary_operator::reference;
|
||||
break;
|
||||
case '^':
|
||||
this->m_operator = unary_operator::dereference;
|
||||
break;
|
||||
default:
|
||||
throw std::logic_error("Invalid unary operator");
|
||||
}
|
||||
}
|
||||
|
||||
void unary_expression::accept(parser_visitor *visitor)
|
||||
{
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
expression& unary_expression::operand()
|
||||
{
|
||||
return *m_operand;
|
||||
}
|
||||
|
||||
call_statement::call_statement(const struct position position, const std::string& name)
|
||||
: statement(position), m_name(name)
|
||||
{
|
||||
@ -477,33 +509,63 @@ namespace elna::source
|
||||
return iterator.errors();
|
||||
}
|
||||
|
||||
std::unique_ptr<expression> parser::parse_unary_expression()
|
||||
{
|
||||
std::unique_ptr<expression> result;
|
||||
|
||||
if (iterator.current(token::type::at))
|
||||
{
|
||||
std::unique_ptr<expression> body_expression;
|
||||
|
||||
++iterator;
|
||||
if ((body_expression = parse_factor()) == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
result = std::make_unique<unary_expression>(iterator->position(), std::move(body_expression), '@');
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((result = parse_factor()) == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if (iterator.current(token::type::hat))
|
||||
{
|
||||
++iterator;
|
||||
result = std::make_unique<unary_expression>(iterator->position(), std::move(result), '^');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<expression> parser::parse_factor()
|
||||
{
|
||||
if (iterator->of() == source::token::type::identifier)
|
||||
if (iterator->of() == token::type::identifier)
|
||||
{
|
||||
auto result = std::make_unique<variable_expression>(iterator->position(), iterator->identifier());
|
||||
++iterator;
|
||||
return result;
|
||||
}
|
||||
else if (iterator->of() == source::token::token::type::number)
|
||||
else if (iterator->of() == token::token::type::number)
|
||||
{
|
||||
auto result = std::make_unique<integer_literal>(iterator->position(), iterator->number());
|
||||
++iterator;
|
||||
return result;
|
||||
}
|
||||
else if (iterator->of() == source::token::token::type::boolean)
|
||||
else if (iterator->of() == token::token::type::boolean)
|
||||
{
|
||||
auto result = std::make_unique<boolean_literal>(iterator->position(), iterator->number());
|
||||
++iterator;
|
||||
return result;
|
||||
}
|
||||
else if (iterator->of() == source::token::type::left_paren)
|
||||
else if (iterator->of() == token::type::left_paren)
|
||||
{
|
||||
++iterator;
|
||||
|
||||
auto expression = parse_condition();
|
||||
|
||||
++iterator;
|
||||
iterator.advance(token::type::right_paren);
|
||||
|
||||
return expression;
|
||||
}
|
||||
@ -512,7 +574,7 @@ namespace elna::source
|
||||
|
||||
std::unique_ptr<expression> parser::parse_term()
|
||||
{
|
||||
auto lhs = parse_factor();
|
||||
auto lhs = parse_unary_expression();
|
||||
if (lhs == nullptr || iterator.current().of() != source::token::type::factor_operator)
|
||||
{
|
||||
return lhs;
|
||||
@ -523,7 +585,7 @@ namespace elna::source
|
||||
const auto operator_position = iterator->position();
|
||||
++iterator;
|
||||
|
||||
auto rhs = parse_factor();
|
||||
auto rhs = parse_unary_expression();
|
||||
lhs = std::make_unique<binary_expression>(operator_position, std::move(lhs),
|
||||
std::move(rhs), _operator);
|
||||
}
|
||||
|
Reference in New Issue
Block a user