1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#[macro_export]
macro_rules! parse_insert_punctuation {
    ($context:ident, $current:ident, $children:ident, $content:expr) => {
        {
            let punc = crate::ast::punctuations::Punctuation::new($content, parse_span(&$current), $context.next_path());
            $children.insert(crate::traits::identifiable::Identifiable::id(&punc), punc.into());
        }
    };
}

#[macro_export]
macro_rules! parse_insert_operator {
    ($context:ident, $current:ident, $children:ident, $content:expr) => {
        {
            let op = crate::ast::operators::Operator::new($content, parse_span(&$current), $context.next_path());
            $children.insert(crate::traits::identifiable::Identifiable::id(&op), op.into());
        }
    };
}

#[macro_export]
macro_rules! parse_insert_keyword {
    ($context:ident, $current:ident, $children:ident, $content:expr) => {
        {
            let keyword = crate::ast::keyword::Keyword::new($content, parse_span(&$current), $context.next_path());
            $children.insert(crate::traits::identifiable::Identifiable::id(&keyword), keyword.into());
        }
    };
}

#[macro_export]
macro_rules! parse_append {
    ($expr:expr, $children:ident) => {
        {
            let node = $expr;
            $children.insert(crate::traits::identifiable::Identifiable::id(&node), node.into());
        }
    };
}

#[macro_export]
macro_rules! parse_insert {
    ($expr:expr, $children:ident, $dest:ident) => {
        {
            let node = $expr;
            $dest.push(crate::traits::identifiable::Identifiable::id(&node));
            $children.insert(crate::traits::identifiable::Identifiable::id(&node), node.into());
        }
    };
}

#[macro_export]
macro_rules! parse_set {
    ($expr:expr, $children:ident, $dest:ident) => {
        {
            let node = $expr;
            $dest = crate::traits::identifiable::Identifiable::id(&node);
            $children.insert(crate::traits::identifiable::Identifiable::id(&node), node.into());
        }
    };
}

#[macro_export]
macro_rules! parse_set_optional {
    ($expr:expr, $children:ident, $dest:ident) => {
        {
            let node = $expr;
            $dest = Some(crate::traits::identifiable::Identifiable::id(&node));
            $children.insert(crate::traits::identifiable::Identifiable::id(&node), node.into());
        }
    };
}

#[macro_export]
macro_rules! parse_set_identifier_and_string_path {
    ($context: ident, $current: ident, $children: ident, $identifier: ident, $string_path: ident) => {
        {
            let node = crate::parser::parse_identifier::parse_identifier(&$current, $context);
            $identifier = crate::traits::identifiable::Identifiable::id(&node);
            $string_path = $context.next_parent_string_path(node.name());
            $children.insert(crate::traits::identifiable::Identifiable::id(&node), node.into());
        }
    };
}

#[macro_export]
macro_rules! parse_container_node_variables_without_span {
    ($context:ident) => {
        {
            let children: std::collections::BTreeMap<usize, crate::ast::node::Node> = std::collections::BTreeMap::new();
            let path = $context.next_parent_path();
            (path, children)
        }
    };
}

#[macro_export]
macro_rules! parse_container_node_variables {
    ($pair:ident, $context:ident) => {
        {
            let span = parse_span(&$pair);
            let children: std::collections::BTreeMap<usize, crate::ast::node::Node> = std::collections::BTreeMap::new();
            let path = $context.next_parent_path();
            (span, path, children)
        }
    };
    ($pair:ident, $context:ident, named) => {
        {
            let span = parse_span(&$pair);
            let children: std::collections::BTreeMap<usize, crate::ast::node::Node> = std::collections::BTreeMap::new();
            let path = $context.next_parent_path();
            let string_path: Vec<String> = Vec::new();
            (span, path, string_path, children)
        }
    };
    ($pair:ident, $context:ident, availability) => {
        {
            let span = parse_span(&$pair);
            let children: std::collections::BTreeMap<usize, crate::ast::node::Node> = std::collections::BTreeMap::new();
            let path = $context.next_parent_path();
            let define_availability = $context.current_availability_flag();
            let actual_availability = std::cell::RefCell::new(crate::availability::Availability::none());
            (span, path, children, define_availability, actual_availability)
        }
    };
    ($pair:ident, $context:ident, named, availability) => {
        {
            let span = parse_span(&$pair);
            let children: std::collections::BTreeMap<usize, crate::ast::node::Node> = std::collections::BTreeMap::new();
            let path = $context.next_parent_path();
            let string_path: Vec<String> = Vec::new();
            let define_availability = $context.current_availability_flag();
            let actual_availability = std::cell::RefCell::new(crate::availability::Availability::none());
            (span, path, string_path, children, define_availability, actual_availability)
        }
    };
}

#[macro_export]
macro_rules! parse_container_node_variables_cleanup {
    ($context: ident) => {
        $context.pop_parent_id();
    };
    ($context: ident, named) => {
        $context.pop_parent_id();
        $context.pop_string_path();
    }
}

#[macro_export]
macro_rules! parse_node_variables {
    ($pair:ident, $context:ident) => {
        {
            let span = parse_span(&$pair);
            let path = $context.next_path();
            (span, path)
        }
    };
}