datex_core/parser/parsers/
map.rs1use 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}