diff --git a/crates/aiken-lang/src/parser/expr/and_or_chain.rs b/crates/aiken-lang/src/parser/expr/and_or_chain.rs new file mode 100644 index 00000000..f50a540a --- /dev/null +++ b/crates/aiken-lang/src/parser/expr/and_or_chain.rs @@ -0,0 +1,72 @@ +use chumsky::prelude::*; + +use crate::{ + ast::LogicalOpChainKind, + expr::UntypedExpr, + parser::{error::ParseError, token::Token}, +}; + +pub fn parser( + expression: Recursive<'_, Token, UntypedExpr, ParseError>, +) -> impl Parser + '_ { + choice(( + just(Token::And).to(LogicalOpChainKind::And), + just(Token::Or).to(LogicalOpChainKind::Or), + )) + .then( + expression + .separated_by(just(Token::Comma)) + .allow_trailing() + .delimited_by(just(Token::LeftBrace), just(Token::RightBrace)), + ) + .map_with_span(|(kind, exprs), span| UntypedExpr::LogicalOpChain { + kind, + expressions: exprs, + location: span, + }) +} + +#[cfg(test)] +mod tests { + use crate::assert_expr; + + #[test] + fn and_chain() { + assert_expr!( + r#" + and { + 1 == 2, + something, + } + "# + ); + } + + #[test] + fn or_chain() { + assert_expr!( + r#" + or { + 1 == 2, + something, + } + "# + ); + } + + #[test] + fn and_or_chain() { + assert_expr!( + r#" + or { + 1 == 2, + something, + and { + 1 == 2, + something, + }, + } + "# + ); + } +} diff --git a/crates/aiken-lang/src/parser/expr/snapshots/and_chain.snap b/crates/aiken-lang/src/parser/expr/snapshots/and_chain.snap new file mode 100644 index 00000000..5c59e349 --- /dev/null +++ b/crates/aiken-lang/src/parser/expr/snapshots/and_chain.snap @@ -0,0 +1,32 @@ +--- +source: crates/aiken-lang/src/parser/expr/and_or_chain.rs +description: "Code:\n\nand {\n 1 == 2,\n something,\n}\n" +--- +LogicalOpChain { + kind: And, + expressions: [ + BinOp { + location: 8..14, + name: Eq, + left: UInt { + location: 8..9, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + right: UInt { + location: 13..14, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + Var { + location: 18..27, + name: "something", + }, + ], + location: 0..30, +} diff --git a/crates/aiken-lang/src/parser/expr/snapshots/and_or_chain.snap b/crates/aiken-lang/src/parser/expr/snapshots/and_or_chain.snap new file mode 100644 index 00000000..53961811 --- /dev/null +++ b/crates/aiken-lang/src/parser/expr/snapshots/and_or_chain.snap @@ -0,0 +1,60 @@ +--- +source: crates/aiken-lang/src/parser/expr/and_or_chain.rs +description: "Code:\n\nor {\n 1 == 2,\n something,\n and {\n 1 == 2,\n something,\n },\n}\n" +--- +LogicalOpChain { + kind: Or, + expressions: [ + BinOp { + location: 7..13, + name: Eq, + left: UInt { + location: 7..8, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + right: UInt { + location: 12..13, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + Var { + location: 17..26, + name: "something", + }, + LogicalOpChain { + kind: And, + expressions: [ + BinOp { + location: 40..46, + name: Eq, + left: UInt { + location: 40..41, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + right: UInt { + location: 45..46, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + Var { + location: 52..61, + name: "something", + }, + ], + location: 30..66, + }, + ], + location: 0..69, +} diff --git a/crates/aiken-lang/src/parser/expr/snapshots/or_chain.snap b/crates/aiken-lang/src/parser/expr/snapshots/or_chain.snap new file mode 100644 index 00000000..ebdd4a59 --- /dev/null +++ b/crates/aiken-lang/src/parser/expr/snapshots/or_chain.snap @@ -0,0 +1,32 @@ +--- +source: crates/aiken-lang/src/parser/expr/and_or_chain.rs +description: "Code:\n\nor {\n 1 == 2,\n something,\n}\n" +--- +LogicalOpChain { + kind: Or, + expressions: [ + BinOp { + location: 7..13, + name: Eq, + left: UInt { + location: 7..8, + value: "1", + base: Decimal { + numeric_underscore: false, + }, + }, + right: UInt { + location: 12..13, + value: "2", + base: Decimal { + numeric_underscore: false, + }, + }, + }, + Var { + location: 17..26, + name: "something", + }, + ], + location: 0..29, +}