Skip to main content

aiken_lang/parser/expr/
list.rs

1use chumsky::prelude::*;
2
3use crate::{
4    expr::UntypedExpr,
5    parser::{error::ParseError, token::Token},
6};
7
8pub fn parser(
9    expression: Recursive<'_, Token, UntypedExpr, ParseError>,
10) -> impl Parser<Token, UntypedExpr, Error = ParseError> + '_ {
11    just(Token::LeftSquare)
12        .ignore_then(expression.clone().separated_by(just(Token::Comma)))
13        .then(choice((
14            just(Token::Comma).ignore_then(
15                just(Token::DotDot)
16                    .ignore_then(expression)
17                    .map(Box::new)
18                    .or_not(),
19            ),
20            just(Token::Comma).ignored().or_not().map(|_| None),
21        )))
22        .then_ignore(just(Token::RightSquare))
23        // TODO: check if tail.is_some and elements.is_empty then return ListSpreadWithoutElements error
24        .map_with_span(|(elements, tail), span| UntypedExpr::List {
25            location: span,
26            elements,
27            tail,
28        })
29}
30
31#[cfg(test)]
32mod tests {
33    use crate::assert_expr;
34
35    #[test]
36    fn empty_list() {
37        assert_expr!("[]");
38    }
39
40    #[test]
41    fn int_list() {
42        assert_expr!("[1, 2, 3]");
43    }
44
45    #[test]
46    fn list_spread() {
47        assert_expr!("[1, 2, ..[]]");
48    }
49}