1use crate::ast::*;
2
3pub trait Visitor {
4 fn visit_import(&mut self, _i: &mut ImportDef) {
5 }
7
8 fn leave_import(&mut self) {
9 }
11
12 fn visit_include(&mut self, _i: &mut IncludeDef) {
13 }
15
16 fn leave_include(&mut self) {
17 }
19
20 fn visit_fail(&mut self, _f: &mut FailDef) {
21 }
23
24 fn leave_fail(&mut self) {
25 }
27
28 fn visit_value(&mut self, _val: &mut Value) {
29 }
31
32 fn leave_value(&mut self, _val: &Value) {
33 }
35
36 fn visit_expression(&mut self, _expr: &mut Expression) {
37 }
39
40 fn leave_expression(&mut self, _expr: &Expression) {
41 }
43
44 fn visit_statement(&mut self, _stmt: &mut Statement) {
45 }
47
48 fn leave_statement(&mut self, _stmt: &Statement) {
49 }
51}
52
53pub trait Walker: Visitor {
54 fn walk_statement_list(&mut self, stmts: Vec<&mut Statement>) {
55 for v in stmts {
56 self.walk_statement(v);
57 }
58 }
59
60 fn walk_statement(&mut self, stmt: &mut Statement) {
61 self.visit_statement(stmt);
62 match stmt {
63 Statement::Let(ref mut def) => {
64 self.walk_expression(&mut def.value);
65 }
66 Statement::Expression(ref mut expr) => {
67 self.walk_expression(expr);
68 }
69 Statement::Assert(_, ref mut expr) => {
70 self.walk_expression(expr);
71 }
72 Statement::Output(_, _, ref mut expr) => {
73 self.walk_expression(expr);
74 }
75 Statement::Print(_, _, ref mut expr) => {
76 self.walk_expression(expr);
77 }
78 }
79 self.leave_statement(stmt);
80 }
81
82 fn walk_fieldset(&mut self, fs: &mut FieldList) {
83 for (_, _constraint, ref mut expr) in fs.iter_mut() {
84 self.walk_expression(expr);
85 }
86 }
87
88 fn walk_expression(&mut self, expr: &mut Expression) {
89 self.visit_expression(expr);
90 match expr {
91 Expression::Call(ref mut def) => {
92 for expr in def.arglist.iter_mut() {
93 self.walk_expression(expr);
94 }
95 }
96 Expression::Cast(ref mut def) => {
97 self.walk_expression(&mut def.target);
98 }
99 Expression::Copy(ref mut def) => {
100 self.walk_fieldset(&mut def.fields);
101 }
102 Expression::Format(ref mut def) => match def.args {
103 FormatArgs::List(ref mut args) => {
104 for expr in args.iter_mut() {
105 self.walk_expression(expr);
106 }
107 }
108 FormatArgs::Single(ref mut expr) => {
109 self.walk_expression(expr);
110 }
111 },
112 Expression::FuncOp(ref mut def) => match def {
113 FuncOpDef::Reduce(ref mut def) => {
114 self.walk_expression(def.target.as_mut());
115 self.walk_expression(def.acc.as_mut())
116 }
117 FuncOpDef::Map(ref mut def) => {
118 self.walk_expression(def.target.as_mut());
119 }
120 FuncOpDef::Filter(ref mut def) => {
121 self.walk_expression(def.target.as_mut());
122 }
123 },
124 Expression::Binary(ref mut def) => {
125 self.walk_expression(def.left.as_mut());
126 self.walk_expression(def.right.as_mut());
127 }
128 Expression::Grouped(ref mut expr, _) => {
129 self.walk_expression(expr);
130 }
131 Expression::Func(ref mut def) => self.walk_expression(def.fields.as_mut()),
132 Expression::Module(ref mut def) => {
133 self.walk_fieldset(&mut def.arg_set);
134 for stmt in def.statements.iter_mut() {
135 self.walk_statement(stmt);
136 }
137 }
138 Expression::Range(ref mut def) => {
139 self.walk_expression(def.start.as_mut());
140 self.walk_expression(def.end.as_mut());
141 if let Some(ref mut expr) = def.step {
142 self.walk_expression(expr.as_mut());
143 }
144 }
145 Expression::Select(ref mut def) => {
146 match def.default {
147 Some(ref mut e) => {
148 self.walk_expression(e.as_mut());
149 }
150 None => {
151 }
153 };
154 self.walk_expression(def.val.as_mut());
155 self.walk_fieldset(&mut def.tuple);
156 }
157 Expression::Simple(ref mut val) => {
158 self.walk_value(val);
159 }
160
161 Expression::Import(i) => {
162 self.visit_import(i);
163 self.leave_import();
164 }
165 Expression::Include(i) => {
166 self.visit_include(i);
167 self.leave_include();
168 }
169 Expression::Fail(f) => {
170 self.visit_fail(f);
171 self.leave_fail();
172 }
173 Expression::Not(ref mut def) => {
174 self.walk_expression(def.expr.as_mut());
175 }
176 Expression::Debug(ref mut def) => {
177 self.walk_expression(&mut def.expr);
178 }
179 }
180 self.leave_expression(expr);
181 }
182
183 fn walk_value(&mut self, val: &mut Value) {
184 self.visit_value(val);
185 match val {
186 Value::Empty(_)
187 | Value::Symbol(_)
188 | Value::Boolean(_)
189 | Value::Int(_)
190 | Value::Float(_)
191 | Value::Str(_) => {
192 }
194 Value::Tuple(fs) => self.walk_fieldset(&mut fs.val),
195 Value::List(vs) => {
196 for e in &mut vs.elems {
197 self.walk_expression(e);
198 }
199 }
200 }
201 self.leave_value(val);
202 }
203}
204
205impl<T> Walker for T where T: Visitor {}
206
207pub struct ChainedWalk<Visitor1, Visitor2> {
208 pub visitor_1: Visitor1,
209 pub visitor_2: Visitor2,
210}
211
212impl<Visitor1, Visitor2> ChainedWalk<Visitor1, Visitor2>
213where
214 Visitor1: Visitor,
215 Visitor2: Visitor,
216{
217 pub fn new(visitor_1: Visitor1, visitor_2: Visitor2) -> Self {
218 Self {
219 visitor_1,
220 visitor_2,
221 }
222 }
223}
224
225impl<Visitor1, Visitor2> Visitor for ChainedWalk<Visitor1, Visitor2>
226where
227 Visitor1: Visitor,
228 Visitor2: Visitor,
229{
230 fn visit_import(&mut self, i: &mut ImportDef) {
231 self.visitor_1.visit_import(i);
232 self.visitor_2.visit_import(i);
233 }
234 fn leave_import(&mut self) {
235 self.visitor_1.leave_import();
236 self.visitor_2.leave_import();
237 }
238
239 fn visit_include(&mut self, i: &mut IncludeDef) {
240 self.visitor_1.visit_include(i);
241 self.visitor_2.visit_include(i);
242 }
243 fn leave_include(&mut self) {
244 self.visitor_1.leave_include();
245 self.visitor_2.leave_include();
246 }
247
248 fn visit_fail(&mut self, f: &mut FailDef) {
249 self.visitor_1.visit_fail(f);
250 self.visitor_2.visit_fail(f);
251 }
252 fn leave_fail(&mut self) {
253 self.visitor_1.leave_fail();
254 self.visitor_2.leave_fail();
255 }
256
257 fn visit_value(&mut self, val: &mut Value) {
258 self.visitor_1.visit_value(val);
259 self.visitor_2.visit_value(val);
260 }
261 fn leave_value(&mut self, val: &Value) {
262 self.visitor_1.leave_value(val);
263 self.visitor_2.leave_value(val);
264 }
265
266 fn visit_expression(&mut self, expr: &mut Expression) {
267 self.visitor_1.visit_expression(expr);
268 self.visitor_2.visit_expression(expr);
269 }
270 fn leave_expression(&mut self, expr: &Expression) {
271 self.visitor_1.leave_expression(expr);
272 self.visitor_2.leave_expression(expr);
273 }
274
275 fn visit_statement(&mut self, stmt: &mut Statement) {
276 self.visitor_1.visit_statement(stmt);
277 self.visitor_2.visit_statement(stmt);
278 }
279 fn leave_statement(&mut self, stmt: &Statement) {
280 self.visitor_1.leave_statement(stmt);
281 self.visitor_2.leave_statement(stmt);
282 }
283}