Skip to main content

aiken_lang/parser/expr/
block.rs

1use chumsky::prelude::*;
2
3use crate::{
4    expr::UntypedExpr,
5    parser::{error::ParseError, token::Token},
6};
7
8pub fn parser(
9    sequence: Recursive<'_, Token, UntypedExpr, ParseError>,
10) -> impl Parser<Token, UntypedExpr, Error = ParseError> + '_ {
11    choice((
12        sequence
13            .clone()
14            .delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
15        sequence.clone().delimited_by(
16            choice((just(Token::LeftParen), just(Token::NewLineLeftParen))),
17            just(Token::RightParen),
18        ),
19    ))
20    .map_with_span(|e, span| {
21        if matches!(e, UntypedExpr::Assignment { .. }) {
22            UntypedExpr::Sequence {
23                location: span,
24                expressions: vec![e],
25            }
26        } else {
27            e
28        }
29    })
30}
31
32#[cfg(test)]
33mod tests {
34    use crate::{assert_definition, assert_expr};
35
36    #[test]
37    fn block_let() {
38        assert_expr!(
39            r#"
40            let b = {
41              let x = 4
42              x + 5
43            }
44            "#
45        );
46    }
47
48    #[test]
49    fn block_single() {
50        assert_expr!(
51            r#"{
52            foo
53            }
54            "#
55        );
56    }
57
58    #[test]
59    fn sequence_then_expr() {
60        assert_definition!(
61            r#"
62            test foo() {
63              {
64                let a = Void
65                a
66              }
67              True
68            }
69            "#
70        );
71    }
72
73    #[test]
74    fn sequence_then_sequence() {
75        assert_definition!(
76            r#"
77            test foo() {
78              {
79                let a = Void
80                a
81              }
82              let _ = True
83              True
84            }
85            "#
86        );
87    }
88}