From febb4e9d55b9e4212ddd16e2355fd45604b4bd1b Mon Sep 17 00:00:00 2001 From: Devin Bidwell Date: Thu, 21 Nov 2024 22:23:31 -0700 Subject: [PATCH] priority expression --- src/parser/mod.rs | 45 ++++++++++++++++++++++++++++++++++++----- src/parser/tree_node.rs | 2 ++ src/tokenizer/token.rs | 7 ------- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 338d7fc..b31804c 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -164,12 +164,13 @@ impl Parser { TokenType::Symbol(Symbol::LBrace) => Expression::BlockExpression(self.block()?), // match literal expressions with a semi-colon afterwards - TokenType::Number(_) | TokenType::String(_) - if !self_matches_peek!(self, TokenType::Symbol(s) if s.is_operator() || s.is_comparison() || s.is_logical()) => - { + TokenType::Number(_) | TokenType::String(_) if !self_matches_peek!(self, TokenType::Symbol(s) if s.is_operator() || s.is_comparison() || s.is_logical()) => { Expression::Literal(self.literal()?) } + // match priority expressions with a left parenthesis + TokenType::Symbol(Symbol::LParen) => Expression::PriorityExpression(self.priority()?), + _ => { return Err(ParseError::UnexpectedToken { token: current_token.clone(), @@ -180,8 +181,25 @@ impl Parser { Ok(to_return) } - fn binary(&mut self) -> Result { - todo!() + fn priority(&mut self) -> Result, ParseError> { + let current_token = token_from_option!(self.current_token); + if !token_matches!(current_token, TokenType::Symbol(Symbol::LParen)) { + return Err(ParseError::UnexpectedToken { + token: current_token.clone(), + }); + } + + let expression = self.parse()?.ok_or(ParseError::UnexpectedEOF)?; + + // make sure the next token is a right parenthesis + let current_token = token_from_option!(self.get_next()?); + if !token_matches!(current_token, TokenType::Symbol(Symbol::RParen)) { + return Err(ParseError::UnexpectedToken { + token: current_token.clone(), + }); + } + + Ok(Box::new(expression)) } fn invocation(&mut self) -> Result { @@ -470,6 +488,23 @@ mod tests { assert_eq!("add()", expression.to_string()); + Ok(()) + } + + #[test] + fn test_priority_expression() -> Result<()> { + let input = r#" + let x = (4); + "#; + + let tokenizer = Tokenizer::from(input.to_owned()); + let mut parser = Parser::new(tokenizer); + + let expression = parser.parse()?.unwrap(); + + assert_eq!("(let x = (4))", expression.to_string()); + + Ok(()) } } diff --git a/src/parser/tree_node.rs b/src/parser/tree_node.rs index ce32fdf..2cb1626 100644 --- a/src/parser/tree_node.rs +++ b/src/parser/tree_node.rs @@ -150,6 +150,7 @@ pub enum Expression { FunctionExpression(FunctionExpression), BlockExpression(BlockExpression), InvocationExpression(InvocationExpression), + PriorityExpression(Box), } impl std::fmt::Display for Expression { @@ -165,6 +166,7 @@ impl std::fmt::Display for Expression { Expression::BlockExpression(e) => write!(f, "{}", e), Expression::InvocationExpression(e) => write!(f, "{}", e), Expression::Variable(id) => write!(f, "{}", id), + Expression::PriorityExpression(e) => write!(f, "({})", e), } } } diff --git a/src/tokenizer/token.rs b/src/tokenizer/token.rs index 5a04c91..df090ca 100644 --- a/src/tokenizer/token.rs +++ b/src/tokenizer/token.rs @@ -148,13 +148,6 @@ impl Symbol { _ => false, } } - - pub fn is_assignment(&self) -> bool { - match self { - Symbol::Assign => true, - _ => false, - } - } } #[derive(Debug, PartialEq, Hash, Eq, Clone, Copy)]