1use crate::lexer;
11use crate::token;
12
13pub(crate) mod ast;
14pub mod error;
15pub mod precedence;
16
17pub 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
25struct Parser<'a> {
27 lexer: &'a mut lexer::Lexer<'a>,
29 current_token: Option<token::Token>,
31 peek_token: Option<token::Token>,
33 errors: Vec<error::ParserError>,
35}
36
37impl<'a> Parser<'a> {
38 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 parser.next_token();
49 parser.next_token();
50 parser
51 }
52
53 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 fn current_token_is(&self, t: &token::Token) -> bool {
62 matches!(self.current_token.as_ref(), Some(current) if current == t)
63 }
64
65 fn peek_token_is(&self, t: &token::Token) -> bool {
67 matches!(self.peek_token.as_ref(), Some(peek) if peek == t)
68 }
69
70 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 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 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 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 _ => self.parse_expression_statement(),
112 }
113 }
114
115 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 self.next_token();
138
139 self.expect_peek_token(&token::Token::Assign)?;
141 self.next_token();
142
143 let expr = self.parse_expression(precedence::Precdence::Lowest)?;
145
146 if self.peek_token_is(&token::Token::Semicolon) {
148 self.next_token();
149 }
150
151 Ok(ast::Statement::Let(ident, expr))
152 }
153
154 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 self.next_token();
168
169 let expr = self.parse_expression(precedence::Precdence::Lowest)?;
171
172 if self.peek_token_is(&token::Token::Semicolon) {
174 self.next_token();
175 }
176
177 Ok(ast::Statement::Return(expr))
178 }
179
180 fn parse_expression_statement(&mut self) -> Result<ast::Statement, error::ParserError> {
182 let expr = self.parse_expression(precedence::Precdence::Lowest)?;
185
186 if self.peek_token_is(&token::Token::Semicolon) {
190 self.next_token();
191 }
192
193 Ok(ast::Statement::Expr(expr))
194 }
195
196 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 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 self.next_token();
214 }
215
216 if !self.errors.is_empty() {
218 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 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 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 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 fn parse_grouped_expression(&mut self) -> Result<ast::Expression, error::ParserError> {
259 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 fn parse_if_expression(&mut self) -> Result<ast::Expression, error::ParserError> {
272 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 let condition = self.parse_expression(precedence::Precdence::Lowest)?;
285 self.expect_peek_token(&token::Token::RParen)?;
286
287 self.expect_peek_token(&token::Token::LBrace)?;
289 let consequence = self.parse_block_statement()?;
290
291 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 fn parse_block_statement(&mut self) -> Result<ast::BlockStatement, error::ParserError> {
310 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 self.next_token();
320
321 let mut block_statement = Vec::new();
322
323 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 fn parse_function_literal(&mut self) -> Result<ast::Expression, error::ParserError> {
339 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 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 fn parse_function_parameters(&mut self) -> Result<Vec<String>, error::ParserError> {
360 let mut identifiers = Vec::new();
361
362 if self.peek_token_is(&token::Token::RParen) {
364 self.next_token();
365 return Ok(identifiers);
366 }
367
368 self.next_token();
370
371 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 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 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 fn parse_prefix_expression(&mut self) -> Result<ast::Expression, error::ParserError> {
424 let prefix = self.current_token.clone();
425
426 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 fn parse_infix_expression(
440 &mut self,
441 left: ast::Expression,
442 ) -> Result<ast::Expression, error::ParserError> {
443 let operator = self.current_token.clone();
445 let precedence = self.curr_precedence();
446 self.next_token();
447
448 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 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 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 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 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 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 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 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 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}