From a5edf5ae11e293c4f4409f7de2ca536ecdec00c5 Mon Sep 17 00:00:00 2001 From: Robert Bendun Date: Sat, 30 Jul 2022 14:11:11 +0200 Subject: [PATCH] First solution (not working properly) --- src/musique.hh | 3 +++ src/parser.cc | 15 ++++++++++----- src/tests/parser.cc | 9 +++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/musique.hh b/src/musique.hh index 59914b7..4a34f7d 100644 --- a/src/musique.hh +++ b/src/musique.hh @@ -575,6 +575,9 @@ struct Parser /// Parse infix expression Result parse_infix_expression(); + /// Parse call expression + Result parse_call_expression(); + /// Parse right hand size of infix expression Result parse_rhs_of_infix_expression(Ast lhs); diff --git a/src/parser.cc b/src/parser.cc index 5dfe760..a66ed6f 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -86,7 +86,7 @@ Result Parser::parse_expression() if (expect(Token::Type::Keyword, "var")) { return parse_variable_declaration(); } - return parse_infix_expression(); + return parse_call_expression(); } Result Parser::parse_variable_declaration() @@ -119,10 +119,16 @@ Result Parser::parse_variable_declaration() return Ast::variable_declaration(var.location, *std::move(lvalue), std::nullopt); } + +Result 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 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 Parser::parse_infix_expression() Result 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") diff --git a/src/tests/parser.cc b/src/tests/parser.cc index c501a6c..a6dd7c5 100644 --- a/src/tests/parser.cc +++ b/src/tests/parser.cc @@ -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", {} }),