From 1ae6640cd0fcd4fae5903545ccdfda564d4c7a7e Mon Sep 17 00:00:00 2001 From: KtorZ Date: Tue, 6 Aug 2024 11:31:11 +0200 Subject: [PATCH] Make alternative clause parser more flexible. The spirit here is to make it easier to discover this syntax. People have different intuition about it and the single pipe may not be the most obvious one. It is however the recommended syntax, and the formatter will rewrite any of the other to it. --- .../aiken-lang/src/parser/expr/when/clause.rs | 26 ++- .../snapshots/when_clause_alternative.snap | 177 ++++++++++++++++++ crates/aiken-project/src/lib.rs | 4 + 3 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 crates/aiken-lang/src/parser/expr/when/snapshots/when_clause_alternative.snap diff --git a/crates/aiken-lang/src/parser/expr/when/clause.rs b/crates/aiken-lang/src/parser/expr/when/clause.rs index 4eaf09f9..262f8e49 100644 --- a/crates/aiken-lang/src/parser/expr/when/clause.rs +++ b/crates/aiken-lang/src/parser/expr/when/clause.rs @@ -11,7 +11,17 @@ pub fn parser( expression: Recursive<'_, Token, UntypedExpr, ParseError>, ) -> impl Parser + '_ { pattern() - .then(just(Token::Vbar).ignore_then(pattern()).repeated().or_not()) + .then( + choice(( + just(Token::Vbar), + just(Token::VbarVbar), + just(Token::Or), + just(Token::Comma), + )) + .ignore_then(pattern()) + .repeated() + .or_not(), + ) .then(choice((just(Token::If) .ignore_then(guard()) .or_not() @@ -76,4 +86,18 @@ mod tests { "# ); } + + #[test] + fn when_clause_alternative() { + assert_expr!( + r#" + when val is { + Bar1{..} | Bar2{..} -> todo + Bar3{..} || Bar4{..} -> todo + Bar5{..} or Bar6{..} -> todo + Bar5{..}, Bar6{..} -> todo + } + "# + ); + } } diff --git a/crates/aiken-lang/src/parser/expr/when/snapshots/when_clause_alternative.snap b/crates/aiken-lang/src/parser/expr/when/snapshots/when_clause_alternative.snap new file mode 100644 index 00000000..7c3245a8 --- /dev/null +++ b/crates/aiken-lang/src/parser/expr/when/snapshots/when_clause_alternative.snap @@ -0,0 +1,177 @@ +--- +source: crates/aiken-lang/src/parser/expr/when/clause.rs +description: "Code:\n\nwhen val is {\n Bar1{..} | Bar2{..} -> todo\n Bar3{..} || Bar4{..} -> todo\n Bar5{..} or Bar6{..} -> todo\n Bar5{..}, Bar6{..} -> todo\n}\n" +--- +When { + location: 0..136, + subject: Var { + location: 5..8, + name: "val", + }, + clauses: [ + UntypedClause { + location: 16..43, + patterns: [ + Constructor { + is_record: true, + location: 16..24, + name: "Bar1", + arguments: [], + module: None, + constructor: (), + spread_location: Some( + 21..23, + ), + tipo: (), + }, + Constructor { + is_record: true, + location: 27..35, + name: "Bar2", + arguments: [], + module: None, + constructor: (), + spread_location: Some( + 32..34, + ), + tipo: (), + }, + ], + then: Trace { + kind: Todo, + location: 39..43, + then: ErrorTerm { + location: 39..43, + }, + label: String { + location: 39..43, + value: "aiken::todo", + }, + arguments: [], + }, + }, + UntypedClause { + location: 46..74, + patterns: [ + Constructor { + is_record: true, + location: 46..54, + name: "Bar3", + arguments: [], + module: None, + constructor: (), + spread_location: Some( + 51..53, + ), + tipo: (), + }, + Constructor { + is_record: true, + location: 58..66, + name: "Bar4", + arguments: [], + module: None, + constructor: (), + spread_location: Some( + 63..65, + ), + tipo: (), + }, + ], + then: Trace { + kind: Todo, + location: 70..74, + then: ErrorTerm { + location: 70..74, + }, + label: String { + location: 70..74, + value: "aiken::todo", + }, + arguments: [], + }, + }, + UntypedClause { + location: 77..105, + patterns: [ + Constructor { + is_record: true, + location: 77..85, + name: "Bar5", + arguments: [], + module: None, + constructor: (), + spread_location: Some( + 82..84, + ), + tipo: (), + }, + Constructor { + is_record: true, + location: 89..97, + name: "Bar6", + arguments: [], + module: None, + constructor: (), + spread_location: Some( + 94..96, + ), + tipo: (), + }, + ], + then: Trace { + kind: Todo, + location: 101..105, + then: ErrorTerm { + location: 101..105, + }, + label: String { + location: 101..105, + value: "aiken::todo", + }, + arguments: [], + }, + }, + UntypedClause { + location: 108..134, + patterns: [ + Constructor { + is_record: true, + location: 108..116, + name: "Bar5", + arguments: [], + module: None, + constructor: (), + spread_location: Some( + 113..115, + ), + tipo: (), + }, + Constructor { + is_record: true, + location: 118..126, + name: "Bar6", + arguments: [], + module: None, + constructor: (), + spread_location: Some( + 123..125, + ), + tipo: (), + }, + ], + then: Trace { + kind: Todo, + location: 130..134, + then: ErrorTerm { + location: 130..134, + }, + label: String { + location: 130..134, + value: "aiken::todo", + }, + arguments: [], + }, + }, + ], +} diff --git a/crates/aiken-project/src/lib.rs b/crates/aiken-project/src/lib.rs index 1ffc6160..5e6bd222 100644 --- a/crates/aiken-project/src/lib.rs +++ b/crates/aiken-project/src/lib.rs @@ -812,6 +812,10 @@ where &mut self.data_types, )?; + if name == "foo" { + println!("{:#?}", checked_module.ast); + } + if our_modules.contains(checked_module.name.as_str()) { self.warnings.extend(warnings); }