datex_core/parser/parsers/
map.rs

1use crate::ast::expressions::{DatexExpression, DatexExpressionData, Map};
2use crate::ast::spanned::Spanned;
3use crate::parser::lexer::Token;
4use crate::parser::{Parser, SpannedParserError};
5
6impl Parser {
7    pub fn parse_map(&mut self) -> Result<DatexExpression, SpannedParserError> {
8        let start = self.expect(Token::LeftCurly)?.span.start;
9        let mut entries = Vec::new();
10
11        while self.peek()?.token != Token::RightCurly {
12            let key = self.parse_key()?;
13            self.expect(Token::Colon)?;
14            let value = self.parse_expression(0)?;
15            entries.push((key, value));
16
17            if self.peek()?.token == Token::Comma {
18                self.advance()?;
19            }
20        }
21        let end = self.expect(Token::RightCurly)?.span.end;
22        Ok(DatexExpressionData::Map(Map { entries }).with_span(start..end))
23    }
24}
25
26#[cfg(test)]
27mod tests {
28    use crate::ast::expressions::BinaryOperation;
29    use crate::ast::expressions::{DatexExpressionData, Map};
30    use crate::ast::spanned::Spanned;
31    use crate::global::operators::BinaryOperator;
32    use crate::global::operators::binary::ArithmeticOperator;
33    use crate::parser::tests::{parse, try_parse_and_return_on_first_error};
34
35    #[test]
36    fn parse_empty_map() {
37        let expr = parse("{}");
38        assert_eq!(
39            expr.data,
40            DatexExpressionData::Map(Map { entries: vec![] })
41        );
42    }
43
44    #[test]
45    fn parse_simple_map() {
46        let expr = parse("{'key1': true, 'key2': false}");
47        assert_eq!(
48            expr.data,
49            DatexExpressionData::Map(Map {
50                entries: vec![
51                    (
52                        DatexExpressionData::Text("key1".to_string())
53                            .with_default_span(),
54                        DatexExpressionData::Boolean(true).with_default_span()
55                    ),
56                    (
57                        DatexExpressionData::Text("key2".to_string())
58                            .with_default_span(),
59                        DatexExpressionData::Boolean(false).with_default_span()
60                    ),
61                ]
62            })
63        );
64    }
65
66    #[test]
67    fn parse_map_with_plain_identifier_keys() {
68        let expr = parse("{key1: true, key2: false}");
69        assert_eq!(
70            expr.data,
71            DatexExpressionData::Map(Map {
72                entries: vec![
73                    (
74                        DatexExpressionData::Text("key1".to_string())
75                            .with_default_span(),
76                        DatexExpressionData::Boolean(true).with_default_span()
77                    ),
78                    (
79                        DatexExpressionData::Text("key2".to_string())
80                            .with_default_span(),
81                        DatexExpressionData::Boolean(false).with_default_span()
82                    ),
83                ]
84            })
85        );
86    }
87
88    #[test]
89    fn parse_map_with_reserved_keyword_keys() {
90        let expr = parse("{if: true, type: false}");
91        assert_eq!(
92            expr.data,
93            DatexExpressionData::Map(Map {
94                entries: vec![
95                    (
96                        DatexExpressionData::Text("if".to_string())
97                            .with_default_span(),
98                        DatexExpressionData::Boolean(true).with_default_span()
99                    ),
100                    (
101                        DatexExpressionData::Text("type".to_string())
102                            .with_default_span(),
103                        DatexExpressionData::Boolean(false).with_default_span()
104                    ),
105                ]
106            })
107        );
108    }
109
110    #[test]
111    fn parse_map_with_dynamic_expression_keys() {
112        let expr = parse("{(x): true, (y + true): false}");
113        assert_eq!(
114            expr.data,
115            DatexExpressionData::Map(Map {
116                entries: vec![
117                    (
118                        DatexExpressionData::Identifier("x".to_string())
119                            .with_default_span(),
120                        DatexExpressionData::Boolean(true).with_default_span()
121                    ),
122                    (
123                        DatexExpressionData::BinaryOperation(BinaryOperation {
124                            left: Box::new(
125                                DatexExpressionData::Identifier(
126                                    "y".to_string()
127                                )
128                                .with_default_span()
129                            ),
130                            operator: BinaryOperator::Arithmetic(
131                                ArithmeticOperator::Add
132                            ),
133                            right: Box::new(
134                                DatexExpressionData::Boolean(true)
135                                    .with_default_span()
136                            ),
137                            ty: None,
138                        })
139                        .with_default_span(),
140                        DatexExpressionData::Boolean(false).with_default_span()
141                    ),
142                ]
143            })
144        );
145    }
146}