From 9ca03f5fdd9d5f78d8ab9b63337a1a15d6a55579 Mon Sep 17 00:00:00 2001 From: Ryan Chandler Date: Fri, 16 Sep 2022 11:21:18 +0100 Subject: [PATCH] parser: support unpacking array items --- trunk_parser/src/ast.rs | 1 + trunk_parser/src/parser/mod.rs | 71 +++++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/trunk_parser/src/ast.rs b/trunk_parser/src/ast.rs index a9656ee..7504f6c 100644 --- a/trunk_parser/src/ast.rs +++ b/trunk_parser/src/ast.rs @@ -591,6 +591,7 @@ pub enum MagicConst { pub struct ArrayItem { pub key: Option, pub value: Expression, + pub unpack: bool, } #[derive(Debug, Eq, PartialEq, Clone)] diff --git a/trunk_parser/src/parser/mod.rs b/trunk_parser/src/parser/mod.rs index 9e01b2d..fbadcd4 100644 --- a/trunk_parser/src/parser/mod.rs +++ b/trunk_parser/src/parser/mod.rs @@ -1595,6 +1595,13 @@ impl Parser { while self.current.kind != TokenKind::RightParen { let mut key = None; + let unpack = if self.current.kind == TokenKind::Ellipsis { + self.next(); + true + } else { + false + }; + let mut value = self.expression(Precedence::Lowest)?; if self.current.kind == TokenKind::DoubleArrow { @@ -1604,7 +1611,7 @@ impl Parser { value = self.expression(Precedence::Lowest)?; } - items.push(ArrayItem { key, value }); + items.push(ArrayItem { key, value, unpack }); self.optional_comma()?; @@ -1626,12 +1633,19 @@ impl Parser { items.push(ArrayItem { key: None, value: Expression::Empty, + unpack: false, }); self.next(); continue; } let mut key = None; + let unpack = if self.current.kind == TokenKind::Ellipsis { + self.next(); + true + } else { + false + }; let mut value = self.expression(Precedence::Lowest)?; if self.current.kind == TokenKind::DoubleArrow { @@ -1641,7 +1655,7 @@ impl Parser { value = self.expression(Precedence::Lowest)?; } - items.push(ArrayItem { key, value }); + items.push(ArrayItem { key, value, unpack }); self.optional_comma()?; @@ -3424,10 +3438,12 @@ mod tests { ArrayItem { key: None, value: Expression::Variable { name: "baz".into() }, + unpack: false, }, ArrayItem { key: None, value: Expression::Variable { name: "car".into() }, + unpack: false, }, ], }, @@ -3777,18 +3793,22 @@ mod tests { ArrayItem { key: None, value: Expression::Int { i: 1 }, + unpack: false, }, ArrayItem { key: None, value: Expression::Int { i: 2 }, + unpack: false, }, ArrayItem { key: None, value: Expression::Empty, + unpack: false, }, ArrayItem { key: None, value: Expression::Int { i: 4 }, + unpack: false, }, ] })], @@ -4339,6 +4359,53 @@ mod tests { ); } + #[test] + fn unpack_array_items() { + assert_ast( + "