Parse array init expressions

This commit is contained in:
Pranav Gaddamadugu 2023-10-08 12:38:54 -04:00 committed by Pranav Gaddamadugu
parent 2edc7aa92f
commit 13e17044fd
4 changed files with 33 additions and 0 deletions

View File

@ -240,6 +240,14 @@ impl<'a> ParserContext<'a> {
self.parse_list(Delimiter::Parenthesis, Some(Token::Comma), f)
}
/// Parse a list separated by `,` and delimited by brackets.
pub(super) fn parse_bracket_comma_list<T>(
&mut self,
f: impl FnMut(&mut Self) -> Result<Option<T>>,
) -> Result<(Vec<T>, bool, Span)> {
self.parse_list(Delimiter::Bracket, Some(Token::Comma), f)
}
/// Returns true if the current token is `(`.
pub(super) fn peek_is_left_par(&self) -> bool {
matches!(self.token.token, Token::LeftParen)

View File

@ -543,6 +543,19 @@ impl ParserContext<'_> {
}
}
/// Returns an [`Expression`] AST node if the next tokens represent an array initialization expression.
fn parse_array_expression(&mut self) -> Result<Expression> {
let (elements, _, span) = self.parse_bracket_comma_list(|p| p.parse_expression().map(Some))?;
match elements.is_empty() {
// If the array expression is empty, return an error.
true => Err(ParserError::array_must_have_at_least_one_element("expression", span).into()),
// Otherwise, return an array expression.
// Note: This is the only place where `ArrayExpression` is constructed in the parser.
false => Ok(Expression::Array(ArrayExpression { elements, span, id: self.node_builder.next_id() })),
}
}
/// Returns a reference to the next token if it is a [`GroupCoordinate`], or [None] if
/// the next token is not a [`GroupCoordinate`].
fn peek_group_coordinate(&self, dist: &mut usize) -> Option<GroupCoordinate> {
@ -651,6 +664,8 @@ impl ParserContext<'_> {
fn parse_primary_expression(&mut self) -> Result<Expression> {
if let Token::LeftParen = self.token.token {
return self.parse_tuple_expression();
} else if let Token::LeftSquare = self.token.token {
return self.parse_array_expression();
}
let SpannedToken { token, span } = self.token.clone();

View File

@ -380,6 +380,8 @@ pub enum Delimiter {
Parenthesis,
/// `{ ... }`
Brace,
/// `[ ... ]`
Bracket,
}
impl Delimiter {
@ -388,6 +390,7 @@ impl Delimiter {
match self {
Self::Parenthesis => (Token::LeftParen, Token::RightParen),
Self::Brace => (Token::LeftCurly, Token::RightCurly),
Self::Bracket => (Token::LeftSquare, Token::RightSquare),
}
}
}

View File

@ -291,4 +291,11 @@ create_messages!(
msg: format!("expected no underscores or leading zeros -- found '{found}'"),
help: None,
}
@formatted
array_must_have_at_least_one_element {
args: (kind: impl Display),
msg: format!("An array {kind} must have at least one element."),
help: None,
}
);