First solution (not working properly)

This commit is contained in:
Robert Bendun 2022-07-30 14:11:11 +02:00
parent d8f8214556
commit a5edf5ae11
3 changed files with 22 additions and 5 deletions

View File

@ -575,6 +575,9 @@ struct Parser
/// Parse infix expression
Result<Ast> parse_infix_expression();
/// Parse call expression
Result<Ast> parse_call_expression();
/// Parse right hand size of infix expression
Result<Ast> parse_rhs_of_infix_expression(Ast lhs);

View File

@ -86,7 +86,7 @@ Result<Ast> Parser::parse_expression()
if (expect(Token::Type::Keyword, "var")) {
return parse_variable_declaration();
}
return parse_infix_expression();
return parse_call_expression();
}
Result<Ast> Parser::parse_variable_declaration()
@ -119,10 +119,16 @@ Result<Ast> Parser::parse_variable_declaration()
return Ast::variable_declaration(var.location, *std::move(lvalue), std::nullopt);
}
Result<Ast> Parser::parse_call_expression()
{
auto maybe_call = Try(parse_many(*this, &Parser::parse_infix_expression, std::nullopt, At_Least::One));
return wrap_if_several(std::move(maybe_call), Ast::call);
}
Result<Ast> Parser::parse_infix_expression()
{
auto atomics = Try(parse_many(*this, &Parser::parse_index_expression, std::nullopt, At_Least::One));
auto lhs = wrap_if_several(std::move(atomics), Ast::call);
auto lhs = Try(parse_index_expression());
bool const next_is_operator = expect(Token::Type::Operator)
|| expect(Token::Type::Keyword, "and")
@ -145,8 +151,7 @@ Result<Ast> Parser::parse_infix_expression()
Result<Ast> Parser::parse_rhs_of_infix_expression(Ast lhs)
{
auto atomics = Try(parse_many(*this, &Parser::parse_index_expression, std::nullopt, At_Least::One));
auto rhs = wrap_if_several(std::move(atomics), Ast::call);
auto rhs = Try(parse_index_expression());
bool const next_is_operator = expect(Token::Type::Operator)
|| expect(Token::Type::Keyword, "and")

View File

@ -105,6 +105,15 @@ suite parser_test = [] {
Ast::literal({ Token::Type::Numeric, "2", {} })
}));
should("Prioritize binary expressions over function calls") = [] {
expect_single_ast("say 1 + 2", Ast::call({
Ast::literal({ Token::Type::Symbol, "say", {} }),
Ast::binary({ Token::Type::Operator, "+", {} },
Ast::literal({ Token::Type::Numeric, "1", {} }),
Ast::literal({ Token::Type::Numeric, "2", {} }))
}));
};
should("Support function call with complicated expression") = [] {
expect_single_ast("say (fib (n-1) + fib (n-2))", Ast::call({
Ast::literal({ Token::Type::Symbol, "say", {} }),