1use crate::ast::{BinaryOp, Block, ElseClause, Expression, Program, Statement, UnaryOp};
9use crate::error::ParseError;
10use crate::lexer::{Token, TokenKind};
11
12pub struct Parser {
14 tokens: Vec<Token>,
16 current: usize,
18}
19
20impl Parser {
21 pub fn new(tokens: Vec<Token>) -> Self {
23 Self { tokens, current: 0 }
24 }
25
26 pub fn parse(&mut self) -> Result<Program, ParseError> {
28 let mut statements = Vec::new();
29
30 while !self.is_at_end() {
31 statements.push(self.parse_statement()?);
32 }
33
34 Ok(Program::new(statements))
35 }
36
37 fn is_at_end(&self) -> bool {
41 self.peek().kind == TokenKind::Eof
42 }
43
44 fn peek(&self) -> &Token {
46 self.tokens.get(self.current).unwrap_or_else(|| {
47 self.tokens
48 .last()
49 .expect("Token stream should have at least EOF")
50 })
51 }
52
53 fn previous(&self) -> &Token {
55 &self.tokens[self.current.saturating_sub(1)]
56 }
57
58 fn advance(&mut self) -> &Token {
60 if !self.is_at_end() {
61 self.current += 1;
62 }
63 self.previous()
64 }
65
66 fn check(&self, kind: &TokenKind) -> bool {
68 if self.is_at_end() {
69 return false;
70 }
71 std::mem::discriminant(&self.peek().kind) == std::mem::discriminant(kind)
72 }
73
74 fn match_token(&mut self, kind: &TokenKind) -> bool {
76 if self.check(kind) {
77 self.advance();
78 true
79 } else {
80 false
81 }
82 }
83
84 fn expect(&mut self, kind: &TokenKind, expected: &str) -> Result<&Token, ParseError> {
86 if self.check(kind) {
87 Ok(self.advance())
88 } else {
89 Err(ParseError::UnexpectedToken(
90 self.peek().kind.to_string(),
91 self.peek().position,
92 expected.to_string(),
93 ))
94 }
95 }
96
97 fn parse_statement(&mut self) -> Result<Statement, ParseError> {
101 match &self.peek().kind {
102 TokenKind::Let => self.parse_let_statement(),
103 TokenKind::If => self.parse_if_statement(),
104 TokenKind::For => self.parse_for_statement(),
105 TokenKind::Return => self.parse_return_statement(),
106 TokenKind::Fn => self.parse_function_definition(),
107 TokenKind::LeftBrace => {
108 if self.is_dictionary_literal() {
110 self.parse_expression_statement()
111 } else {
112 let block = self.parse_block()?;
113 Ok(Statement::Block(block))
114 }
115 }
116 _ => self.parse_expression_statement(),
117 }
118 }
119
120 fn parse_let_statement(&mut self) -> Result<Statement, ParseError> {
122 let position = self.peek().position;
123 self.advance(); let name = match &self.peek().kind {
126 TokenKind::Identifier(name) => name.clone(),
127 _ => return Err(ParseError::ExpectedIdentifier(self.peek().position)),
128 };
129 self.advance();
130
131 self.expect(&TokenKind::Assign, "=")?;
132 let value = self.parse_expression()?;
133 self.expect(&TokenKind::Semicolon, ";")?;
134
135 Ok(Statement::Let {
136 name,
137 value,
138 position,
139 })
140 }
141
142 fn parse_if_statement(&mut self) -> Result<Statement, ParseError> {
144 let position = self.peek().position;
145 self.advance(); self.expect(&TokenKind::LeftParen, "(")?;
148 let condition = self.parse_expression()?;
149 self.expect(&TokenKind::RightParen, ")")?;
150
151 let then_block = self.parse_block()?;
152
153 let else_block = if self.match_token(&TokenKind::Else) {
154 if self.check(&TokenKind::If) {
155 Some(ElseClause::ElseIf(Box::new(self.parse_if_statement()?)))
157 } else {
158 Some(ElseClause::Block(self.parse_block()?))
160 }
161 } else {
162 None
163 };
164
165 Ok(Statement::If {
166 condition,
167 then_block,
168 else_block,
169 position,
170 })
171 }
172
173 fn parse_for_statement(&mut self) -> Result<Statement, ParseError> {
175 let position = self.peek().position;
176 self.advance(); self.expect(&TokenKind::LeftParen, "(")?;
179
180 let init = if self.match_token(&TokenKind::Semicolon) {
182 None
183 } else if self.check(&TokenKind::Let) {
184 Some(Box::new(self.parse_let_statement()?))
185 } else {
186 let expr = self.parse_expression()?;
187 let pos = expr.position();
188 self.expect(&TokenKind::Semicolon, ";")?;
189 Some(Box::new(Statement::Expression {
190 expression: expr,
191 position: pos,
192 }))
193 };
194
195 let condition = if self.check(&TokenKind::Semicolon) {
197 None
198 } else {
199 Some(self.parse_expression()?)
200 };
201 self.expect(&TokenKind::Semicolon, ";")?;
202
203 let update = if self.check(&TokenKind::RightParen) {
205 None
206 } else {
207 Some(self.parse_expression()?)
208 };
209 self.expect(&TokenKind::RightParen, ")")?;
210
211 let body = self.parse_block()?;
212
213 Ok(Statement::For {
214 init,
215 condition,
216 update,
217 body,
218 position,
219 })
220 }
221
222 fn parse_return_statement(&mut self) -> Result<Statement, ParseError> {
224 let position = self.peek().position;
225 self.advance(); let value = if self.check(&TokenKind::Semicolon) {
228 None
229 } else {
230 Some(self.parse_expression()?)
231 };
232
233 self.expect(&TokenKind::Semicolon, ";")?;
234
235 Ok(Statement::Return { value, position })
236 }
237
238 fn parse_function_definition(&mut self) -> Result<Statement, ParseError> {
240 let position = self.peek().position;
241 self.advance(); let name = match &self.peek().kind {
244 TokenKind::Identifier(name) => name.clone(),
245 _ => return Err(ParseError::ExpectedIdentifier(self.peek().position)),
246 };
247 self.advance();
248
249 self.expect(&TokenKind::LeftParen, "(")?;
250 let params = self.parse_parameters()?;
251 self.expect(&TokenKind::RightParen, ")")?;
252
253 let body = self.parse_block()?;
254
255 Ok(Statement::Function {
256 name,
257 params,
258 body,
259 position,
260 })
261 }
262
263 fn parse_parameters(&mut self) -> Result<Vec<String>, ParseError> {
265 let mut params = Vec::new();
266
267 if !self.check(&TokenKind::RightParen) {
268 loop {
269 let pos = self.peek().position;
270 let name = match &self.peek().kind {
271 TokenKind::Identifier(name) => name.clone(),
272 _ => return Err(ParseError::ExpectedIdentifier(self.peek().position)),
273 };
274 self.advance();
275
276 if params.contains(&name) {
278 return Err(ParseError::UnexpectedToken(
279 name,
280 pos,
281 "unique parameter name (duplicate parameter)".to_string(),
282 ));
283 }
284
285 params.push(name);
286
287 if !self.match_token(&TokenKind::Comma) {
288 break;
289 }
290 }
291 }
292
293 Ok(params)
294 }
295
296 fn parse_expression_statement(&mut self) -> Result<Statement, ParseError> {
298 let expression = self.parse_expression()?;
299 let position = expression.position();
300 self.expect(&TokenKind::Semicolon, ";")?;
301 Ok(Statement::Expression {
302 expression,
303 position,
304 })
305 }
306
307 fn parse_block(&mut self) -> Result<Block, ParseError> {
309 let position = self.peek().position;
310 self.expect(&TokenKind::LeftBrace, "{")?;
311
312 let mut statements = Vec::new();
313 while !self.check(&TokenKind::RightBrace) && !self.is_at_end() {
314 statements.push(self.parse_statement()?);
315 }
316
317 self.expect(&TokenKind::RightBrace, "}")?;
318 Ok(Block::new(statements, position))
319 }
320
321 pub fn parse_expression(&mut self) -> Result<Expression, ParseError> {
325 self.parse_assignment()
326 }
327
328 fn parse_assignment(&mut self) -> Result<Expression, ParseError> {
330 let expr = self.parse_or()?;
331
332 if self.match_token(&TokenKind::Assign) {
333 let position = self.previous().position;
334 let value = self.parse_assignment()?;
335
336 match expr {
337 Expression::Identifier { name, .. } => {
338 return Ok(Expression::Assignment {
339 name,
340 value: Box::new(value),
341 position,
342 });
343 }
344 _ => return Err(ParseError::InvalidAssignmentTarget(position)),
345 }
346 }
347
348 Ok(expr)
349 }
350
351 fn parse_or(&mut self) -> Result<Expression, ParseError> {
353 let mut left = self.parse_and()?;
354
355 while self.match_token(&TokenKind::Or) {
356 let position = self.previous().position;
357 let right = self.parse_and()?;
358 left = Expression::Binary {
359 left: Box::new(left),
360 operator: BinaryOp::Or,
361 right: Box::new(right),
362 position,
363 };
364 }
365
366 Ok(left)
367 }
368
369 fn parse_and(&mut self) -> Result<Expression, ParseError> {
371 let mut left = self.parse_equality()?;
372
373 while self.match_token(&TokenKind::And) {
374 let position = self.previous().position;
375 let right = self.parse_equality()?;
376 left = Expression::Binary {
377 left: Box::new(left),
378 operator: BinaryOp::And,
379 right: Box::new(right),
380 position,
381 };
382 }
383
384 Ok(left)
385 }
386
387 fn parse_equality(&mut self) -> Result<Expression, ParseError> {
389 let mut left = self.parse_comparison()?;
390
391 loop {
392 let op = if self.match_token(&TokenKind::Equal) {
393 BinaryOp::Equal
394 } else if self.match_token(&TokenKind::NotEqual) {
395 BinaryOp::NotEqual
396 } else {
397 break;
398 };
399
400 let position = self.previous().position;
401 let right = self.parse_comparison()?;
402 left = Expression::Binary {
403 left: Box::new(left),
404 operator: op,
405 right: Box::new(right),
406 position,
407 };
408 }
409
410 Ok(left)
411 }
412
413 fn parse_comparison(&mut self) -> Result<Expression, ParseError> {
415 let mut left = self.parse_addition()?;
416
417 loop {
418 let op = if self.match_token(&TokenKind::LessThan) {
419 BinaryOp::LessThan
420 } else if self.match_token(&TokenKind::LessEqual) {
421 BinaryOp::LessEqual
422 } else if self.match_token(&TokenKind::GreaterThan) {
423 BinaryOp::GreaterThan
424 } else if self.match_token(&TokenKind::GreaterEqual) {
425 BinaryOp::GreaterEqual
426 } else {
427 break;
428 };
429
430 let position = self.previous().position;
431 let right = self.parse_addition()?;
432 left = Expression::Binary {
433 left: Box::new(left),
434 operator: op,
435 right: Box::new(right),
436 position,
437 };
438 }
439
440 Ok(left)
441 }
442
443 fn parse_addition(&mut self) -> Result<Expression, ParseError> {
445 let mut left = self.parse_multiplication()?;
446
447 loop {
448 let op = if self.match_token(&TokenKind::Plus) {
449 BinaryOp::Add
450 } else if self.match_token(&TokenKind::Minus) {
451 BinaryOp::Subtract
452 } else {
453 break;
454 };
455
456 let position = self.previous().position;
457 let right = self.parse_multiplication()?;
458 left = Expression::Binary {
459 left: Box::new(left),
460 operator: op,
461 right: Box::new(right),
462 position,
463 };
464 }
465
466 Ok(left)
467 }
468
469 fn parse_multiplication(&mut self) -> Result<Expression, ParseError> {
471 let mut left = self.parse_unary()?;
472
473 loop {
474 let op = if self.match_token(&TokenKind::Star) {
475 BinaryOp::Multiply
476 } else if self.match_token(&TokenKind::Slash) {
477 BinaryOp::Divide
478 } else if self.match_token(&TokenKind::Percent) {
479 BinaryOp::Modulo
480 } else {
481 break;
482 };
483
484 let position = self.previous().position;
485 let right = self.parse_unary()?;
486 left = Expression::Binary {
487 left: Box::new(left),
488 operator: op,
489 right: Box::new(right),
490 position,
491 };
492 }
493
494 Ok(left)
495 }
496
497 fn parse_unary(&mut self) -> Result<Expression, ParseError> {
499 if self.match_token(&TokenKind::Bang) {
500 let position = self.previous().position;
501 let operand = self.parse_unary()?;
502 return Ok(Expression::Unary {
503 operator: UnaryOp::Not,
504 operand: Box::new(operand),
505 position,
506 });
507 }
508
509 if self.match_token(&TokenKind::Minus) {
510 let position = self.previous().position;
511 let operand = self.parse_unary()?;
512 return Ok(Expression::Unary {
513 operator: UnaryOp::Negate,
514 operand: Box::new(operand),
515 position,
516 });
517 }
518
519 self.parse_call()
520 }
521
522 fn parse_call(&mut self) -> Result<Expression, ParseError> {
527 let mut expr = self.parse_primary()?;
528
529 loop {
530 if self.match_token(&TokenKind::Dot) {
531 expr = self.parse_method_call_continuation(expr)?;
533 } else if self.is_function_call_start(&expr) {
534 expr = self.parse_function_call_continuation(expr)?;
536 } else {
537 break;
539 }
540 }
541
542 Ok(expr)
543 }
544
545 fn is_function_call_start(&self, expr: &Expression) -> bool {
547 matches!(expr, Expression::Identifier { .. }) && self.check(&TokenKind::LeftParen)
548 }
549
550 fn parse_method_call_continuation(
554 &mut self,
555 receiver: Expression,
556 ) -> Result<Expression, ParseError> {
557 let method_pos = self.previous().position;
558
559 let method = match &self.peek().kind {
561 TokenKind::Identifier(name) => name.clone(),
562 _ => {
563 return Err(ParseError::UnexpectedToken(
564 self.peek().kind.to_string(),
565 self.peek().position,
566 "method name".to_string(),
567 ))
568 }
569 };
570 self.advance();
571
572 self.expect(&TokenKind::LeftParen, "(")?;
574 let arguments = self.parse_arguments()?;
575 self.expect(&TokenKind::RightParen, ")")?;
576
577 Ok(Expression::MethodCall {
578 receiver: Box::new(receiver),
579 method,
580 arguments,
581 position: method_pos,
582 })
583 }
584
585 fn parse_function_call_continuation(
589 &mut self,
590 expr: Expression,
591 ) -> Result<Expression, ParseError> {
592 let Expression::Identifier { name, position } = expr else {
593 return Err(ParseError::ExpectedIdentifier(self.peek().position));
595 };
596
597 self.advance(); let arguments = self.parse_arguments()?;
599 self.expect(&TokenKind::RightParen, ")")?;
600
601 Ok(Expression::Call {
602 function: name,
603 arguments,
604 position,
605 })
606 }
607
608 fn parse_arguments(&mut self) -> Result<Vec<Expression>, ParseError> {
610 let mut args = Vec::new();
611
612 if !self.check(&TokenKind::RightParen) {
613 loop {
614 args.push(self.parse_expression()?);
615 if !self.match_token(&TokenKind::Comma) {
616 break;
617 }
618 }
619 }
620
621 Ok(args)
622 }
623
624 fn parse_primary(&mut self) -> Result<Expression, ParseError> {
626 let position = self.peek().position;
627
628 match &self.peek().kind {
629 TokenKind::Integer(value) => {
630 let value = *value;
631 self.advance();
632 Ok(Expression::Integer { value, position })
633 }
634 TokenKind::Float(value) => {
635 let value = *value;
636 self.advance();
637 Ok(Expression::Float { value, position })
638 }
639 TokenKind::String(value) => {
640 let value = value.clone();
641 self.advance();
642 Ok(Expression::String { value, position })
643 }
644 TokenKind::True => {
645 self.advance();
646 Ok(Expression::Boolean {
647 value: true,
648 position,
649 })
650 }
651 TokenKind::False => {
652 self.advance();
653 Ok(Expression::Boolean {
654 value: false,
655 position,
656 })
657 }
658 TokenKind::Null => {
659 self.advance();
660 Ok(Expression::Null { position })
661 }
662 TokenKind::Identifier(name) => {
663 let name = name.clone();
664 self.advance();
665 Ok(Expression::Identifier { name, position })
666 }
667 TokenKind::LeftParen => {
668 self.advance();
669 let expression = self.parse_expression()?;
670 self.expect(&TokenKind::RightParen, ")")?;
671 Ok(Expression::Grouped {
672 expression: Box::new(expression),
673 position,
674 })
675 }
676 TokenKind::LeftBracket => self.parse_array_literal(),
677 TokenKind::LeftBrace => {
678 if self.is_dictionary_literal() {
682 self.parse_dictionary_literal()
683 } else {
684 Err(ParseError::ExpectedExpression(position))
685 }
686 }
687 TokenKind::Eof => Err(ParseError::UnexpectedEof(position)),
688 _ => Err(ParseError::ExpectedExpression(position)),
689 }
690 }
691
692 fn is_dictionary_literal(&self) -> bool {
695 if !self.check(&TokenKind::LeftBrace) {
696 return false;
697 }
698
699 let mut lookahead = self.current + 1;
701
702 if lookahead >= self.tokens.len() {
704 return false;
705 }
706
707 if matches!(
709 self.tokens.get(lookahead).map(|t| &t.kind),
710 Some(TokenKind::RightBrace)
711 ) {
712 return true;
713 }
714
715 match self.tokens.get(lookahead).map(|t| &t.kind) {
717 Some(TokenKind::String(_)) | Some(TokenKind::Identifier(_)) => {
718 lookahead += 1;
719 matches!(
720 self.tokens.get(lookahead).map(|t| &t.kind),
721 Some(TokenKind::Colon)
722 )
723 }
724 _ => false,
725 }
726 }
727
728 fn parse_array_literal(&mut self) -> Result<Expression, ParseError> {
730 let position = self.peek().position;
731 self.expect(&TokenKind::LeftBracket, "[")?;
732
733 let mut elements = Vec::new();
734
735 if !self.check(&TokenKind::RightBracket) {
736 loop {
737 elements.push(self.parse_expression()?);
738 if !self.match_token(&TokenKind::Comma) {
739 break;
740 }
741 if self.check(&TokenKind::RightBracket) {
743 break;
744 }
745 }
746 }
747
748 self.expect(&TokenKind::RightBracket, "]")?;
749 Ok(Expression::ArrayLiteral { elements, position })
750 }
751
752 fn parse_dictionary_literal(&mut self) -> Result<Expression, ParseError> {
754 let position = self.peek().position;
755 self.expect(&TokenKind::LeftBrace, "{")?;
756
757 let mut pairs = Vec::new();
758
759 if !self.check(&TokenKind::RightBrace) {
760 loop {
761 let key = match &self.peek().kind {
763 TokenKind::String(s) => {
764 let key_pos = self.peek().position;
765 let s = s.clone();
766 self.advance();
767 Expression::String {
768 value: s,
769 position: key_pos,
770 }
771 }
772 TokenKind::Identifier(name) => {
773 let key_pos = self.peek().position;
775 let name = name.clone();
776 self.advance();
777 Expression::String {
778 value: name,
779 position: key_pos,
780 }
781 }
782 _ => {
783 return Err(ParseError::UnexpectedToken(
784 self.peek().kind.to_string(),
785 self.peek().position,
786 "string key".to_string(),
787 ))
788 }
789 };
790
791 self.expect(&TokenKind::Colon, ":")?;
792 let value = self.parse_expression()?;
793 pairs.push((key, value));
794
795 if !self.match_token(&TokenKind::Comma) {
796 break;
797 }
798 if self.check(&TokenKind::RightBrace) {
800 break;
801 }
802 }
803 }
804
805 self.expect(&TokenKind::RightBrace, "}")?;
806 Ok(Expression::DictionaryLiteral { pairs, position })
807 }
808}
809
810#[cfg(test)]
811mod tests {
812 use super::*;
813 use crate::lexer::Lexer;
814
815 fn parse(source: &str) -> Result<Program, ParseError> {
816 let mut lexer = Lexer::new(source);
817 let tokens = lexer.tokenize().expect("Lexer error");
818 let mut parser = Parser::new(tokens);
819 parser.parse()
820 }
821
822 #[test]
823 fn test_let_statement() {
824 let program = parse("let x = 10;").unwrap();
825 assert_eq!(program.statements.len(), 1);
826 assert!(matches!(
827 &program.statements[0],
828 Statement::Let { name, .. } if name == "x"
829 ));
830 }
831
832 #[test]
833 fn test_expression_statement() {
834 let program = parse("42;").unwrap();
835 assert_eq!(program.statements.len(), 1);
836 assert!(matches!(
837 &program.statements[0],
838 Statement::Expression { .. }
839 ));
840 }
841
842 #[test]
843 fn test_binary_expression() {
844 let program = parse("1 + 2 * 3;").unwrap();
845 if let Statement::Expression { expression, .. } = &program.statements[0] {
847 assert!(matches!(
848 expression,
849 Expression::Binary {
850 operator: BinaryOp::Add,
851 ..
852 }
853 ));
854 } else {
855 panic!("Expected expression statement");
856 }
857 }
858
859 #[test]
860 fn test_if_statement() {
861 let program = parse("if (x > 0) { let y = 1; }").unwrap();
862 assert!(matches!(&program.statements[0], Statement::If { .. }));
863 }
864
865 #[test]
866 fn test_if_else_statement() {
867 let program = parse("if (x > 0) { let y = 1; } else { let y = 2; }").unwrap();
868 if let Statement::If { else_block, .. } = &program.statements[0] {
869 assert!(else_block.is_some());
870 } else {
871 panic!("Expected if statement");
872 }
873 }
874
875 #[test]
876 fn test_for_statement() {
877 let program = parse("for (let i = 0; i < 10; i = i + 1) { print(i); }").unwrap();
878 assert!(matches!(&program.statements[0], Statement::For { .. }));
879 }
880
881 #[test]
882 fn test_function_definition() {
883 let program = parse("fn add(a, b) { return a + b; }").unwrap();
884 if let Statement::Function { name, params, .. } = &program.statements[0] {
885 assert_eq!(name, "add");
886 assert_eq!(params, &["a", "b"]);
887 } else {
888 panic!("Expected function definition");
889 }
890 }
891
892 #[test]
893 fn test_function_call() {
894 let program = parse("print(42);").unwrap();
895 if let Statement::Expression { expression, .. } = &program.statements[0] {
896 assert!(matches!(expression, Expression::Call { function, .. } if function == "print"));
897 } else {
898 panic!("Expected expression statement");
899 }
900 }
901
902 #[test]
903 fn test_unary_expression() {
904 let program = parse("-42;").unwrap();
905 if let Statement::Expression { expression, .. } = &program.statements[0] {
906 assert!(matches!(
907 expression,
908 Expression::Unary {
909 operator: UnaryOp::Negate,
910 ..
911 }
912 ));
913 } else {
914 panic!("Expected expression statement");
915 }
916 }
917
918 #[test]
919 fn test_grouped_expression() {
920 let program = parse("(1 + 2) * 3;").unwrap();
921 if let Statement::Expression { expression, .. } = &program.statements[0] {
922 if let Expression::Binary {
923 left,
924 operator: BinaryOp::Multiply,
925 ..
926 } = expression
927 {
928 assert!(matches!(left.as_ref(), Expression::Grouped { .. }));
929 } else {
930 panic!("Expected multiply expression");
931 }
932 } else {
933 panic!("Expected expression statement");
934 }
935 }
936
937 #[test]
938 fn test_assignment_expression() {
939 let program = parse("x = 10;").unwrap();
940 if let Statement::Expression { expression, .. } = &program.statements[0] {
941 assert!(matches!(expression, Expression::Assignment { name, .. } if name == "x"));
942 } else {
943 panic!("Expected expression statement");
944 }
945 }
946
947 #[test]
948 fn test_return_statement() {
949 let program = parse("return 42;").unwrap();
950 assert!(matches!(
951 &program.statements[0],
952 Statement::Return { value: Some(_), .. }
953 ));
954 }
955
956 #[test]
957 fn test_empty_return() {
958 let program = parse("return;").unwrap();
959 assert!(matches!(
960 &program.statements[0],
961 Statement::Return { value: None, .. }
962 ));
963 }
964
965 #[test]
966 fn test_method_call() {
967 let program = parse(r#""hello".len();"#).unwrap();
968 if let Statement::Expression { expression, .. } = &program.statements[0] {
969 assert!(matches!(
970 expression,
971 Expression::MethodCall { method, .. } if method == "len"
972 ));
973 } else {
974 panic!("Expected expression statement with method call");
975 }
976 }
977
978 #[test]
979 fn test_method_call_with_args() {
980 let program = parse(r#"arr.push(1);"#).unwrap();
981 if let Statement::Expression { expression, .. } = &program.statements[0] {
982 if let Expression::MethodCall {
983 method, arguments, ..
984 } = expression
985 {
986 assert_eq!(method, "push");
987 assert_eq!(arguments.len(), 1);
988 } else {
989 panic!("Expected method call");
990 }
991 } else {
992 panic!("Expected expression statement");
993 }
994 }
995
996 #[test]
997 fn test_chained_method_calls() {
998 let program = parse(r#"arr.push(1).len();"#).unwrap();
999 if let Statement::Expression { expression, .. } = &program.statements[0] {
1000 if let Expression::MethodCall {
1002 method, receiver, ..
1003 } = expression
1004 {
1005 assert_eq!(method, "len");
1006 assert!(matches!(
1008 receiver.as_ref(),
1009 Expression::MethodCall { method, .. } if method == "push"
1010 ));
1011 } else {
1012 panic!("Expected method call");
1013 }
1014 } else {
1015 panic!("Expected expression statement");
1016 }
1017 }
1018
1019 #[test]
1020 fn test_method_call_on_literal() {
1021 let program = parse(r#"[1, 2, 3].len();"#).unwrap();
1022 if let Statement::Expression { expression, .. } = &program.statements[0] {
1023 if let Expression::MethodCall {
1024 method, receiver, ..
1025 } = expression
1026 {
1027 assert_eq!(method, "len");
1028 assert!(matches!(receiver.as_ref(), Expression::ArrayLiteral { .. }));
1029 } else {
1030 panic!("Expected method call");
1031 }
1032 } else {
1033 panic!("Expected expression statement");
1034 }
1035 }
1036
1037 #[test]
1038 fn test_method_call_invalid_method_name_error() {
1039 let result = parse(r#""hello".123();"#);
1041 assert!(matches!(
1042 result,
1043 Err(ParseError::UnexpectedToken(_, _, expected)) if expected == "method name"
1044 ));
1045 }
1046
1047 #[test]
1048 fn test_method_call_missing_parens_error() {
1049 let result = parse(r#""hello".len;"#);
1051 assert!(matches!(result, Err(ParseError::UnexpectedToken(_, _, _))));
1052 }
1053}