diff --git a/crates/aiken-lang/src/format.rs b/crates/aiken-lang/src/format.rs index ef7f9202..041c6049 100644 --- a/crates/aiken-lang/src/format.rs +++ b/crates/aiken-lang/src/format.rs @@ -424,7 +424,14 @@ impl<'comments> Formatter<'comments> { Annotation::Tuple { elems, .. } => { wrap_args(elems.iter().map(|t| (self.annotation(t), false))) } - Annotation::Pair { .. } => todo!(), + Annotation::Pair { fst, snd, .. } => "Pair" + .to_doc() + .append("<") + .append(self.annotation(fst)) + .append(break_(",", ", ")) + .append(self.annotation(snd)) + .append(">") + .group(), } .group() } diff --git a/crates/aiken-lang/src/parser/annotation.rs b/crates/aiken-lang/src/parser/annotation.rs index 8afdac55..148947e5 100644 --- a/crates/aiken-lang/src/parser/annotation.rs +++ b/crates/aiken-lang/src/parser/annotation.rs @@ -1,8 +1,9 @@ -use chumsky::prelude::*; - -use crate::ast; - use super::{error::ParseError, token::Token}; +use crate::{ + ast, + builtins::{PAIR, PRELUDE}, +}; +use chumsky::prelude::*; pub fn parser() -> impl Parser { recursive(|expression| { @@ -14,6 +15,31 @@ pub fn parser() -> impl Parser { name, } }), + // Pair + select! {Token::Name { name } if name == PRELUDE => name} + .then_ignore(just(Token::Dot)) + .or_not() + .then_ignore(select! {Token::UpName { name } if name == PAIR => name}) + .ignore_then( + expression + .clone() + .separated_by(just(Token::Comma)) + .exactly(2) + .delimited_by(just(Token::Less), just(Token::Greater)), + ) + .map_with_span(|elems: Vec, span| ast::Annotation::Pair { + location: span, + fst: elems + .first() + .expect("Pair should have exactly 2 elements") + .to_owned() + .into(), + snd: elems + .last() + .expect("Pair should have exactly 2 elements") + .to_owned() + .into(), + }), // Tuple expression .clone() diff --git a/crates/aiken-lang/src/tests/format.rs b/crates/aiken-lang/src/tests/format.rs index 1649a7e5..2b4162dd 100644 --- a/crates/aiken-lang/src/tests/format.rs +++ b/crates/aiken-lang/src/tests/format.rs @@ -792,3 +792,13 @@ fn superfluous_parens_in_binop() { "# ); } + +#[test] +fn format_pairs() { + assert_format!( + r#" + pub fn foo(x: Pair) { + Pair(x.1st, x.2nd) + }"# + ); +} diff --git a/crates/aiken-lang/src/tests/snapshots/format_pairs.snap b/crates/aiken-lang/src/tests/snapshots/format_pairs.snap new file mode 100644 index 00000000..2b4d6277 --- /dev/null +++ b/crates/aiken-lang/src/tests/snapshots/format_pairs.snap @@ -0,0 +1,7 @@ +--- +source: crates/aiken-lang/src/tests/format.rs +description: "Code:\n\npub fn foo(x: Pair) {\n Pair(x.1st, x.2nd)\n}" +--- +pub fn foo(x: Pair) { + Pair(x.1st, x.2nd) +}