Skip to main content

ucglib/ast/
walk.rs

1use crate::ast::*;
2
3pub trait Visitor {
4    fn visit_import(&mut self, _i: &mut ImportDef) {
5        // noop by default;
6    }
7
8    fn leave_import(&mut self) {
9        // noop by default
10    }
11
12    fn visit_include(&mut self, _i: &mut IncludeDef) {
13        // noop by default;
14    }
15
16    fn leave_include(&mut self) {
17        // noop by default
18    }
19
20    fn visit_fail(&mut self, _f: &mut FailDef) {
21        // noop by default;
22    }
23
24    fn leave_fail(&mut self) {
25        // noop by default
26    }
27
28    fn visit_value(&mut self, _val: &mut Value) {
29        // noop by default
30    }
31
32    fn leave_value(&mut self, _val: &Value) {
33        // noop by default
34    }
35
36    fn visit_expression(&mut self, _expr: &mut Expression) {
37        // noop by default
38    }
39
40    fn leave_expression(&mut self, _expr: &Expression) {
41        // noop by default
42    }
43
44    fn visit_statement(&mut self, _stmt: &mut Statement) {
45        // noop by default
46    }
47
48    fn leave_statement(&mut self, _stmt: &Statement) {
49        // noop by default
50    }
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                        // noop;
152                    }
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                // noop
193            }
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}