1use crate::ast::*;
2
3pub trait Walker {
4 fn walk_statement_list(&mut self, stmts: Vec<&mut Statement>) {
5 for v in stmts {
6 self.walk_statement(v);
7 }
8 }
9
10 fn walk_statement(&mut self, stmt: &mut Statement) {
11 self.visit_statement(stmt);
12 match stmt {
13 Statement::Let(ref mut def) => {
14 self.walk_expression(&mut def.value);
15 }
16 Statement::Expression(ref mut expr) => {
17 self.walk_expression(expr);
18 }
19 Statement::Assert(_, ref mut expr) => {
20 self.walk_expression(expr);
21 }
22 Statement::Output(_, _, ref mut expr) => {
23 self.walk_expression(expr);
24 }
25 Statement::Print(_, _, ref mut expr) => {
26 self.walk_expression(expr);
27 }
28 }
29 }
30
31 fn walk_fieldset(&mut self, fs: &mut FieldList) {
32 for &mut (_, ref mut expr) in fs.iter_mut() {
33 self.walk_expression(expr);
34 }
35 }
36
37 fn walk_expression(&mut self, expr: &mut Expression) {
38 self.visit_expression(expr);
39 match expr {
40 Expression::Call(ref mut def) => {
41 for expr in def.arglist.iter_mut() {
42 self.walk_expression(expr);
43 }
44 }
45 Expression::Cast(ref mut def) => {
46 self.walk_expression(&mut def.target);
47 }
48 Expression::Copy(ref mut def) => {
49 self.walk_fieldset(&mut def.fields);
50 }
51 Expression::Format(ref mut def) => match def.args {
52 FormatArgs::List(ref mut args) => {
53 for expr in args.iter_mut() {
54 self.walk_expression(expr);
55 }
56 }
57 FormatArgs::Single(ref mut expr) => {
58 self.walk_expression(expr);
59 }
60 },
61 Expression::FuncOp(ref mut def) => match def {
62 FuncOpDef::Reduce(ref mut def) => {
63 self.walk_expression(def.target.as_mut());
64 self.walk_expression(def.acc.as_mut())
65 }
66 FuncOpDef::Map(ref mut def) => {
67 self.walk_expression(def.target.as_mut());
68 }
69 FuncOpDef::Filter(ref mut def) => {
70 self.walk_expression(def.target.as_mut());
71 }
72 },
73 Expression::Binary(ref mut def) => {
74 self.walk_expression(def.left.as_mut());
75 self.walk_expression(def.right.as_mut());
76 }
77 Expression::Grouped(ref mut expr, _) => {
78 self.walk_expression(expr);
79 }
80 Expression::Func(ref mut def) => self.walk_expression(def.fields.as_mut()),
81 Expression::Module(ref mut def) => {
82 self.walk_fieldset(&mut def.arg_set);
83 for stmt in def.statements.iter_mut() {
84 self.walk_statement(stmt);
85 }
86 }
87 Expression::Range(ref mut def) => {
88 self.walk_expression(def.start.as_mut());
89 self.walk_expression(def.end.as_mut());
90 if let Some(ref mut expr) = def.step {
91 self.walk_expression(expr.as_mut());
92 }
93 }
94 Expression::Select(ref mut def) => {
95 match def.default {
96 Some(ref mut e) => {
97 self.walk_expression(e.as_mut());
98 }
99 None => {
100 }
102 };
103 self.walk_expression(def.val.as_mut());
104 self.walk_fieldset(&mut def.tuple);
105 }
106 Expression::Simple(ref mut val) => {
107 self.walk_value(val);
108 }
109
110 Expression::Import(i) => {
111 self.visit_import(i);
112 }
113 Expression::Include(i) => {
114 self.visit_include(i);
115 }
116 Expression::Fail(f) => {
117 self.visit_fail(f);
118 }
119 Expression::Not(ref mut def) => {
120 self.walk_expression(def.expr.as_mut());
121 }
122 Expression::Debug(ref mut def) => {
123 self.walk_expression(&mut def.expr);
124 }
125 }
126 }
127
128 fn walk_value(&mut self, val: &mut Value) {
129 match val {
130 Value::Empty(_)
131 | Value::Symbol(_)
132 | Value::Boolean(_)
133 | Value::Int(_)
134 | Value::Float(_)
135 | Value::Str(_) => self.visit_value(val),
136 Value::Tuple(fs) => self.walk_fieldset(&mut fs.val),
137 Value::List(vs) => {
138 for e in &mut vs.elems {
139 self.walk_expression(e);
140 }
141 }
142 }
143 }
144
145 fn visit_import(&mut self, _i: &mut ImportDef) {
147 }
149
150 fn visit_include(&mut self, _i: &mut IncludeDef) {
151 }
153
154 fn visit_fail(&mut self, _f: &mut FailDef) {
155 }
157
158 fn visit_value(&mut self, _val: &mut Value) {
159 }
161
162 fn visit_expression(&mut self, _expr: &mut Expression) {
163 }
165
166 fn visit_statement(&mut self, _stmt: &mut Statement) {
167 }
169}
170
171pub struct AstWalker<'a> {
173 handle_value: Option<&'a dyn Fn(&mut Value)>,
174 handle_expression: Option<&'a dyn Fn(&mut Expression)>,
175 handle_statment: Option<&'a dyn Fn(&mut Statement)>,
176}
177
178impl<'a> AstWalker<'a> {
179 pub fn new() -> Self {
180 AstWalker {
181 handle_value: None,
182 handle_expression: None,
183 handle_statment: None,
184 }
185 }
186
187 pub fn with_value_handler(mut self, h: &'a dyn Fn(&mut Value)) -> Self {
188 self.handle_value = Some(h);
189 self
190 }
191
192 pub fn with_expr_handler(mut self, h: &'a dyn Fn(&mut Expression)) -> Self {
193 self.handle_expression = Some(h);
194 self
195 }
196
197 pub fn with_stmt_handler(mut self, h: &'a dyn Fn(&mut Statement)) -> Self {
198 self.handle_statment = Some(h);
199 self
200 }
201}
202
203impl<'a> Walker for AstWalker<'a> {
204 fn visit_value(&mut self, val: &mut Value) {
205 if let Some(h) = self.handle_value {
206 h(val);
207 }
208 }
209
210 fn visit_expression(&mut self, expr: &mut Expression) {
211 if let Some(h) = self.handle_expression {
212 h(expr);
213 }
214 }
215
216 fn visit_statement(&mut self, stmt: &mut Statement) {
217 if let Some(h) = self.handle_statment {
218 h(stmt);
219 }
220 }
221}