aiken_lang/parser/expr/
pair.rs1use crate::{
2 ast::well_known,
3 builtins::PRELUDE,
4 expr::UntypedExpr,
5 parser::{error::ParseError, token::Token},
6};
7use chumsky::prelude::*;
8
9pub fn parser(
10 r: Recursive<'_, Token, UntypedExpr, ParseError>,
11) -> impl Parser<Token, UntypedExpr, Error = ParseError> + '_ {
12 select! {Token::Name { name } if name == PRELUDE => name}
13 .then_ignore(just(Token::Dot))
14 .or_not()
15 .then_ignore(select! {Token::UpName { name } if name == well_known::PAIR => name})
16 .ignore_then(
17 r.clone()
18 .separated_by(just(Token::Comma))
19 .exactly(2)
20 .allow_trailing()
21 .delimited_by(
22 choice((just(Token::LeftParen), just(Token::NewLineLeftParen))),
23 just(Token::RightParen),
24 )
25 .map_with_span(|elems, location| UntypedExpr::Pair {
26 location,
27 fst: elems
28 .first()
29 .expect("Pair should have exactly 2 elements")
30 .to_owned()
31 .into(),
32 snd: elems
33 .last()
34 .expect("Pair should have exactly 2 elements")
35 .to_owned()
36 .into(),
37 }),
38 )
39}
40
41#[cfg(test)]
42mod tests {
43 use crate::assert_expr;
44
45 #[test]
46 fn basic_pair() {
47 assert_expr!(r#"Pair(1, 2)"#);
48 }
49
50 #[test]
51 fn pair_from_prelude() {
52 assert_expr!(r#"aiken.Pair(1, 2)"#);
53 }
54}