From fecea3b38856540d62dc8585021f7674249a1511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Mon, 2 Jan 2023 15:32:33 +0100 Subject: [PATCH] Parser - Support for calls with arbitrary expressions as the callee --- src/parser.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 7d2a8e3..a7ecaf9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -507,7 +507,7 @@ impl Parser { /// ``` /// unary := "-" unary /// unary := "!" unary - /// unary := primary + /// unary := primary call_arguments* /// ``` fn parse_unary(&mut self) -> ParserResult { if let Some(operator) = self.expect(&[TokenType::Bang, TokenType::Minus]) { @@ -516,7 +516,11 @@ impl Parser { right: Box::new(self.parse_unary()?), }) } else { - self.parse_primary() + let mut expr = self.parse_primary()?; + while self.expect(&[TokenType::LeftParen]).is_some() { + expr = self.parse_call_arguments(expr)?; + } + Ok(expr) } } @@ -543,27 +547,23 @@ impl Parser { TokenType::Number(_) | &TokenType::String(_) => Ok(ast::ExprNode::Litteral { value: self.advance().clone(), }), - TokenType::Identifier(_) => { - let identifier = self.advance().clone(); - if self.expect(&[TokenType::LeftParen]).is_some() { - self.parse_call(identifier) - } else { - Ok(ast::ExprNode::Variable { name: identifier }) - } - } + TokenType::Identifier(_) => Ok(ast::ExprNode::Variable { + name: self.advance().clone(), + }), _ => Err(ParserError::new(self.peek(), "expected expression")), } } } - /// Parse the following rules: + /// Help parsing the following rules: /// ``` - /// call := IDENTIFIER "(" arguments? ")" + /// call := expression "(" arguments? ")" /// arguments := expression ( "," expression )* /// ``` - /// The `identifier` has already been read and is provided to the method; - /// the opening parenthesis has already been skipped. - fn parse_call(&mut self, name: Token) -> Result { + fn parse_call_arguments( + &mut self, + callee: ast::ExprNode, + ) -> Result { let mut arguments = Vec::new(); if !self.check(&TokenType::RightParen) { loop { @@ -583,7 +583,7 @@ impl Parser { .consume(&TokenType::RightParen, "')' expected after arguments")? .clone(); Ok(ast::ExprNode::Call { - name, + callee: Box::new(callee), right_paren, arguments, })