Skip to main content

conjure_cp_essence_parser/parser/
macros.rs

1/// Get the i-th named child of a node, or return a syntax error with a message if it doesn't exist.
2#[macro_export]
3macro_rules! named_child {
4    ($node:ident) => {
5        named_child!($node, 0, "Missing sub-expression")
6    };
7    ($node:ident, $i:literal) => {
8        named_child!($node, $i, format!("Missing sub-expression #{}", $i + 1))
9    };
10    ($node:ident, $i:literal, $msg:expr) => {
11        $node
12            .named_child($i)
13            .ok_or(FatalParseError::internal_error(
14                format!("{} in expression of kind '{}'", $msg, $node.kind()),
15                Some($node.range()),
16            ))?
17    };
18    // recoverable version
19    (recover, $ctx:expr, $node:expr) => {{
20        match $node.named_child(0) {
21            Some(child) => Some(child),
22            None => {
23                $ctx.record_error($crate::errors::RecoverableParseError::new(
24                    format!(
25                        "Missing sub-expression in expression of kind '{}'",
26                        $node.kind()
27                    ),
28                    Some($node.range()),
29                ));
30                None
31            }
32        }
33    }};
34    (recover, $ctx:expr, $node:expr, $i:literal) => {{
35        match $node.named_child($i) {
36            Some(child) => Some(child),
37            None => {
38                $ctx.record_error($crate::errors::RecoverableParseError::new(
39                    format!(
40                        "Missing sub-expression #{} in expression of kind '{}'",
41                        $i + 1,
42                        $node.kind()
43                    ),
44                    Some($node.range()),
45                ));
46                None
47            }
48        }
49    }};
50}
51
52/// Get the i-th child of a node, or return a syntax error with a message if it doesn't exist.
53#[macro_export]
54macro_rules! child {
55    ($node:ident) => {
56        child!($node, 0, "Missing sub-expression")
57    };
58    ($node:ident, $i:literal) => {
59        child!($node, $i, format!("Missing sub-expression #{}", $i + 1))
60    };
61    ($node:ident, $i:literal, $msg:expr) => {
62        $node.child($i).ok_or(FatalParseError::internal_error(
63            format!("{} in expression of kind '{}'", $msg, $node.kind()),
64            Some($node.range()),
65        ))?
66    };
67    // recoverable version
68    (recover, $ctx:expr, $node:expr) => {{
69        match $node.child(0) {
70            Some(child) => Some(child),
71            None => {
72                $ctx.record_error($crate::errors::RecoverableParseError::new(
73                    format!(
74                        "Missing sub-expression in expression of kind '{}'",
75                        $node.kind()
76                    ),
77                    Some($node.range()),
78                ));
79                None
80            }
81        }
82    }};
83    (recover, $ctx:expr, $node:expr, $i:literal) => {{
84        match $node.child($i) {
85            Some(child) => Some(child),
86            None => {
87                $ctx.record_error($crate::errors::RecoverableParseError::new(
88                    format!(
89                        "Missing sub-expression #{} in expression of kind '{}'",
90                        $i + 1,
91                        $node.kind()
92                    ),
93                    Some($node.range()),
94                ));
95                None
96            }
97        }
98    }};
99}
100
101/// Get the named field of a node, or return a syntax error with a message if it doesn't exist.
102#[macro_export]
103macro_rules! field {
104    ($node:ident, $name:expr) => {
105        $node
106            .child_by_field_name($name)
107            .ok_or(FatalParseError::internal_error(
108                format!(
109                    "Missing field '{}' in expression of kind '{}'",
110                    $name,
111                    $node.kind()
112                ),
113                Some($node.range()),
114            ))?
115    };
116    // recoverable version
117    (recover, $ctx:expr, $node:expr, $name:expr) => {{
118        match $node.child_by_field_name($name) {
119            Some(child) => Some(child),
120            None => {
121                $ctx.record_error($crate::errors::RecoverableParseError::new(
122                    format!(
123                        "Missing field '{}' in expression of kind '{}'",
124                        $name,
125                        $node.kind()
126                    ),
127                    Some($node.range()),
128                ));
129                None
130            }
131        }
132    }};
133}