monkey_rs/
parser.rs

1/*!
2# Parser
3
4Parses the input token stream into an AST and performs syntactic analysis.
5The parsing is accomplished via "top down operator precedence," also known
6as Pratt Parsing based off Vaughan Pratt's 1973 paper ["Top Down Operator
7Precdence"](https://dl.acm.org/doi/10.1145/512927.512931).
8*/
9
10use crate::lexer;
11use crate::token;
12
13pub(crate) mod ast;
14pub mod error;
15pub mod precedence;
16
17/// Exposed function to parse a given input into a `ast::Node::Program`.
18pub fn parse(input: &str) -> Result<ast::Node, error::ParserError> {
19    let mut lexer = lexer::Lexer::new(input);
20    let mut parser = Parser::new(&mut lexer);
21    let program = parser.parse_program()?;
22    Ok(ast::Node::Program(program))
23}
24
25/// Parses the token stream into an AST.
26struct Parser<'a> {
27    /// Lexer instance to read tokens from.
28    lexer: &'a mut lexer::Lexer<'a>,
29    /// The current token.
30    current_token: Option<token::Token>,
31    /// The next token.
32    peek_token: Option<token::Token>,
33    /// Accrued parsing errors
34    errors: Vec<error::ParserError>,
35}
36
37impl<'a> Parser<'a> {
38    /// Creates a new parser instance.
39    pub fn new(lexer: &'a mut lexer::Lexer<'a>) -> Self {
40        let mut parser = Self {
41            lexer,
42            current_token: None,
43            peek_token: None,
44            errors: Vec::new(),
45        };
46
47        // Read two token to set `current` and `peek`
48        parser.next_token();
49        parser.next_token();
50        parser
51    }
52
53    /// Moves the current token to the `current` field and puts the next token
54    /// into the `peek` field.
55    fn next_token(&mut self) {
56        self.current_token = self.peek_token.take();
57        self.peek_token = Some(self.lexer.next_token());
58    }
59
60    /// Determine whether the current token matches the specific token variant.
61    fn current_token_is(&self, t: &token::Token) -> bool {
62        matches!(self.current_token.as_ref(), Some(current) if current == t)
63    }
64
65    /// Determine whether the peek token matches the specific token variant.
66    fn peek_token_is(&self, t: &token::Token) -> bool {
67        matches!(self.peek_token.as_ref(), Some(peek) if peek == t)
68    }
69
70    /// Assertion function to check if the type of the next token matches its
71    /// expected type, and only then advancing the tokens.
72    fn expect_peek_token(&mut self, t: &token::Token) -> Result<(), error::ParserError> {
73        if self.peek_token_is(t) {
74            self.next_token();
75            Ok(())
76        } else {
77            Err(error::ParserError::new(format!(
78                "Expected next token to be {:?}, received {:?}",
79                t, self.peek_token
80            )))
81        }
82    }
83
84    /// Returns the precedence of the next token `self.peek`. If the next token
85    /// does not exist, then defaults to `Precdence::Lowest`. The returned
86    /// precedence value corresponds to the left-binding power of the next
87    /// token/operator in the token stream.
88    fn peek_precedence(&self) -> precedence::Precdence {
89        match &self.peek_token {
90            Some(token) => precedence::token_precedence(token),
91            None => precedence::Precdence::Lowest,
92        }
93    }
94
95    /// Returns the precedence of the current token `self.current_token`. If the
96    /// current token does not exist, then defaults to `Precdence::Lowest`.
97    fn curr_precedence(&self) -> precedence::Precdence {
98        match &self.current_token {
99            Some(token) => precedence::token_precedence(token),
100            None => precedence::Precdence::Lowest,
101        }
102    }
103
104    /// Parses a statement, returning an AST node if successful, else a
105    /// `ParserError`.
106    fn parse_statement(&mut self) -> Result<ast::Statement, error::ParserError> {
107        match self.current_token {
108            Some(token::Token::Let) => self.parse_let_statement(),
109            Some(token::Token::Return) => self.parse_return_statement(),
110            // Otherwise, default to parsing an expression statement.
111            _ => self.parse_expression_statement(),
112        }
113    }
114
115    /// Parses a let statement, returning an AST node if successful, else a
116    /// `ParserError`.
117    fn parse_let_statement(&mut self) -> Result<ast::Statement, error::ParserError> {
118        if let Some(token) = &self.current_token {
119            if token != &token::Token::Let {
120                return Err(error::ParserError::new(format!(
121                    "Expected 'let' token, got {:?}",
122                    token
123                )));
124            }
125        }
126
127        let ident = match &self.peek_token {
128            Some(token::Token::Ident(ident)) => ident.clone(),
129            _ => {
130                return Err(error::ParserError::new(
131                    "Expected identifier after 'let'".to_string(),
132                ))
133            }
134        };
135
136        // Consume the identifier
137        self.next_token();
138
139        // Check that the next token is an assignment
140        self.expect_peek_token(&token::Token::Assign)?;
141        self.next_token();
142
143        // Parse expression
144        let expr = self.parse_expression(precedence::Precdence::Lowest)?;
145
146        // Advance parser past the optional semicolon, if it exists
147        if self.peek_token_is(&token::Token::Semicolon) {
148            self.next_token();
149        }
150
151        Ok(ast::Statement::Let(ident, expr))
152    }
153
154    /// Parses a return statement, returning an AST node if successful, else a
155    /// `ParserError`.
156    fn parse_return_statement(&mut self) -> Result<ast::Statement, error::ParserError> {
157        if let Some(token) = &self.current_token {
158            if token != &token::Token::Return {
159                return Err(error::ParserError::new(format!(
160                    "Expected 'return' token, got {:?}",
161                    token
162                )));
163            }
164        }
165
166        // Consume the `return`
167        self.next_token();
168
169        // Parse expression
170        let expr = self.parse_expression(precedence::Precdence::Lowest)?;
171
172        // Place parser after the semicolon, if it exists
173        if self.peek_token_is(&token::Token::Semicolon) {
174            self.next_token();
175        }
176
177        Ok(ast::Statement::Return(expr))
178    }
179
180    /// Parse a given expression statement.
181    fn parse_expression_statement(&mut self) -> Result<ast::Statement, error::ParserError> {
182        // Pass an initial lowest precedence since we haven't parse the rest of
183        // the expression.
184        let expr = self.parse_expression(precedence::Precdence::Lowest)?;
185
186        // Check for optional semicolon, advancing past the semicolon
187        // The semicolon is optional to allow expression statements such as
188        // `5 + 5` easier to type in the REPL
189        if self.peek_token_is(&token::Token::Semicolon) {
190            self.next_token();
191        }
192
193        Ok(ast::Statement::Expr(expr))
194    }
195
196    /// Parse the input token into a program AST (a series of statements).
197    fn parse_program(&mut self) -> Result<Vec<ast::Statement>, error::ParserError> {
198        let mut statements: Vec<ast::Statement> = Vec::new();
199
200        while let Some(current) = self.current_token.as_ref() {
201            // reached end of file
202            if *current == token::Token::Eof {
203                break;
204            }
205
206            match self.parse_statement() {
207                Ok(stmt) => statements.push(stmt),
208                Err(err) => {
209                    self.errors.push(err);
210                }
211            }
212            // Advance tokens
213            self.next_token();
214        }
215
216        // Return a parsing error if any errors were encountered.
217        if !self.errors.is_empty() {
218            // collect errors for display
219            let error_messages: Vec<String> = self.errors.iter().map(|e| e.to_string()).collect();
220            return Err(error::ParserError::new(format!(
221                "Encountered {} error(s) while parsing:\n{}",
222                self.errors.len(),
223                error_messages.join("\n")
224            )));
225        }
226
227        Ok(statements)
228    }
229
230    /// Parses the current token as an identifier expression, else returns a
231    /// parse error.
232    fn parse_identifier(&self) -> Result<ast::Expression, error::ParserError> {
233        match &self.current_token {
234            Some(token::Token::Ident(ident)) => Ok(ast::Expression::Identifier(ident.to_string())),
235            _ => Err(error::ParserError::new("Expected identifier".to_string())),
236        }
237    }
238
239    /// Attempts to parse the current token as an integer literal expression.
240    fn parse_integer_literal(&self) -> Result<ast::Expression, error::ParserError> {
241        match &self.current_token {
242            Some(token::Token::Int(int)) => Ok(ast::Expression::Lit(ast::Literal::Integer(*int))),
243            _ => Err(error::ParserError::new("Expected integer".to_string())),
244        }
245    }
246
247    /// Attempts to parse the current token as a Boolean literal expression.
248    fn parse_boolean(&self) -> Result<ast::Expression, error::ParserError> {
249        match &self.current_token {
250            Some(token::Token::True) => Ok(ast::Expression::Lit(ast::Literal::Boolean(true))),
251            Some(token::Token::False) => Ok(ast::Expression::Lit(ast::Literal::Boolean(false))),
252            _ => Err(error::ParserError::new("Expected boolean".to_string())),
253        }
254    }
255
256    /// Attempts to parse a group expression, starting from the opening
257    /// `token::Token::LParen` token.
258    fn parse_grouped_expression(&mut self) -> Result<ast::Expression, error::ParserError> {
259        // Advance past the opening left parenthesis
260        self.next_token();
261
262        let expr = self.parse_expression(precedence::Precdence::Lowest)?;
263        self.expect_peek_token(&token::Token::RParen)?;
264
265        Ok(expr)
266    }
267
268    /// Parses the if-else expression from the current token, returning an
269    /// `ast::Expression::If(...)` node of the condition, consequence, and
270    /// optional alternative expressions and block statements, respectively.
271    fn parse_if_expression(&mut self) -> Result<ast::Expression, error::ParserError> {
272        // Ensure the current token is `If`
273        if !self.current_token_is(&token::Token::If) {
274            return Err(error::ParserError::new(format!(
275                "Expected 'if' token, got {:?}",
276                self.current_token
277            )));
278        }
279
280        self.expect_peek_token(&token::Token::LParen)?;
281        self.next_token();
282
283        // Parse condition expression
284        let condition = self.parse_expression(precedence::Precdence::Lowest)?;
285        self.expect_peek_token(&token::Token::RParen)?;
286
287        // Parse consequence expression
288        self.expect_peek_token(&token::Token::LBrace)?;
289        let consequence = self.parse_block_statement()?;
290
291        // Parse alternative expression, if it exists
292        let alternative = if self.peek_token_is(&token::Token::Else) {
293            self.next_token();
294            self.expect_peek_token(&token::Token::LBrace)?;
295            Some(self.parse_block_statement()?)
296        } else {
297            None
298        };
299
300        Ok(ast::Expression::If(
301            Box::new(condition),
302            consequence,
303            alternative,
304        ))
305    }
306
307    /// Parses the block statement from the current token, which should be on
308    /// the opening curly left brace.
309    fn parse_block_statement(&mut self) -> Result<ast::BlockStatement, error::ParserError> {
310        // Ensure the current token is `LBrace`
311        if !self.current_token_is(&token::Token::LBrace) {
312            return Err(error::ParserError::new(format!(
313                "Expected '{{' token, got {:?}",
314                self.current_token
315            )));
316        }
317
318        // Advance past the opening curly brace
319        self.next_token();
320
321        let mut block_statement = Vec::new();
322
323        // Continue to parse statement until we either reach the end of the
324        // block statement or EOF.
325        while !self.current_token_is(&token::Token::RBrace)
326            && !self.current_token_is(&token::Token::Eof)
327        {
328            if let Ok(stmt) = self.parse_statement() {
329                block_statement.push(stmt);
330            }
331            self.next_token();
332        }
333
334        Ok(block_statement)
335    }
336
337    /// Parses the function literal from the current token.
338    fn parse_function_literal(&mut self) -> Result<ast::Expression, error::ParserError> {
339        // Ensure the current token is `Function`
340        if !self.current_token_is(&token::Token::Function) {
341            return Err(error::ParserError::new(format!(
342                "Expected 'fn' token, got {:?}",
343                self.current_token
344            )));
345        }
346
347        self.expect_peek_token(&token::Token::LParen)?;
348
349        // Parse the parameters of the function
350        let parameters = self.parse_function_parameters()?;
351
352        self.expect_peek_token(&token::Token::LBrace)?;
353
354        let body = self.parse_block_statement()?;
355        Ok(ast::Expression::Fn(parameters, body))
356    }
357
358    /// Parses the parameters of a function literal expression.
359    fn parse_function_parameters(&mut self) -> Result<Vec<String>, error::ParserError> {
360        let mut identifiers = Vec::new();
361
362        // Early exit in the case of no parameters/ empty list
363        if self.peek_token_is(&token::Token::RParen) {
364            self.next_token();
365            return Ok(identifiers);
366        }
367
368        // Advance past the opening left parenthesis
369        self.next_token();
370
371        // Add the current identifier
372        match &self.current_token {
373            Some(token::Token::Ident(ref param)) => identifiers.push(param.clone()),
374            Some(token) => {
375                return Err(error::ParserError::new(format!(
376                    "Expected a parameter identifer, got {}",
377                    token
378                )))
379            }
380            None => {
381                return Err(error::ParserError::new(
382                    "Expected a parameter identifer, received None".to_string(),
383                ))
384            }
385        }
386
387        // Add parameter identifier(s) following the first parameter, if they
388        // exist
389        while self.peek_token_is(&token::Token::Comma) {
390            self.next_token();
391            self.next_token();
392            match &self.current_token {
393                Some(token::Token::Ident(ref param)) => identifiers.push(param.clone()),
394                Some(token) => {
395                    return Err(error::ParserError::new(format!(
396                        "Expected a parameter identifer, got {}",
397                        token
398                    )))
399                }
400                None => {
401                    return Err(error::ParserError::new(
402                        "Expected a parameter identifer, received None".to_string(),
403                    ))
404                }
405            }
406        }
407
408        self.expect_peek_token(&token::Token::RParen)?;
409
410        Ok(identifiers)
411    }
412
413    /// Parse the function call expression from the current token.
414    fn parse_call_expression(
415        &mut self,
416        expr: ast::Expression,
417    ) -> Result<ast::Expression, error::ParserError> {
418        let args = self.parse_expression_list(&token::Token::RParen)?;
419        Ok(ast::Expression::Call(Box::new(expr), args))
420    }
421
422    /// Attempts to parse the current token as a prefix expression.
423    fn parse_prefix_expression(&mut self) -> Result<ast::Expression, error::ParserError> {
424        let prefix = self.current_token.clone();
425
426        // advance the parser
427        self.next_token();
428
429        let expr = self.parse_expression(precedence::Precdence::Prefix)?;
430
431        Ok(ast::Expression::Prefix(
432            prefix.expect("Expected a prefix token"),
433            Box::new(expr),
434        ))
435    }
436
437    /// Attempts to parse an infix expression, given the left-hand side to the
438    /// infix expression.
439    fn parse_infix_expression(
440        &mut self,
441        left: ast::Expression,
442    ) -> Result<ast::Expression, error::ParserError> {
443        // Handle the infix operator
444        let operator = self.current_token.clone();
445        let precedence = self.curr_precedence();
446        self.next_token();
447
448        // Parse the right expression
449        let right = self.parse_expression(precedence)?;
450
451        Ok(ast::Expression::Infix(
452            operator.expect("Expected infix operator"),
453            Box::new(left),
454            Box::new(right),
455        ))
456    }
457
458    /// Parses the current expression based on precedence rules. The passed
459    /// value for `precedence` signifies the current right-binding power of the
460    /// invocation.
461    fn parse_expression(
462        &mut self,
463        precedence: precedence::Precdence,
464    ) -> Result<ast::Expression, error::ParserError> {
465        let mut left_expr = match self.current_token {
466            Some(token::Token::True) | Some(token::Token::False) => self.parse_boolean(),
467            Some(token::Token::Ident(_)) => self.parse_identifier(),
468            Some(token::Token::Int(_)) => self.parse_integer_literal(),
469            Some(token::Token::Bang) | Some(token::Token::Minus) => self.parse_prefix_expression(),
470            Some(token::Token::LParen) => self.parse_grouped_expression(),
471            Some(token::Token::If) => self.parse_if_expression(),
472            Some(token::Token::Function) => self.parse_function_literal(),
473            Some(token::Token::String(_)) => self.parse_string_literal(),
474            Some(token::Token::LBracket) => self.parse_array_literal(),
475            Some(token::Token::LBrace) => self.parse_hash_literal(),
476            _ => Err(error::ParserError::new(format!(
477                "No prefix parse function for {:?}",
478                self.current_token
479            ))),
480        };
481
482        // Try to parse the infix expression, if it exists. Checks if the
483        // left-binding power of the next operator/token is higher than the
484        // current right-binding power.
485        //
486        // NOTE: The check for the peek token being a semicolon is not strictly
487        // necessary since the `peek_precedence` method will default to
488        // returning `Precdence::Lowest`. However, this explicitly sets the
489        // semantic behavior of semicolons and expression-ending delimiters.
490        while !self.peek_token_is(&token::Token::Semicolon) && precedence < self.peek_precedence() {
491            match self.peek_token {
492                Some(token::Token::Plus)
493                | Some(token::Token::Minus)
494                | Some(token::Token::Slash)
495                | Some(token::Token::Asterisk)
496                | Some(token::Token::Eq)
497                | Some(token::Token::NotEq)
498                | Some(token::Token::Lt)
499                | Some(token::Token::Gt) => {
500                    self.next_token();
501                    match left_expr {
502                        Ok(left) => left_expr = self.parse_infix_expression(left),
503                        Err(e) => return Err(e),
504                    }
505                }
506                Some(token::Token::LParen) => {
507                    self.next_token();
508                    match left_expr {
509                        Ok(expr) => left_expr = self.parse_call_expression(expr),
510                        Err(e) => return Err(e),
511                    };
512                }
513                Some(token::Token::LBracket) => {
514                    self.next_token();
515                    let expr = left_expr?;
516                    left_expr = self.parse_index_expresssion(expr);
517                }
518                Some(_) => {
519                    return Err(error::ParserError::new(format!(
520                        "No infix parse function for {:?}",
521                        &self.peek_token
522                    )))
523                }
524                None => return left_expr,
525            }
526        }
527
528        left_expr
529    }
530
531    /// Parse the string literal from the current token.
532    fn parse_string_literal(&self) -> Result<ast::Expression, error::ParserError> {
533        match &self.current_token {
534            Some(ref str) => Ok(ast::Expression::Lit(ast::Literal::String(str.to_string()))),
535            None => Err(error::ParserError::new(
536                "expected string literal".to_string(),
537            )),
538        }
539    }
540
541    /// Parse the array literal from the current token.
542    fn parse_array_literal(&mut self) -> Result<ast::Expression, error::ParserError> {
543        let array = self.parse_expression_list(&token::Token::RBracket)?;
544        Ok(ast::Expression::Lit(ast::Literal::Array(array)))
545    }
546
547    /// Parse a comma-separated list of expressions until the ending token is
548    /// the next token.
549    fn parse_expression_list(
550        &mut self,
551        end: &token::Token,
552    ) -> Result<Vec<ast::Expression>, error::ParserError> {
553        let mut list = Vec::new();
554
555        if self.peek_token_is(end) {
556            self.next_token();
557            return Ok(list);
558        }
559
560        self.next_token();
561        list.push(self.parse_expression(precedence::Precdence::Lowest)?);
562
563        while self.peek_token_is(&token::Token::Comma) {
564            self.next_token();
565            self.next_token();
566            list.push(self.parse_expression(precedence::Precdence::Lowest)?);
567        }
568
569        self.expect_peek_token(end)?;
570
571        Ok(list)
572    }
573
574    /// Parse the index expression from the current token.
575    fn parse_index_expresssion(
576        &mut self,
577        left_expr: ast::Expression,
578    ) -> Result<ast::Expression, error::ParserError> {
579        self.next_token();
580
581        let index_expr = self.parse_expression(precedence::Precdence::Lowest)?;
582
583        self.expect_peek_token(&token::Token::RBracket)?;
584
585        Ok(ast::Expression::Index(
586            Box::new(left_expr),
587            Box::new(index_expr),
588        ))
589    }
590
591    /// Parse the hash literal expression from the current token.
592    fn parse_hash_literal(&mut self) -> Result<ast::Expression, error::ParserError> {
593        let mut hash = Vec::new();
594        while !self.peek_token_is(&token::Token::RBrace) {
595            self.next_token();
596
597            let key = self.parse_expression(precedence::Precdence::Lowest)?;
598
599            self.expect_peek_token(&token::Token::Colon)?;
600            self.next_token();
601
602            let value = self.parse_expression(precedence::Precdence::Lowest)?;
603
604            hash.push((key, value));
605
606            if !self.peek_token_is(&token::Token::RBrace) {
607                self.expect_peek_token(&token::Token::Comma)?;
608            }
609        }
610
611        self.expect_peek_token(&token::Token::RBrace)?;
612
613        Ok(ast::Expression::Lit(ast::Literal::Hash(hash)))
614    }
615}
616
617#[cfg(test)]
618mod tests {
619    use super::*;
620
621    /// Checks the output of parsing an input program string against the
622    /// expected serialized display output for the parsed program AST.
623    fn check_parse_test_cases(cases: &[(&str, &str)]) {
624        for (input, expected) in cases {
625            let mut l = lexer::Lexer::new(input);
626            let mut p = Parser::new(&mut l);
627            match p.parse_program() {
628                Ok(stmts) => {
629                    let program = ast::Node::Program(stmts);
630                    assert_eq!(expected, &format!("{}", program))
631                }
632                Err(e) => panic!("Parsing error: {}", e),
633            }
634        }
635    }
636
637    #[test]
638    fn test_let_statement() {
639        let input = "let x = 5; \
640                                   let y = 10; \
641                                   let foobar = 838383;";
642
643        let mut l = lexer::Lexer::new(input);
644        let mut p = Parser::new(&mut l);
645        let program = p.parse_program();
646        assert!(program.is_ok());
647        let program = program.unwrap();
648        if program.len() != 3 {
649            panic!(
650                "program does not contain 3 statements. got={}",
651                program.len()
652            );
653        }
654
655        let expected = vec![
656            ast::Statement::Let(
657                "x".to_string(),
658                ast::Expression::Lit(ast::Literal::Integer(5)),
659            ),
660            ast::Statement::Let(
661                "y".to_string(),
662                ast::Expression::Lit(ast::Literal::Integer(10)),
663            ),
664            ast::Statement::Let(
665                "foobar".to_string(),
666                ast::Expression::Lit(ast::Literal::Integer(838383)),
667            ),
668        ];
669        assert_eq!(expected, program)
670    }
671
672    #[test]
673    fn test_invalid_let_statement() {
674        let input = "let x 5;";
675        let mut l = lexer::Lexer::new(input);
676        let mut p = Parser::new(&mut l);
677        let program = p.parse_program();
678        assert!(&program.is_err());
679    }
680
681    #[test]
682    fn test_return_statements() {
683        let input = "return 5; \
684                     return 10; \
685                     return 993322;";
686        let mut l = lexer::Lexer::new(input);
687        let mut p = Parser::new(&mut l);
688        let program = p.parse_program();
689        assert!(program.is_ok());
690        let program = program.unwrap();
691        if program.len() != 3 {
692            panic!(
693                "program does not contain 3 statements. got={}",
694                program.len()
695            );
696        }
697        let expected = vec![
698            ast::Statement::Return(ast::Expression::Lit(ast::Literal::Integer(5))),
699            ast::Statement::Return(ast::Expression::Lit(ast::Literal::Integer(10))),
700            ast::Statement::Return(ast::Expression::Lit(ast::Literal::Integer(993322))),
701        ];
702        assert_eq!(expected, program)
703    }
704
705    #[test]
706    fn test_simple_program_display() {
707        let input = "let myVar = anotherVar;";
708        let mut l = lexer::Lexer::new(input);
709        let mut p = Parser::new(&mut l);
710        let program = p.parse_program();
711        assert!(program.is_ok());
712        let program = ast::Node::Program(program.unwrap());
713        let expected = ast::Node::Program(vec![ast::Statement::Let(
714            "myVar".to_string(),
715            ast::Expression::Identifier("anotherVar".to_string()),
716        )]);
717        assert_eq!(expected, program);
718    }
719
720    #[test]
721    fn test_identifier_expression() {
722        let input = "foobar;";
723        let mut l = lexer::Lexer::new(input);
724        let mut p = Parser::new(&mut l);
725        let program = p.parse_program().unwrap();
726        assert_eq!(program.len(), 1);
727        let expected = vec![ast::Statement::Expr(ast::Expression::Identifier(
728            "foobar".to_string(),
729        ))];
730        assert_eq!(expected, program);
731    }
732
733    #[test]
734    fn test_integer_literal_expression() {
735        let input = "5;";
736        let mut l = lexer::Lexer::new(input);
737        let mut p = Parser::new(&mut l);
738        let program = p.parse_program().unwrap();
739        assert_eq!(program.len(), 1);
740        let expected = vec![ast::Statement::Expr(ast::Expression::Lit(
741            ast::Literal::Integer(5),
742        ))];
743        assert_eq!(expected, program);
744    }
745
746    #[test]
747    fn test_boolean_expressions() {
748        let bool_tests = [("true", "true"), ("false", "false")];
749        check_parse_test_cases(&bool_tests);
750    }
751
752    #[test]
753    fn test_parsing_prefix_expressions() {
754        let prefix_cases = [
755            ("!5;", "(!5)"),
756            ("-15;", "(-15)"),
757            ("!true", "(!true)"),
758            ("!false", "(!false)"),
759        ];
760        check_parse_test_cases(&prefix_cases);
761    }
762
763    #[test]
764    fn test_parsing_infix_expressions() {
765        let infix_tests = [
766            ("5 + 5;", "(5 + 5)"),
767            ("5 - 5;", "(5 - 5)"),
768            ("5 * 5;", "(5 * 5)"),
769            ("5 / 5;", "(5 / 5)"),
770            ("5 > 5;", "(5 > 5)"),
771            ("5 < 5;", "(5 < 5)"),
772            ("5 == 5;", "(5 == 5)"),
773            ("5 != 5;", "(5 != 5)"),
774            ("true == true", "(true == true)"),
775            ("true != false", "(true != false)"),
776            ("false == false", "(false == false)"),
777        ];
778        check_parse_test_cases(&infix_tests);
779    }
780
781    #[test]
782    fn test_operator_precedence_parsing() {
783        let precedence_tests = [
784            ("-a * b", "((-a) * b)"),
785            ("!-a", "(!(-a))"),
786            ("a + b + c", "((a + b) + c)"),
787            ("a + b - c", "((a + b) - c)"),
788            ("a * b * c", "((a * b) * c)"),
789            ("a * b / c", "((a * b) / c)"),
790            ("a + b / c", "(a + (b / c))"),
791            ("a + b * c + d / e - f", "(((a + (b * c)) + (d / e)) - f)"),
792            ("3 + 4; -5 * 5", "(3 + 4)((-5) * 5)"),
793            ("5 > 4 == 3 < 4", "((5 > 4) == (3 < 4))"),
794            ("5 < 4 != 3 > 4", "((5 < 4) != (3 > 4))"),
795            (
796                "3 + 4 * 5 == 3 * 1 + 4 * 5",
797                "((3 + (4 * 5)) == ((3 * 1) + (4 * 5)))",
798            ),
799            ("true", "true"),
800            ("false", "false"),
801            ("3 > 5 == false", "((3 > 5) == false)"),
802            ("3 < 5 == true", "((3 < 5) == true)"),
803            ("1 + (2 + 3) + 4", "((1 + (2 + 3)) + 4)"),
804            ("(5 + 5) * 2", "((5 + 5) * 2)"),
805            ("2 / (5 + 5)", "(2 / (5 + 5))"),
806            ("-(5 + 5)", "(-(5 + 5))"),
807            ("!(true == true)", "(!(true == true))"),
808            ("a + add(b * c) + d", "((a + add((b * c))) + d)"),
809            (
810                "add(a, b, 1, 2 * 3, 4 + 5, add(6, 7 * 8))",
811                "add(a, b, 1, (2 * 3), (4 + 5), add(6, (7 * 8)))",
812            ),
813            (
814                "add(a + b + c * d / f + g)",
815                "add((((a + b) + ((c * d) / f)) + g))",
816            ),
817            (
818                "a * [1, 2, 3, 4][b * c] * d",
819                "((a * ([1, 2, 3, 4][(b * c)])) * d)",
820            ),
821            (
822                "add(a * b[2], b[1], 2 * [1, 2][1])",
823                "add((a * (b[2])), (b[1]), (2 * ([1, 2][1])))",
824            ),
825        ];
826        check_parse_test_cases(&precedence_tests);
827    }
828
829    #[test]
830    fn test_if_expression() {
831        let if_case = [("if (x < y) { x }", "if (x < y) { x }")];
832        check_parse_test_cases(&if_case);
833    }
834
835    #[test]
836    fn test_ifelse_expression() {
837        let ifelse_case = [("if (x < y) { x } else { y }", "if (x < y) { x } else { y }")];
838        check_parse_test_cases(&ifelse_case);
839    }
840
841    #[test]
842    fn test_if_else_function_literal() {
843        let cases = [
844            (
845                "let myFunc = fn() { if (1 > 2) { 10 } else { 20 } };",
846                "let myFunc = fn() { if (1 > 2) { 10 } else { 20 } };",
847            ),
848            (
849                "fn() { if (1 > 2) { 10 } else { 20 } }",
850                "fn() { if (1 > 2) { 10 } else { 20 } }",
851            ),
852            (
853                "let factorial = fn(n) { if (n == 1) { 0 } else { n * factorial(n - 1) } };",
854                "let factorial = fn(n) { if (n == 1) { 0 } else { (n * factorial((n - 1))) } };",
855            ),
856        ];
857        check_parse_test_cases(&cases);
858    }
859
860    #[test]
861    fn test_function_parameter_parsing() {
862        let fn_params_cases = [
863            ("fn() {};", "fn() {  }"),
864            ("fn(x) {};", "fn(x) {  }"),
865            ("fn(x, y, z) {};", "fn(x, y, z) {  }"),
866        ];
867        check_parse_test_cases(&fn_params_cases);
868    }
869
870    #[test]
871    fn test_call_expression_parsing() {
872        let fn_call_cases = [("add(1, 2 * 3, 4 + 5)", "add(1, (2 * 3), (4 + 5))")];
873        check_parse_test_cases(&fn_call_cases);
874    }
875
876    #[test]
877    fn test_string_literal_expression() {
878        let str_lit_cases = [("\"hello world\";", "\"hello world\"")];
879        check_parse_test_cases(&str_lit_cases);
880    }
881
882    #[test]
883    fn test_parsing_array_literals() {
884        let case = [("[1, 2 * 2, 3 + 3]", "[1, (2 * 2), (3 + 3)]")];
885        check_parse_test_cases(&case);
886    }
887
888    #[test]
889    fn test_parsing_index_expressions() {
890        let case = [("myArray[1 + 1]", "(myArray[(1 + 1)])")];
891        check_parse_test_cases(&case);
892    }
893
894    #[test]
895    fn test_parsing_hash_literals_string_keys() {
896        let case = [(
897            r#"{"one": 1, "two": 2, "three": 3}"#,
898            r#"{"one": 1, "two": 2, "three": 3}"#,
899        )];
900        check_parse_test_cases(&case);
901    }
902
903    #[test]
904    fn test_parsing_empty_hash_literal() {
905        let case = [(r#"{}"#, r#"{}"#)];
906        check_parse_test_cases(&case);
907    }
908
909    #[test]
910    fn test_parsing_hash_literal_boolean_keys() {
911        let case = [(r#"{true: 1, false: 2}"#, r#"{true: 1, false: 2}"#)];
912        check_parse_test_cases(&case);
913    }
914
915    #[test]
916    fn test_parsing_hash_literal_integer_keys() {
917        let case = [(r#"{1: 1, 2: 2, 3: 3}"#, r#"{1: 1, 2: 2, 3: 3}"#)];
918        check_parse_test_cases(&case);
919    }
920
921    #[test]
922    fn test_parsing_hash_literals_with_expressions() {
923        let case = [(
924            r#"{"one": 0 + 1, "two": 10 - 8, "three": 15 / 5}"#,
925            r#"{"one": (0 + 1), "two": (10 - 8), "three": (15 / 5)}"#,
926        )];
927        check_parse_test_cases(&case);
928    }
929}