Parses a variable list of comma-separated expressions. The caller must have consumed the open parenthesis and we stop processing when we encounter the terminating parenthesis (and consume it). We expect at least one expression.
(&mut self)
| 730 | /// open parenthesis and we stop processing when we encounter the terminating parenthesis (and |
| 731 | /// consume it). We expect at least one expression. |
| 732 | fn parse_comma_separated_exprs(&mut self) -> Result<Vec<ArgSpan>> { |
| 733 | let mut spans = vec![]; |
| 734 | |
| 735 | // The first expression is optional to support calls to functions without arguments. |
| 736 | let mut is_first = true; |
| 737 | let mut prev_expr = self.parse_expr(None)?; |
| 738 | |
| 739 | loop { |
| 740 | let peeked = self.lexer.peek()?; |
| 741 | let pos = peeked.pos; |
| 742 | match &peeked.token { |
| 743 | Token::RightParen => { |
| 744 | self.lexer.consume_peeked(); |
| 745 | |
| 746 | if let Some(expr) = prev_expr.take() { |
| 747 | spans.push(ArgSpan { expr: Some(expr), sep: ArgSep::End, sep_pos: pos }); |
| 748 | } else if !is_first { |
| 749 | return Err(Error::Bad(pos, "Missing expression".to_owned())); |
| 750 | } |
| 751 | |
| 752 | break; |
| 753 | } |
| 754 | Token::Comma => { |
| 755 | self.lexer.consume_peeked(); |
| 756 | |
| 757 | if let Some(expr) = prev_expr.take() { |
| 758 | // The first expression is optional to support calls to functions without |
| 759 | // arguments. |
| 760 | spans.push(ArgSpan { expr: Some(expr), sep: ArgSep::Long, sep_pos: pos }); |
| 761 | } else { |
| 762 | return Err(Error::Bad(pos, "Missing expression".to_owned())); |
| 763 | } |
| 764 | |
| 765 | prev_expr = self.parse_expr(None)?; |
| 766 | } |
| 767 | t => return Err(Error::Bad(pos, format!("Unexpected {}", t))), |
| 768 | } |
| 769 | |
| 770 | is_first = false; |
| 771 | } |
| 772 | |
| 773 | Ok(spans) |
| 774 | } |
| 775 | |
| 776 | /// Parses an expression. |
| 777 | /// |
no test coverage detected