dpscript/
macros.rs

1#[macro_export]
2macro_rules! check_token {
3    ($cursor: ident => $var: ident[$n: expr] == $tkn: ident) => {{
4        let it = $var.get($n);
5
6        if let Some((token, span)) = it {
7            if token.clone() != $crate::Token::$tkn {
8                return Err($crate::LexerError {
9                    src: $cursor.source(),
10                    at: span.clone(),
11                    err: format!(
12                        "Unexpected token: {} (expected: {})",
13                        token,
14                        $crate::Token::$tkn
15                    ),
16                }
17                .into());
18            }
19        }
20
21        it
22    }};
23
24    (data $cursor: ident => $var: ident[$n: expr] == $tkn: ident) => {{
25        let it = $var.get($n);
26
27        if let Some((token, span)) = it {
28            if let $crate::Token::$tkn(_) = token {
29            } else {
30                return Err($crate::LexerError {
31                    src: $cursor.source(),
32                    at: span.clone(),
33                    err: format!("Unexpected token: {}", token),
34                }
35                .into());
36            }
37        }
38
39        it
40    }};
41
42    (remove $cursor: ident => $var: ident[$n: expr] == $tkn: ident) => {{
43        let it = $var.get($n);
44
45        if let Some((token, span)) = it {
46            if token.clone() != $crate::Token::$tkn {
47                return Err($crate::LexerError {
48                    src: $cursor.source(),
49                    at: span.clone(),
50                    err: format!(
51                        "Unexpected token: {} (expected: {})",
52                        token,
53                        $crate::Token::$tkn
54                    ),
55                }
56                .into());
57            }
58        }
59
60        $var.remove($n)
61    }};
62
63    ($cursor: ident => $tkn: ident == $expected: ident) => {{
64        if $tkn.0 != $crate::Token::$expected {
65            return Err($crate::LexerError {
66                src: $cursor.source(),
67                at: $tkn.1.clone(),
68                err: format!(
69                    "Unexpected token: {} (expected: {})",
70                    $tkn.0,
71                    $crate::Token::$expected
72                ),
73            }
74            .into());
75        }
76    }};
77
78    (data $cursor: ident == $tkn: ident) => {{
79        let it = $cursor.peek();
80
81        if let Some((token, span)) = it {
82            if let $crate::Token::$tkn(_) = token {
83            } else {
84                return Err($crate::LexerError {
85                    src: $cursor.source(),
86                    at: span.clone(),
87                    err: format!("Unexpected token: {}", token),
88                }
89                .into());
90            }
91        }
92
93        it
94    }};
95
96    ($cursor: ident == $tkn: ident) => {{
97        let it = $cursor.peek();
98
99        if let Some((token, span)) = it.clone() {
100            if token != $crate::Token::$tkn {
101                return Err($crate::LexerError {
102                    src: $cursor.source(),
103                    at: span.clone(),
104                    err: format!(
105                        "Unexpected token: {} (expected: {})",
106                        token,
107                        $crate::Token::$tkn
108                    ),
109                }
110                .into());
111            }
112        }
113
114        it
115    }};
116
117    (remove $cursor: ident == $tkn: ident) => {{
118        let it = $cursor.next();
119
120        if let Some((token, span)) = it.clone() {
121            if token != $crate::Token::$tkn {
122                return Err($crate::LexerError {
123                    src: $cursor.source(),
124                    at: span.clone(),
125                    err: format!(
126                        "Unexpected token: {} (expected: {})",
127                        token,
128                        $crate::Token::$tkn
129                    ),
130                }
131                .into());
132            }
133        }
134
135        it
136    }};
137
138    (data $cursor: ident => $tkn: ident == $expected: ident) => {{
139        if let $crate::Token::$expected(_) = $tkn.0 {
140        } else {
141            return Err($crate::LexerError {
142                src: $cursor.source(),
143                at: $tkn.1.clone(),
144                err: format!("Unexpected token: {}", $tkn.0),
145            }
146            .into());
147        }
148    }};
149}
150
151#[macro_export]
152macro_rules! check_ir_token {
153    ($cursor: ident => $var: ident[$n: expr] == $tkn: ident) => {{
154        let it = $var.get($n);
155
156        if let Some((token, span)) = it {
157            if token.clone() != $crate::IRToken::$tkn {
158                return Err($crate::IRLexerError {
159                    src: $cursor.source(),
160                    at: span.clone(),
161                    err: format!(
162                        "Unexpected token: {} (expected: {})",
163                        token,
164                        $crate::IRToken::$tkn
165                    ),
166                }
167                .into());
168            }
169        }
170
171        it
172    }};
173
174    (data $cursor: ident => $var: ident[$n: expr] == $tkn: ident) => {{
175        let it = $var.get($n);
176
177        if let Some((token, span)) = it {
178            if let $crate::IRToken::$tkn(_) = token {
179            } else {
180                return Err($crate::IRLexerError {
181                    src: $cursor.source(),
182                    at: span.clone(),
183                    err: format!("Unexpected token: {}", token),
184                }
185                .into());
186            }
187        }
188
189        it
190    }};
191
192    (remove $cursor: ident => $var: ident[$n: expr] == $tkn: ident) => {{
193        let it = $var.get($n);
194
195        if let Some((token, span)) = it {
196            if token.clone() != $crate::IRToken::$tkn {
197                return Err($crate::IRLexerError {
198                    src: $cursor.source(),
199                    at: span.clone(),
200                    err: format!(
201                        "Unexpected token: {} (expected: {})",
202                        token,
203                        $crate::IRToken::$tkn
204                    ),
205                }
206                .into());
207            }
208        }
209
210        $var.remove($n)
211    }};
212
213    ($cursor: ident => $tkn: ident == $expected: ident) => {{
214        if $tkn.0 != $crate::IRToken::$expected {
215            return Err($crate::IRLexerError {
216                src: $cursor.source(),
217                at: $tkn.1.clone(),
218                err: format!(
219                    "Unexpected token: {} (expected: {})",
220                    $tkn.0,
221                    $crate::IRToken::$expected
222                ),
223            }
224            .into());
225        }
226    }};
227
228    (data $cursor: ident == $tkn: ident) => {{
229        let it = $cursor.peek();
230
231        if let Some((token, span)) = it {
232            if let $crate::IRToken::$tkn(_) = token {
233            } else {
234                return Err($crate::IRLexerError {
235                    src: $cursor.source(),
236                    at: span.clone(),
237                    err: format!("Unexpected token: {}", token),
238                }
239                .into());
240            }
241        }
242
243        it
244    }};
245
246    ($cursor: ident == $tkn: ident) => {{
247        let it = $cursor.peek();
248
249        if let Some((token, span)) = it.clone() {
250            if token != $crate::IRToken::$tkn {
251                return Err($crate::IRLexerError {
252                    src: $cursor.source(),
253                    at: span.clone(),
254                    err: format!(
255                        "Unexpected token: {} (expected: {})",
256                        token,
257                        $crate::IRToken::$tkn
258                    ),
259                }
260                .into());
261            }
262        }
263
264        it
265    }};
266
267    (remove $cursor: ident == $tkn: ident) => {{
268        let it = $cursor.next();
269
270        if let Some((token, span)) = it.clone() {
271            if token != $crate::IRToken::$tkn {
272                return Err($crate::UnnamedLexerError {
273                    src: $cursor.source(),
274                    at: span.clone(),
275                    err: format!(
276                        "Unexpected token: {} (expected: {})",
277                        token,
278                        $crate::IRToken::$tkn
279                    ),
280                }
281                .into());
282            }
283        }
284
285        it
286    }};
287
288    (data $cursor: ident => $tkn: ident == $expected: ident) => {{
289        if let $crate::IRToken::$expected(_) = $tkn.0 {
290        } else {
291            return Err($crate::IRLexerError {
292                src: $cursor.source(),
293                at: $tkn.1.clone(),
294                err: format!("Unexpected token: {}", $tkn.0),
295            }
296            .into());
297        }
298    }};
299}
300
301#[macro_export]
302macro_rules! add_return {
303    ($arr: ident += $variant: ident($val: ident)) => {{
304        let node = $crate::Node::$variant($val);
305        $arr.push(node.clone());
306        return Ok(Some(node));
307    }};
308}
309
310#[macro_export]
311macro_rules! add_ir_return {
312    ($arr: ident += $variant: ident($val: ident)) => {{
313        let node = $crate::IRNode::$variant($val);
314        $arr.push(node.clone());
315        return Ok(Some(node));
316    }};
317}
318
319#[macro_export]
320macro_rules! module_top_level_getter {
321    ($fn: ident -> $ty: ident) => {
322        impl $crate::Module {
323            pub fn $fn(&self) -> Vec<$crate::$ty> {
324                let mut items = Vec::new();
325
326                if let Some(nodes) = &self.top_level {
327                    for node in nodes {
328                        if let $crate::TopLevelNode::$ty(item) = node {
329                            items.push(item.clone());
330                        }
331                    }
332                }
333
334                items
335            }
336        }
337    };
338}
339
340#[macro_export]
341macro_rules! module_indexer_add {
342    ($id: ident += ($name: ident, $module: ident)) => {
343        if let Some(it) = $id.get_mut(&$name) {
344            it.extend($module.$id());
345        } else {
346            $id.insert($name.clone(), $module.$id());
347        }
348    };
349
350    ($id: ident += ($name: ident, $module: ident, &$cx: ident)) => {
351        if let Some(it) = $id.get_mut(&$name) {
352            it.extend($module.$id());
353        } else {
354            $id.insert($name.clone(), $module.$id(&$cx));
355        }
356    };
357}
358
359#[macro_export]
360macro_rules! dump_ast_part {
361    ($ast: ident.$id: ident => $dir: ident) => {
362        if let Some(it) = &$ast.$id {
363            let path = $dir.join(format!("{}.ron", stringify!($id)));
364
365            fs::write(path, ron::ser::to_string_pretty(it, PrettyConfig::new())?)?;
366        }
367    };
368}
369
370#[macro_export]
371macro_rules! command {
372    ($($part: expr),*) => {
373        $crate::IRCommand {
374            cmd: vec![$($crate::IRNode::Literal($crate::IRLiteral::String($part.into()))),*],
375        }
376    };
377}