From c210b76f4e27f9ba355f8592f2bcb5dddc83c35e Mon Sep 17 00:00:00 2001 From: Gil Ben-Shachar Date: Mon, 26 Jun 2023 17:15:17 +0300 Subject: [PATCH] Allow brackets and braces in inline_macro. --- .../src/node_properties.rs | 16 +- crates/cairo-lang-parser/src/parser.rs | 91 ++++- .../src/parser_test_data/function_signature | 2 +- .../src/parser_test_data/inline_macro | 9 +- crates/cairo-lang-parser/src/recovery.rs | 7 + .../expected_results/test1_tree_no_trivia | 4 +- .../expected_results/test1_tree_with_trivia | 4 +- .../expected_results/test2_tree_no_trivia | 2 +- .../expected_results/test2_tree_with_trivia | 2 +- .../expected_results/test3_tree_no_trivia | 8 +- .../expected_results/test3_tree_with_trivia | 8 +- .../src/plugins/consteval_int.rs | 24 +- .../cairo-lang-semantic/src/expr/compute.rs | 2 +- .../src/cairo_spec.rs | 21 +- crates/cairo-lang-syntax/src/node/ast.rs | 318 ++++++++++++++++-- .../cairo-lang-syntax/src/node/key_fields.rs | 8 +- crates/cairo-lang-syntax/src/node/kind.rs | 4 +- 17 files changed, 451 insertions(+), 79 deletions(-) diff --git a/crates/cairo-lang-formatter/src/node_properties.rs b/crates/cairo-lang-formatter/src/node_properties.rs index 1c8e0347f47..332b7e5438c 100644 --- a/crates/cairo-lang-formatter/src/node_properties.rs +++ b/crates/cairo-lang-formatter/src/node_properties.rs @@ -195,7 +195,9 @@ impl SyntaxNodeFormat for SyntaxNode { | SyntaxKind::ExprParenthesized | SyntaxKind::ExprPath | SyntaxKind::ExprStructCtorCall - | SyntaxKind::ExprTuple + | SyntaxKind::ExprListParenthesized + | SyntaxKind::ExprListBraced + | SyntaxKind::ExprListBracketed | SyntaxKind::ExprUnary => Some(2), SyntaxKind::ElseClause => Some(3), _ => None, @@ -214,7 +216,9 @@ impl SyntaxNodeFormat for SyntaxNode { | SyntaxKind::ExprParenthesized | SyntaxKind::ExprPath | SyntaxKind::ExprStructCtorCall - | SyntaxKind::ExprTuple + | SyntaxKind::ExprListParenthesized + | SyntaxKind::ExprListBraced + | SyntaxKind::ExprListBracketed | SyntaxKind::ExprUnary => Some(10), _ => None, }, @@ -231,7 +235,9 @@ impl SyntaxNodeFormat for SyntaxNode { | SyntaxKind::ExprParenthesized | SyntaxKind::ExprPath | SyntaxKind::ExprStructCtorCall - | SyntaxKind::ExprTuple + | SyntaxKind::ExprListParenthesized + | SyntaxKind::ExprListBraced + | SyntaxKind::ExprListBracketed | SyntaxKind::ExprUnary => Some(1), SyntaxKind::TerminalEq => Some(10), SyntaxKind::PatternEnum | SyntaxKind::PatternTuple | SyntaxKind::PatternStruct => { @@ -244,7 +250,9 @@ impl SyntaxNodeFormat for SyntaxNode { SyntaxKind::ExprParenthesized | SyntaxKind::ExprList | SyntaxKind::ExprBlock - | SyntaxKind::ExprTuple + | SyntaxKind::ExprListParenthesized + | SyntaxKind::ExprListBraced + | SyntaxKind::ExprListBracketed | SyntaxKind::PatternTuple | SyntaxKind::ModuleBody | SyntaxKind::MatchArms diff --git a/crates/cairo-lang-parser/src/parser.rs b/crates/cairo-lang-parser/src/parser.rs index 7738fad67ce..ff0a6691422 100644 --- a/crates/cairo-lang-parser/src/parser.rs +++ b/crates/cairo-lang-parser/src/parser.rs @@ -927,13 +927,79 @@ impl<'a> Parser<'a> { ExprFunctionCall::new_green(self.db, func_name, parenthesized_args) } - /// Assumes the current token is LParen. - /// Expected pattern: `` + /// Assumes the current token is TerminalNot. + /// Expected pattern: `!` fn expect_macro_call(&mut self, path: ExprPathGreen) -> ExprInlineMacroGreen { let bang = self.take::(); let macro_name = path; - let parenthesized_args = self.expect_parenthesized_argument_list(); - ExprInlineMacro::new_green(self.db, macro_name, bang, parenthesized_args) + let wrapped_expr_list = self.parse_wrapped_expr_list(); + ExprInlineMacro::new_green(self.db, macro_name, bang, wrapped_expr_list) + } + + /// Returns a GreenId of a node with an ExprTuple|ExprListBracketed kind or None if such an + /// argument list can't be parsed. + fn parse_wrapped_expr_list(&mut self) -> WrappedExprListGreen { + let current_token = self.peek().kind; + match current_token { + SyntaxKind::TerminalLParen => self.expect_parenthesized_expr_list().into(), + SyntaxKind::TerminalLBrack => self.expect_bracketed_expr_list().into(), + SyntaxKind::TerminalLBrace => self.expect_braced_expr_list().into(), + _ => self.create_and_report_missing::( + ParserDiagnosticKind::MissingExpression, + ), + } + } + + /// Assumes the current token is LBrack. + /// Expected pattern: `\((,)*?\)` + /// Returns a GreenId of a node with kind ExprListParenthesized. + fn expect_parenthesized_expr_list(&mut self) -> ExprListParenthesizedGreen { + let lparen = self.take::(); + let exprs: Vec = self + .parse_separated_list::( + Self::try_parse_expr, + is_of_kind!(rparen, rbrace, rbrack, block, top_level), + "expression", + ); + let rparen = self.parse_token::(); + ExprListParenthesized::new_green( + self.db, + lparen, + ExprList::new_green(self.db, exprs), + rparen, + ) + } + + /// Assumes the current token is LBrack. + /// Expected pattern: `\[(,)*?\]` + /// Returns a GreenId of a node with kind ExprListBracketed. + fn expect_bracketed_expr_list(&mut self) -> ExprListBracketedGreen { + let lbrack = self.take::(); + let exprs: Vec = self + .parse_separated_list::( + Self::try_parse_expr, + is_of_kind!(rparen, rbrace, rbrack, block, top_level), + "expression", + ); + let rbrack = self.parse_token::(); + + ExprListBracketed::new_green(self.db, lbrack, ExprList::new_green(self.db, exprs), rbrack) + } + + /// Assumes the current token is LBrace. + /// Expected pattern: `\{(,)*?\}` + /// Returns a GreenId of a node with kind ExprListBraced. + fn expect_braced_expr_list(&mut self) -> ExprListBracedGreen { + let lbrace = self.take::(); + let exprs: Vec = self + .parse_separated_list::( + Self::try_parse_expr, + is_of_kind!(rparen, rbrace, rbrack, block, top_level), + "expression", + ); + let rbrace = self.parse_token::(); + + ExprListBraced::new_green(self.db, lbrace, ExprList::new_green(self.db, exprs), rbrace) } /// Assumes the current token is LParen. @@ -1075,8 +1141,13 @@ impl<'a> Parser<'a> { // We have exactly one item and no separator --> This is not a tuple. ExprParenthesized::new_green(self.db, lparen, *expr, rparen).into() } else { - ExprTuple::new_green(self.db, lparen, ExprList::new_green(self.db, exprs), rparen) - .into() + ExprListParenthesized::new_green( + self.db, + lparen, + ExprList::new_green(self.db, exprs), + rparen, + ) + .into() } } @@ -1099,7 +1170,13 @@ impl<'a> Parser<'a> { span: TextSpan { start: self.offset, end: self.offset }, }); } - ExprTuple::new_green(self.db, lparen, ExprList::new_green(self.db, exprs), rparen).into() + ExprListParenthesized::new_green( + self.db, + lparen, + ExprList::new_green(self.db, exprs), + rparen, + ) + .into() } /// Assumes the current token is DotDot. diff --git a/crates/cairo-lang-parser/src/parser_test_data/function_signature b/crates/cairo-lang-parser/src/parser_test_data/function_signature index 53451dc1692..f160ffc800a 100644 --- a/crates/cairo-lang-parser/src/parser_test_data/function_signature +++ b/crates/cairo-lang-parser/src/parser_test_data/function_signature @@ -94,7 +94,7 @@ fn bar() -> (felt252) { ├── rparen (kind: TokenRParen): ')' ├── ret_ty (kind: ReturnTypeClause) │ ├── arrow (kind: TokenArrow): '->' - │ └── ty (kind: ExprTuple) + │ └── ty (kind: ExprListParenthesized) │ ├── lparen (kind: TokenLParen): '(' │ ├── expressions (kind: ExprList) │ │ └── item #0 (kind: ExprPath) diff --git a/crates/cairo-lang-parser/src/parser_test_data/inline_macro b/crates/cairo-lang-parser/src/parser_test_data/inline_macro index dde3769b9fc..8db5d1d0ff5 100644 --- a/crates/cairo-lang-parser/src/parser_test_data/inline_macro +++ b/crates/cairo-lang-parser/src/parser_test_data/inline_macro @@ -21,11 +21,8 @@ ExprInlineMacro │ └── item #0 (kind: PathSegmentSimple) │ └── ident (kind: TokenIdentifier): 'println' ├── bang (kind: TokenNot): '!' - └── arguments (kind: ArgListParenthesized) + └── arguments (kind: ExprListParenthesized) ├── lparen (kind: TokenLParen): '(' - ├── args (kind: ArgList) - │ └── item #0 (kind: Arg) - │ ├── modifiers (kind: ModifierList) [] - │ └── arg_clause (kind: ArgClauseUnnamed) - │ └── value (kind: TokenShortString): ''foo'' + ├── expressions (kind: ExprList) + │ └── item #0 (kind: TokenShortString): ''foo'' └── rparen (kind: TokenRParen): ')' diff --git a/crates/cairo-lang-parser/src/recovery.rs b/crates/cairo-lang-parser/src/recovery.rs index 51ae752f01a..544f1978ac5 100644 --- a/crates/cairo-lang-parser/src/recovery.rs +++ b/crates/cairo-lang-parser/src/recovery.rs @@ -34,6 +34,13 @@ macro_rules! rparen { } pub(crate) use rparen; +macro_rules! rbrack { + () => { + SyntaxKind::TerminalRBrack + }; +} +pub(crate) use rbrack; + macro_rules! rangle { () => { SyntaxKind::TerminalGT diff --git a/crates/cairo-lang-parser/test_data/expected_results/test1_tree_no_trivia b/crates/cairo-lang-parser/test_data/expected_results/test1_tree_no_trivia index aea53d7626d..23b5c515e57 100644 --- a/crates/cairo-lang-parser/test_data/expected_results/test1_tree_no_trivia +++ b/crates/cairo-lang-parser/test_data/expected_results/test1_tree_no_trivia @@ -520,7 +520,7 @@ │ │ │ ├── name (kind: TokenIdentifier): 'member2' │ │ │ └── type_clause (kind: TypeClause) │ │ │ ├── colon (kind: TokenColon): ':' - │ │ │ └── ty (kind: ExprTuple) + │ │ │ └── ty (kind: ExprListParenthesized) │ │ │ ├── lparen (kind: TokenLParen): '(' │ │ │ ├── expressions (kind: ExprList) │ │ │ │ ├── item #0 (kind: ExprPath) @@ -531,7 +531,7 @@ │ │ │ │ │ └── item #0 (kind: PathSegmentSimple) │ │ │ │ │ └── ident (kind: TokenIdentifier): 'felt252' │ │ │ │ ├── separator #1 (kind: TokenComma): ',' - │ │ │ │ └── item #2 (kind: ExprTuple) + │ │ │ │ └── item #2 (kind: ExprListParenthesized) │ │ │ │ ├── lparen (kind: TokenLParen): '(' │ │ │ │ ├── expressions (kind: ExprList) [] │ │ │ │ └── rparen (kind: TokenRParen): ')' diff --git a/crates/cairo-lang-parser/test_data/expected_results/test1_tree_with_trivia b/crates/cairo-lang-parser/test_data/expected_results/test1_tree_with_trivia index 56e808f92f0..cfc2ef69993 100644 --- a/crates/cairo-lang-parser/test_data/expected_results/test1_tree_with_trivia +++ b/crates/cairo-lang-parser/test_data/expected_results/test1_tree_with_trivia @@ -1422,7 +1422,7 @@ │ │ │ │ ├── token (kind: TokenColon): ':' │ │ │ │ └── trailing_trivia (kind: Trivia) │ │ │ │ └── child #0 (kind: TokenWhitespace). - │ │ │ └── ty (kind: ExprTuple) + │ │ │ └── ty (kind: ExprListParenthesized) │ │ │ ├── lparen (kind: TerminalLParen) │ │ │ │ ├── leading_trivia (kind: Trivia) [] │ │ │ │ ├── token (kind: TokenLParen): '(' @@ -1450,7 +1450,7 @@ │ │ │ │ │ ├── token (kind: TokenComma): ',' │ │ │ │ │ └── trailing_trivia (kind: Trivia) │ │ │ │ │ └── child #0 (kind: TokenWhitespace). - │ │ │ │ └── item #2 (kind: ExprTuple) + │ │ │ │ └── item #2 (kind: ExprListParenthesized) │ │ │ │ ├── lparen (kind: TerminalLParen) │ │ │ │ │ ├── leading_trivia (kind: Trivia) [] │ │ │ │ │ ├── token (kind: TokenLParen): '(' diff --git a/crates/cairo-lang-parser/test_data/expected_results/test2_tree_no_trivia b/crates/cairo-lang-parser/test_data/expected_results/test2_tree_no_trivia index 506504c12c0..1f379302518 100644 --- a/crates/cairo-lang-parser/test_data/expected_results/test2_tree_no_trivia +++ b/crates/cairo-lang-parser/test_data/expected_results/test2_tree_no_trivia @@ -107,7 +107,7 @@ │ │ │ │ │ │ │ ├── identifier (kind: TokenIdentifier): '_gg' │ │ │ │ │ │ │ └── arg_expr (kind: StructArgExpr) │ │ │ │ │ │ │ ├── colon (kind: TokenColon): ':' - │ │ │ │ │ │ │ └── expr (kind: ExprTuple) + │ │ │ │ │ │ │ └── expr (kind: ExprListParenthesized) │ │ │ │ │ │ │ ├── lparen (kind: TokenLParen): '(' │ │ │ │ │ │ │ ├── expressions (kind: ExprList) [] │ │ │ │ │ │ │ └── rparen (kind: TokenRParen): ')' diff --git a/crates/cairo-lang-parser/test_data/expected_results/test2_tree_with_trivia b/crates/cairo-lang-parser/test_data/expected_results/test2_tree_with_trivia index a2cdbbd013a..dc466f3b55c 100644 --- a/crates/cairo-lang-parser/test_data/expected_results/test2_tree_with_trivia +++ b/crates/cairo-lang-parser/test_data/expected_results/test2_tree_with_trivia @@ -290,7 +290,7 @@ │ │ │ │ │ │ │ │ ├── token (kind: TokenColon): ':' │ │ │ │ │ │ │ │ └── trailing_trivia (kind: Trivia) │ │ │ │ │ │ │ │ └── child #0 (kind: TokenWhitespace). - │ │ │ │ │ │ │ └── expr (kind: ExprTuple) + │ │ │ │ │ │ │ └── expr (kind: ExprListParenthesized) │ │ │ │ │ │ │ ├── lparen (kind: TerminalLParen) │ │ │ │ │ │ │ │ ├── leading_trivia (kind: Trivia) [] │ │ │ │ │ │ │ │ ├── token (kind: TokenLParen): '(' diff --git a/crates/cairo-lang-parser/test_data/expected_results/test3_tree_no_trivia b/crates/cairo-lang-parser/test_data/expected_results/test3_tree_no_trivia index 68f8ea16c20..05dc52e6c01 100644 --- a/crates/cairo-lang-parser/test_data/expected_results/test3_tree_no_trivia +++ b/crates/cairo-lang-parser/test_data/expected_results/test3_tree_no_trivia @@ -130,9 +130,9 @@ │ │ │ │ │ │ └── item #0 (kind: PathSegmentSimple) │ │ │ │ │ │ └── ident (kind: TokenIdentifier): 'some_macro' │ │ │ │ │ ├── bang (kind: TokenNot): '!' - │ │ │ │ │ └── arguments (kind: ArgListParenthesized) + │ │ │ │ │ └── arguments (kind: ExprListParenthesized) │ │ │ │ │ ├── lparen (kind: TokenLParen): '(' - │ │ │ │ │ ├── args (kind: ArgList) [] + │ │ │ │ │ ├── expressions (kind: ExprList) [] │ │ │ │ │ └── rparen (kind: TokenRParen): ')' │ │ │ │ └── semicolon (kind: TokenSemicolon): ';' │ │ │ └── child #2 (kind: StatementExpr) @@ -245,7 +245,7 @@ │ │ ├── rparen (kind: TokenRParen): ')' │ │ ├── ret_ty (kind: ReturnTypeClause) │ │ │ ├── arrow (kind: TokenArrow): '->' - │ │ │ └── ty (kind: ExprTuple) + │ │ │ └── ty (kind: ExprListParenthesized) │ │ │ ├── lparen (kind: TokenLParen): '(' │ │ │ ├── expressions (kind: ExprList) │ │ │ │ ├── item #0 (kind: ExprPath) @@ -305,7 +305,7 @@ │ │ │ │ ├── item #0 (kind: MatchArm) │ │ │ │ │ ├── pattern (kind: TokenLiteralNumber): '0' │ │ │ │ │ ├── arrow (kind: TokenMatchArrow): '=>' - │ │ │ │ │ └── expression (kind: ExprTuple) + │ │ │ │ │ └── expression (kind: ExprListParenthesized) │ │ │ │ │ ├── lparen (kind: TokenLParen): '(' │ │ │ │ │ ├── expressions (kind: ExprList) │ │ │ │ │ │ ├── item #0 (kind: ExprFunctionCall) diff --git a/crates/cairo-lang-parser/test_data/expected_results/test3_tree_with_trivia b/crates/cairo-lang-parser/test_data/expected_results/test3_tree_with_trivia index 45e08cd8f29..ddb0b388c97 100644 --- a/crates/cairo-lang-parser/test_data/expected_results/test3_tree_with_trivia +++ b/crates/cairo-lang-parser/test_data/expected_results/test3_tree_with_trivia @@ -303,12 +303,12 @@ │ │ │ │ │ │ ├── leading_trivia (kind: Trivia) [] │ │ │ │ │ │ ├── token (kind: TokenNot): '!' │ │ │ │ │ │ └── trailing_trivia (kind: Trivia) [] - │ │ │ │ │ └── arguments (kind: ArgListParenthesized) + │ │ │ │ │ └── arguments (kind: ExprListParenthesized) │ │ │ │ │ ├── lparen (kind: TerminalLParen) │ │ │ │ │ │ ├── leading_trivia (kind: Trivia) [] │ │ │ │ │ │ ├── token (kind: TokenLParen): '(' │ │ │ │ │ │ └── trailing_trivia (kind: Trivia) [] - │ │ │ │ │ ├── args (kind: ArgList) [] + │ │ │ │ │ ├── expressions (kind: ExprList) [] │ │ │ │ │ └── rparen (kind: TerminalRParen) │ │ │ │ │ ├── leading_trivia (kind: Trivia) [] │ │ │ │ │ ├── token (kind: TokenRParen): ')' @@ -593,7 +593,7 @@ │ │ │ │ ├── token (kind: TokenArrow): '->' │ │ │ │ └── trailing_trivia (kind: Trivia) │ │ │ │ └── child #0 (kind: TokenWhitespace). - │ │ │ └── ty (kind: ExprTuple) + │ │ │ └── ty (kind: ExprListParenthesized) │ │ │ ├── lparen (kind: TerminalLParen) │ │ │ │ ├── leading_trivia (kind: Trivia) [] │ │ │ │ ├── token (kind: TokenLParen): '(' @@ -737,7 +737,7 @@ │ │ │ │ │ │ ├── token (kind: TokenMatchArrow): '=>' │ │ │ │ │ │ └── trailing_trivia (kind: Trivia) │ │ │ │ │ │ └── child #0 (kind: TokenWhitespace). - │ │ │ │ │ └── expression (kind: ExprTuple) + │ │ │ │ │ └── expression (kind: ExprListParenthesized) │ │ │ │ │ ├── lparen (kind: TerminalLParen) │ │ │ │ │ │ ├── leading_trivia (kind: Trivia) [] │ │ │ │ │ │ ├── token (kind: TokenLParen): '(' diff --git a/crates/cairo-lang-plugins/src/plugins/consteval_int.rs b/crates/cairo-lang-plugins/src/plugins/consteval_int.rs index 742695df51e..a8c4cf25ae1 100644 --- a/crates/cairo-lang-plugins/src/plugins/consteval_int.rs +++ b/crates/cairo-lang-plugins/src/plugins/consteval_int.rs @@ -74,24 +74,24 @@ fn extract_consteval_macro_expression( macro_ast: &ast::ExprInlineMacro, diagnostics: &mut Vec, ) -> Option { - let args = macro_ast.arguments(db).args(db).elements(db); - if args.len() != 1 { + let wrapped_args = macro_ast.arguments(db); + let exprs = match wrapped_args { + ast::WrappedExprList::BracketedExprList(args_list) => { + args_list.expressions(db).elements(db) + } + ast::WrappedExprList::ParenthesizedExprList(args_list) => { + args_list.expressions(db).elements(db) + } + ast::WrappedExprList::BracedExprList(args_list) => args_list.expressions(db).elements(db), + }; + if exprs.len() != 1 { diagnostics.push(PluginDiagnostic { stable_ptr: macro_ast.stable_ptr().untyped(), message: "consteval_int macro must have a single unnamed argument.".to_string(), }); return None; } - match args[0].arg_clause(db) { - ast::ArgClause::Unnamed(arg) => Some(arg.value(db)), - _ => { - diagnostics.push(PluginDiagnostic { - stable_ptr: macro_ast.stable_ptr().untyped(), - message: "consteval_int macro must have a single unnamed argument.".to_string(), - }); - None - } - } + Some(exprs[0].clone()) } /// Compute the actual value of an integer expression, or fail with diagnostics. diff --git a/crates/cairo-lang-semantic/src/expr/compute.rs b/crates/cairo-lang-semantic/src/expr/compute.rs index 7cc3680e972..6f18b36b567 100644 --- a/crates/cairo-lang-semantic/src/expr/compute.rs +++ b/crates/cairo-lang-semantic/src/expr/compute.rs @@ -466,7 +466,7 @@ fn call_core_binary_op( fn compute_expr_tuple_semantic( ctx: &mut ComputationContext<'_>, - syntax: &ast::ExprTuple, + syntax: &ast::ExprListParenthesized, ) -> Maybe { let db = ctx.db; let syntax_db = db.upcast(); diff --git a/crates/cairo-lang-syntax-codegen/src/cairo_spec.rs b/crates/cairo-lang-syntax-codegen/src/cairo_spec.rs index 6708d9cd31d..1c6ce1a9c5b 100644 --- a/crates/cairo-lang-syntax-codegen/src/cairo_spec.rs +++ b/crates/cairo-lang-syntax-codegen/src/cairo_spec.rs @@ -22,7 +22,7 @@ pub fn get_spec() -> Vec { .node("Parenthesized") .node("Unary") .node("Binary") - .node("Tuple") + .node_with_explicit_kind("Tuple", "ExprListParenthesized") .node("FunctionCall") .node("StructCtorCall") .node("Block") @@ -114,7 +114,7 @@ pub fn get_spec() -> Vec { .node_with_explicit_kind("LT", "TerminalLT") .node_with_explicit_kind("GT", "TerminalGT") ) - .add_struct(StructBuilder::new("ExprTuple") + .add_struct(StructBuilder::new("ExprListParenthesized") .node("lparen", "TerminalLParen") .node("expressions", "ExprList") .node("rparen", "TerminalRParen") @@ -181,7 +181,7 @@ pub fn get_spec() -> Vec { .add_struct(StructBuilder::new("ExprInlineMacro") .node("path", "ExprPath") .node("bang", "TerminalNot") - .node("arguments", "ArgListParenthesized") + .node("arguments", "WrappedExprList") ) // --- Struct ctor --- .add_struct(StructBuilder::new("StructArgExpr") @@ -207,6 +207,21 @@ pub fn get_spec() -> Vec { .node("arguments", "StructArgList") .node("rbrace", "TerminalRBrace") ) + .add_struct(StructBuilder::new("ExprListBracketed") + .node("lbrack", "TerminalLBrack") + .node("expressions", "ExprList") + .node("rbrack", "TerminalRBrack") +) + .add_struct(StructBuilder::new("ExprListBraced") + .node("lbrace", "TerminalLBrace") + .node("expressions", "ExprList") + .node("rbrace", "TerminalRBrace") + ) + .add_enum(EnumBuilder::new("WrappedExprList") + .node_with_explicit_kind("BracketedExprList", "ExprListBracketed") + .node_with_explicit_kind("ParenthesizedExprList", "ExprListParenthesized") + .node_with_explicit_kind("BracedExprList", "ExprListBraced") + ) // ---Patterns --- // TODO(spapini): Support "Or" patterns (e.g. 1 | 2). // TODO(spapini): Support tuple patterns (e.g. (x, _)). diff --git a/crates/cairo-lang-syntax/src/node/ast.rs b/crates/cairo-lang-syntax/src/node/ast.rs index 18d6e653fd9..2e332db6e37 100644 --- a/crates/cairo-lang-syntax/src/node/ast.rs +++ b/crates/cairo-lang-syntax/src/node/ast.rs @@ -185,7 +185,7 @@ pub enum Expr { Parenthesized(ExprParenthesized), Unary(ExprUnary), Binary(ExprBinary), - Tuple(ExprTuple), + Tuple(ExprListParenthesized), FunctionCall(ExprFunctionCall), StructCtorCall(ExprStructCtorCall), Block(ExprBlock), @@ -245,8 +245,8 @@ impl From for ExprPtr { Self(value.0) } } -impl From for ExprPtr { - fn from(value: ExprTuplePtr) -> Self { +impl From for ExprPtr { + fn from(value: ExprListParenthesizedPtr) -> Self { Self(value.0) } } @@ -345,8 +345,8 @@ impl From for ExprGreen { Self(value.0) } } -impl From for ExprGreen { - fn from(value: ExprTupleGreen) -> Self { +impl From for ExprGreen { + fn from(value: ExprListParenthesizedGreen) -> Self { Self(value.0) } } @@ -431,7 +431,9 @@ impl TypedSyntaxNode for Expr { } SyntaxKind::ExprUnary => Expr::Unary(ExprUnary::from_syntax_node(db, node)), SyntaxKind::ExprBinary => Expr::Binary(ExprBinary::from_syntax_node(db, node)), - SyntaxKind::ExprTuple => Expr::Tuple(ExprTuple::from_syntax_node(db, node)), + SyntaxKind::ExprListParenthesized => { + Expr::Tuple(ExprListParenthesized::from_syntax_node(db, node)) + } SyntaxKind::ExprFunctionCall => { Expr::FunctionCall(ExprFunctionCall::from_syntax_node(db, node)) } @@ -499,7 +501,7 @@ impl Expr { SyntaxKind::ExprParenthesized => true, SyntaxKind::ExprUnary => true, SyntaxKind::ExprBinary => true, - SyntaxKind::ExprTuple => true, + SyntaxKind::ExprListParenthesized => true, SyntaxKind::ExprFunctionCall => true, SyntaxKind::ExprStructCtorCall => true, SyntaxKind::ExprBlock => true, @@ -2381,11 +2383,11 @@ impl BinaryOperator { } } #[derive(Clone, Debug, Eq, Hash, PartialEq)] -pub struct ExprTuple { +pub struct ExprListParenthesized { node: SyntaxNode, children: Vec, } -impl ExprTuple { +impl ExprListParenthesized { pub const INDEX_LPAREN: usize = 0; pub const INDEX_EXPRESSIONS: usize = 1; pub const INDEX_RPAREN: usize = 2; @@ -2394,16 +2396,16 @@ impl ExprTuple { lparen: TerminalLParenGreen, expressions: ExprListGreen, rparen: TerminalRParenGreen, - ) -> ExprTupleGreen { + ) -> ExprListParenthesizedGreen { let children: Vec = vec![lparen.0, expressions.0, rparen.0]; let width = children.iter().copied().map(|id| db.lookup_intern_green(id).width()).sum(); - ExprTupleGreen(db.intern_green(GreenNode { - kind: SyntaxKind::ExprTuple, + ExprListParenthesizedGreen(db.intern_green(GreenNode { + kind: SyntaxKind::ExprListParenthesized, details: GreenNodeDetails::Node { children, width }, })) } } -impl ExprTuple { +impl ExprListParenthesized { pub fn lparen(&self, db: &dyn SyntaxGroup) -> TerminalLParen { TerminalLParen::from_syntax_node(db, self.children[0].clone()) } @@ -2415,21 +2417,21 @@ impl ExprTuple { } } #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct ExprTuplePtr(pub SyntaxStablePtrId); -impl ExprTuplePtr { +pub struct ExprListParenthesizedPtr(pub SyntaxStablePtrId); +impl ExprListParenthesizedPtr { pub fn untyped(&self) -> SyntaxStablePtrId { self.0 } } #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub struct ExprTupleGreen(pub GreenId); -impl TypedSyntaxNode for ExprTuple { - const OPTIONAL_KIND: Option = Some(SyntaxKind::ExprTuple); - type StablePtr = ExprTuplePtr; - type Green = ExprTupleGreen; +pub struct ExprListParenthesizedGreen(pub GreenId); +impl TypedSyntaxNode for ExprListParenthesized { + const OPTIONAL_KIND: Option = Some(SyntaxKind::ExprListParenthesized); + type StablePtr = ExprListParenthesizedPtr; + type Green = ExprListParenthesizedGreen; fn missing(db: &dyn SyntaxGroup) -> Self::Green { - ExprTupleGreen(db.intern_green(GreenNode { - kind: SyntaxKind::ExprTuple, + ExprListParenthesizedGreen(db.intern_green(GreenNode { + kind: SyntaxKind::ExprListParenthesized, details: GreenNodeDetails::Node { children: vec![ TerminalLParen::missing(db).0, @@ -2444,10 +2446,10 @@ impl TypedSyntaxNode for ExprTuple { let kind = node.kind(db); assert_eq!( kind, - SyntaxKind::ExprTuple, + SyntaxKind::ExprListParenthesized, "Unexpected SyntaxKind {:?}. Expected {:?}.", kind, - SyntaxKind::ExprTuple + SyntaxKind::ExprListParenthesized ); let children = node.children(db).collect(); Self { node, children } @@ -2459,7 +2461,7 @@ impl TypedSyntaxNode for ExprTuple { self.node.clone() } fn stable_ptr(&self) -> Self::StablePtr { - ExprTuplePtr(self.node.0.stable_ptr) + ExprListParenthesizedPtr(self.node.0.stable_ptr) } } #[derive(Clone, Debug, Eq, Hash, PartialEq)] @@ -3778,7 +3780,7 @@ impl ExprInlineMacro { db: &dyn SyntaxGroup, path: ExprPathGreen, bang: TerminalNotGreen, - arguments: ArgListParenthesizedGreen, + arguments: WrappedExprListGreen, ) -> ExprInlineMacroGreen { let children: Vec = vec![path.0, bang.0, arguments.0]; let width = children.iter().copied().map(|id| db.lookup_intern_green(id).width()).sum(); @@ -3795,8 +3797,8 @@ impl ExprInlineMacro { pub fn bang(&self, db: &dyn SyntaxGroup) -> TerminalNot { TerminalNot::from_syntax_node(db, self.children[1].clone()) } - pub fn arguments(&self, db: &dyn SyntaxGroup) -> ArgListParenthesized { - ArgListParenthesized::from_syntax_node(db, self.children[2].clone()) + pub fn arguments(&self, db: &dyn SyntaxGroup) -> WrappedExprList { + WrappedExprList::from_syntax_node(db, self.children[2].clone()) } } #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] @@ -3819,7 +3821,7 @@ impl TypedSyntaxNode for ExprInlineMacro { children: vec![ ExprPath::missing(db).0, TerminalNot::missing(db).0, - ArgListParenthesized::missing(db).0, + WrappedExprList::missing(db).0, ], width: TextWidth::default(), }, @@ -4450,6 +4452,264 @@ impl TypedSyntaxNode for ArgListBraced { } } #[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct ExprListBracketed { + node: SyntaxNode, + children: Vec, +} +impl ExprListBracketed { + pub const INDEX_LBRACK: usize = 0; + pub const INDEX_EXPRESSIONS: usize = 1; + pub const INDEX_RBRACK: usize = 2; + pub fn new_green( + db: &dyn SyntaxGroup, + lbrack: TerminalLBrackGreen, + expressions: ExprListGreen, + rbrack: TerminalRBrackGreen, + ) -> ExprListBracketedGreen { + let children: Vec = vec![lbrack.0, expressions.0, rbrack.0]; + let width = children.iter().copied().map(|id| db.lookup_intern_green(id).width()).sum(); + ExprListBracketedGreen(db.intern_green(GreenNode { + kind: SyntaxKind::ExprListBracketed, + details: GreenNodeDetails::Node { children, width }, + })) + } +} +impl ExprListBracketed { + pub fn lbrack(&self, db: &dyn SyntaxGroup) -> TerminalLBrack { + TerminalLBrack::from_syntax_node(db, self.children[0].clone()) + } + pub fn expressions(&self, db: &dyn SyntaxGroup) -> ExprList { + ExprList::from_syntax_node(db, self.children[1].clone()) + } + pub fn rbrack(&self, db: &dyn SyntaxGroup) -> TerminalRBrack { + TerminalRBrack::from_syntax_node(db, self.children[2].clone()) + } +} +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub struct ExprListBracketedPtr(pub SyntaxStablePtrId); +impl ExprListBracketedPtr { + pub fn untyped(&self) -> SyntaxStablePtrId { + self.0 + } +} +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub struct ExprListBracketedGreen(pub GreenId); +impl TypedSyntaxNode for ExprListBracketed { + const OPTIONAL_KIND: Option = Some(SyntaxKind::ExprListBracketed); + type StablePtr = ExprListBracketedPtr; + type Green = ExprListBracketedGreen; + fn missing(db: &dyn SyntaxGroup) -> Self::Green { + ExprListBracketedGreen(db.intern_green(GreenNode { + kind: SyntaxKind::ExprListBracketed, + details: GreenNodeDetails::Node { + children: vec![ + TerminalLBrack::missing(db).0, + ExprList::missing(db).0, + TerminalRBrack::missing(db).0, + ], + width: TextWidth::default(), + }, + })) + } + fn from_syntax_node(db: &dyn SyntaxGroup, node: SyntaxNode) -> Self { + let kind = node.kind(db); + assert_eq!( + kind, + SyntaxKind::ExprListBracketed, + "Unexpected SyntaxKind {:?}. Expected {:?}.", + kind, + SyntaxKind::ExprListBracketed + ); + let children = node.children(db).collect(); + Self { node, children } + } + fn from_ptr(db: &dyn SyntaxGroup, root: &SyntaxFile, ptr: Self::StablePtr) -> Self { + Self::from_syntax_node(db, root.as_syntax_node().lookup_ptr(db, ptr.0)) + } + fn as_syntax_node(&self) -> SyntaxNode { + self.node.clone() + } + fn stable_ptr(&self) -> Self::StablePtr { + ExprListBracketedPtr(self.node.0.stable_ptr) + } +} +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct ExprListBraced { + node: SyntaxNode, + children: Vec, +} +impl ExprListBraced { + pub const INDEX_LBRACE: usize = 0; + pub const INDEX_EXPRESSIONS: usize = 1; + pub const INDEX_RBRACE: usize = 2; + pub fn new_green( + db: &dyn SyntaxGroup, + lbrace: TerminalLBraceGreen, + expressions: ExprListGreen, + rbrace: TerminalRBraceGreen, + ) -> ExprListBracedGreen { + let children: Vec = vec![lbrace.0, expressions.0, rbrace.0]; + let width = children.iter().copied().map(|id| db.lookup_intern_green(id).width()).sum(); + ExprListBracedGreen(db.intern_green(GreenNode { + kind: SyntaxKind::ExprListBraced, + details: GreenNodeDetails::Node { children, width }, + })) + } +} +impl ExprListBraced { + pub fn lbrace(&self, db: &dyn SyntaxGroup) -> TerminalLBrace { + TerminalLBrace::from_syntax_node(db, self.children[0].clone()) + } + pub fn expressions(&self, db: &dyn SyntaxGroup) -> ExprList { + ExprList::from_syntax_node(db, self.children[1].clone()) + } + pub fn rbrace(&self, db: &dyn SyntaxGroup) -> TerminalRBrace { + TerminalRBrace::from_syntax_node(db, self.children[2].clone()) + } +} +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub struct ExprListBracedPtr(pub SyntaxStablePtrId); +impl ExprListBracedPtr { + pub fn untyped(&self) -> SyntaxStablePtrId { + self.0 + } +} +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub struct ExprListBracedGreen(pub GreenId); +impl TypedSyntaxNode for ExprListBraced { + const OPTIONAL_KIND: Option = Some(SyntaxKind::ExprListBraced); + type StablePtr = ExprListBracedPtr; + type Green = ExprListBracedGreen; + fn missing(db: &dyn SyntaxGroup) -> Self::Green { + ExprListBracedGreen(db.intern_green(GreenNode { + kind: SyntaxKind::ExprListBraced, + details: GreenNodeDetails::Node { + children: vec![ + TerminalLBrace::missing(db).0, + ExprList::missing(db).0, + TerminalRBrace::missing(db).0, + ], + width: TextWidth::default(), + }, + })) + } + fn from_syntax_node(db: &dyn SyntaxGroup, node: SyntaxNode) -> Self { + let kind = node.kind(db); + assert_eq!( + kind, + SyntaxKind::ExprListBraced, + "Unexpected SyntaxKind {:?}. Expected {:?}.", + kind, + SyntaxKind::ExprListBraced + ); + let children = node.children(db).collect(); + Self { node, children } + } + fn from_ptr(db: &dyn SyntaxGroup, root: &SyntaxFile, ptr: Self::StablePtr) -> Self { + Self::from_syntax_node(db, root.as_syntax_node().lookup_ptr(db, ptr.0)) + } + fn as_syntax_node(&self) -> SyntaxNode { + self.node.clone() + } + fn stable_ptr(&self) -> Self::StablePtr { + ExprListBracedPtr(self.node.0.stable_ptr) + } +} +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub enum WrappedExprList { + BracketedExprList(ExprListBracketed), + ParenthesizedExprList(ExprListParenthesized), + BracedExprList(ExprListBraced), +} +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub struct WrappedExprListPtr(pub SyntaxStablePtrId); +impl WrappedExprListPtr { + pub fn untyped(&self) -> SyntaxStablePtrId { + self.0 + } +} +impl From for WrappedExprListPtr { + fn from(value: ExprListBracketedPtr) -> Self { + Self(value.0) + } +} +impl From for WrappedExprListPtr { + fn from(value: ExprListParenthesizedPtr) -> Self { + Self(value.0) + } +} +impl From for WrappedExprListPtr { + fn from(value: ExprListBracedPtr) -> Self { + Self(value.0) + } +} +impl From for WrappedExprListGreen { + fn from(value: ExprListBracketedGreen) -> Self { + Self(value.0) + } +} +impl From for WrappedExprListGreen { + fn from(value: ExprListParenthesizedGreen) -> Self { + Self(value.0) + } +} +impl From for WrappedExprListGreen { + fn from(value: ExprListBracedGreen) -> Self { + Self(value.0) + } +} +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub struct WrappedExprListGreen(pub GreenId); +impl TypedSyntaxNode for WrappedExprList { + const OPTIONAL_KIND: Option = None; + type StablePtr = WrappedExprListPtr; + type Green = WrappedExprListGreen; + fn missing(db: &dyn SyntaxGroup) -> Self::Green { + panic!("No missing variant."); + } + fn from_syntax_node(db: &dyn SyntaxGroup, node: SyntaxNode) -> Self { + let kind = node.kind(db); + match kind { + SyntaxKind::ExprListBracketed => { + WrappedExprList::BracketedExprList(ExprListBracketed::from_syntax_node(db, node)) + } + SyntaxKind::ExprListParenthesized => WrappedExprList::ParenthesizedExprList( + ExprListParenthesized::from_syntax_node(db, node), + ), + SyntaxKind::ExprListBraced => { + WrappedExprList::BracedExprList(ExprListBraced::from_syntax_node(db, node)) + } + _ => { + panic!("Unexpected syntax kind {:?} when constructing {}.", kind, "WrappedExprList") + } + } + } + fn as_syntax_node(&self) -> SyntaxNode { + match self { + WrappedExprList::BracketedExprList(x) => x.as_syntax_node(), + WrappedExprList::ParenthesizedExprList(x) => x.as_syntax_node(), + WrappedExprList::BracedExprList(x) => x.as_syntax_node(), + } + } + fn from_ptr(db: &dyn SyntaxGroup, root: &SyntaxFile, ptr: Self::StablePtr) -> Self { + Self::from_syntax_node(db, root.as_syntax_node().lookup_ptr(db, ptr.0)) + } + fn stable_ptr(&self) -> Self::StablePtr { + WrappedExprListPtr(self.as_syntax_node().0.stable_ptr) + } +} +impl WrappedExprList { + #[allow(clippy::match_like_matches_macro)] + pub fn is_variant(kind: SyntaxKind) -> bool { + match kind { + SyntaxKind::ExprListBracketed => true, + SyntaxKind::ExprListParenthesized => true, + SyntaxKind::ExprListBraced => true, + _ => false, + } + } +} +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum Pattern { Underscore(TerminalUnderscore), Literal(TerminalLiteralNumber), diff --git a/crates/cairo-lang-syntax/src/node/key_fields.rs b/crates/cairo-lang-syntax/src/node/key_fields.rs index e227427b882..e3232d72e1f 100644 --- a/crates/cairo-lang-syntax/src/node/key_fields.rs +++ b/crates/cairo-lang-syntax/src/node/key_fields.rs @@ -46,7 +46,7 @@ pub fn get_key_fields(kind: SyntaxKind, children: Vec) -> Vec SyntaxKind::ExprBinary => { vec![] } - SyntaxKind::ExprTuple => { + SyntaxKind::ExprListParenthesized => { vec![] } SyntaxKind::ExprFunctionCall => { @@ -108,6 +108,12 @@ pub fn get_key_fields(kind: SyntaxKind, children: Vec) -> Vec SyntaxKind::ArgListBraced => { vec![] } + SyntaxKind::ExprListBracketed => { + vec![] + } + SyntaxKind::ExprListBraced => { + vec![] + } SyntaxKind::PatternIdentifier => { vec![/* name */ children[1]] } diff --git a/crates/cairo-lang-syntax/src/node/kind.rs b/crates/cairo-lang-syntax/src/node/kind.rs index d9795f63492..5c008bdc711 100644 --- a/crates/cairo-lang-syntax/src/node/kind.rs +++ b/crates/cairo-lang-syntax/src/node/kind.rs @@ -18,7 +18,7 @@ pub enum SyntaxKind { ExprParenthesized, ExprUnary, ExprBinary, - ExprTuple, + ExprListParenthesized, ExprFunctionCall, ArgListParenthesized, OptionArgListParenthesizedEmpty, @@ -40,6 +40,8 @@ pub enum SyntaxKind { StructArgTail, StructArgList, ArgListBraced, + ExprListBracketed, + ExprListBraced, PatternIdentifier, PatternStruct, PatternStructParamList,