aiken_lang/parser/expr/
block.rs1use 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}