1use crate::ast::*;
2use crate::types::*;
3
4pub trait AstVisitor<E = ()> {
8 fn stat_sep(&mut self) {}
9
10 fn begin_if(&mut self, _cond: &Expr) -> Result<bool, E> {
11 Ok(false)
12 }
13 fn then(&mut self, _block: &Block) -> Result<bool, E> {
14 Ok(false)
15 }
16 fn begin_else_if(&mut self, _cond: &Expr) -> Result<bool, E> {
17 Ok(false)
18 }
19 fn begin_else(&mut self, _block: &Block) -> Result<bool, E> {
20 Ok(false)
21 }
22 fn end_if(&mut self) {}
23
24 fn begin_while(&mut self, _cond: &Expr) -> Result<bool, E> {
25 Ok(false)
26 }
27 fn begin_while_block(&mut self, _block: &Block) -> Result<bool, E> {
28 Ok(false)
29 }
30 fn end_while(&mut self) {}
31
32 fn begin_do_block(&mut self, _block: &Block) -> Result<bool, E> {
33 Ok(false)
34 }
35 fn end_do_block(&mut self) {}
36
37 fn for_num(&mut self, _fornum: &ForNum) -> Result<bool, E> {
38 Ok(false)
39 }
40 fn for_list(&mut self, _forlist: &ForList) -> Result<bool, E> {
41 Ok(false)
42 }
43 fn begin_for_block(&mut self, _block: &Block) -> Result<bool, E> {
44 Ok(false)
45 }
46 fn end_for(&mut self) {}
47
48 fn begin_repeat(&mut self, _block: &Block) -> Result<bool, E> {
49 Ok(false)
50 }
51 fn until(&mut self) {}
52 fn end_repeat(&mut self) {}
53
54 fn func(&mut self, _funcstat: &FuncStat) {}
55
56 fn local_stat(&mut self, _stat: &LocalStat) -> Result<(), E> {
57 Ok(())
58 }
59 fn label_stat(&mut self, _stat: &LabelStat) -> Result<(), E> {
60 Ok(())
61 }
62 fn ret_stat(&mut self, _stat: &RetStat) -> Result<(), E> {
63 Ok(())
64 }
65 fn break_stat(&mut self, _stat: &BreakStat) -> Result<(), E> {
66 Ok(())
67 }
68 fn goto_stat(&mut self, _stat: &GotoStat) -> Result<(), E> {
69 Ok(())
70 }
71 fn assign_stat(&mut self, _stat: &AssignStat) -> Result<(), E> {
72 Ok(())
73 }
74 fn call_stat(&mut self, _stat: &CallStat) -> Result<(), E> {
75 Ok(())
76 }
77
78 fn expr(&mut self, _stat: &Expr) -> Result<bool, E> {
79 Ok(false)
80 }
81 fn expr_sep(&mut self) {}
82
83 fn nil(&mut self) {}
84 fn true_(&mut self) {}
85 fn false_(&mut self) {}
86 fn float(&mut self, _f: FloatType) {}
87 fn int(&mut self, _i: IntType) {}
88 fn string(&mut self, _s: &str) {}
89 fn vararg(&mut self) {}
90
91 fn anonymous_func(&mut self) {}
92 fn begin_func_body(&mut self, _body: &FuncBody) -> Result<bool, E> {
93 Ok(false)
94 }
95 fn end_func_body(&mut self) {}
96
97 fn begin_table(&mut self, _t: &Table) -> Result<bool, E> {
98 Ok(false)
99 }
100 fn end_table(&mut self, _t: &Table) {}
101
102 fn field_sep(&mut self) {}
103
104 fn begin_rec_field(&mut self, _field: &RecField) -> Result<bool, E> {
105 Ok(false)
106 }
107 fn field_kv_sep(&mut self) {}
108 fn begin_field_key(&mut self, _key: &FieldKey) -> Result<bool, E> {
109 Ok(false)
110 }
111 fn end_field_key(&mut self, _key: &FieldKey) {}
112 fn end_rec_field(&mut self) {}
113
114 fn begin_bin_expr(&mut self, _expr: &BinExpr) -> Result<bool, E> {
115 Ok(false)
116 }
117 fn binop(&mut self, _op: BinOp) {}
118 fn end_bin_expr(&mut self) {}
119
120 fn begin_un_expr(&mut self, _expr: &UnExpr) -> Result<bool, E> {
121 Ok(false)
122 }
123 fn unop(&mut self, _op: UnOp) {}
124 fn end_un_expr(&mut self) {}
125
126 fn begin_suffixed_expr(&mut self, _expr: &SuffixedExpr) -> Result<bool, E> {
127 Ok(false)
128 }
129 fn end_suffixed_expr(&mut self) {}
130
131 fn name(&mut self, _name: &str) {}
132 fn attr(&mut self, _attr: &str) {}
133 fn method(&mut self, _method: &str) {}
134
135 fn begin_index(&mut self, _expr: &Expr) -> Result<bool, E> {
136 Ok(false)
137 }
138 fn end_index(&mut self) {}
139
140 fn begin_func_args(&mut self, _args: &FuncArgs) -> Result<bool, E> {
141 Ok(false)
142 }
143 fn end_func_args(&mut self) {}
144
145 fn begin_paren_expr(&mut self, _expr: &Expr) -> Result<bool, E> {
146 Ok(false)
147 }
148 fn end_paren_expr(&mut self) {}
149
150 fn suffix(&mut self, _suf: &Suffix) -> Result<bool, E> {
151 Ok(false)
152 }
153
154 fn comment(&mut self, _comment: &CommentStat) {}
155
156 fn error(&mut self, e: E, _source: &Source) -> Result<(), E> { Err(e) }
157}
158
159pub mod ast_walker {
160 use super::AstVisitor;
161 use crate::ast::*;
162
163 pub fn walk_block<T: AstVisitor<E>, E>(block: &Block, visitor: &mut T) -> Result<(), E> {
164 for StatInfo { source, stat } in block.stats.iter() {
165 match walk_stat(stat, visitor) {
166 Err(e) => return visitor.error(e, source),
167 _ => (),
168 };
169 visitor.stat_sep();
170 }
171 Ok(())
172 }
173
174 pub fn walk_stat<T: AstVisitor<E>, E>(stat: &Stat, visitor: &mut T) -> Result<(), E> {
175 match stat {
176 Stat::IfStat(ifstat) => walk_ifstat(ifstat, visitor),
177 Stat::WhileStat(whilestat) => walk_whilestat(whilestat, visitor),
178 Stat::DoBlock(doblock) => walk_doblockstat(doblock, visitor),
179 Stat::ForStat(forstat) => walk_forstat(forstat, visitor),
180 Stat::RepeatStat(repeatstat) => walk_repeatstat(repeatstat, visitor),
181 Stat::FuncStat(funcstat) => walk_funcstat(funcstat, visitor),
182 Stat::LocalStat(localstat) => walk_localstat(localstat, visitor),
183 Stat::LabelStat(labelstat) => walk_labelstat(labelstat, visitor),
184 Stat::RetStat(retstat) => walk_retstat(retstat, visitor),
185 Stat::BreakStat(breakstat) => walk_breakstat(breakstat, visitor),
186 Stat::GotoStat(gotostat) => walk_gotostat(gotostat, visitor),
187 Stat::AssignStat(assignstat) => walk_assignstat(assignstat, visitor),
188 Stat::CallStat(callstat) => walk_callstat(callstat, visitor),
189 Stat::CommentStat(comment) => walk_comment(comment, visitor),
190 }
191 }
192
193 pub fn walk_ifstat<T: AstVisitor<E>, E>(stat: &IfStat, visitor: &mut T) -> Result<(), E> {
194 let mut if_blocks = stat.cond_blocks.iter();
195 if let Some(if_block) = if_blocks.next() {
196 if !visitor.begin_if(&if_block.cond)? {
197 walk_expr(&if_block.cond, visitor)?;
198 }
199 if !visitor.then(&if_block.block)? {
200 walk_block(&if_block.block, visitor)?;
201 }
202 while let Some(else_if_block) = if_blocks.next() {
203 if !visitor.begin_else_if(&else_if_block.cond)? {
204 walk_expr(&else_if_block.cond, visitor)?;
205 }
206 if !visitor.then(&else_if_block.block)? {
207 walk_block(&else_if_block.block, visitor)?;
208 }
209 }
210 if let Some(else_block) = &stat.else_block {
211 if else_block.stats.len() > 0 {
212 if !visitor.begin_else(else_block)? {
213 walk_block(else_block, visitor)?;
214 }
215 }
216 }
217 visitor.end_if();
218 }
219 Ok(())
220 }
221
222 pub fn walk_whilestat<T: AstVisitor<E>, E>(stat: &WhileStat, visitor: &mut T) -> Result<(), E> {
223 if !visitor.begin_while(&stat.cond)? {
224 walk_expr(&stat.cond, visitor)?;
225 }
226 if !visitor.begin_while_block(&stat.block)? {
227 walk_block(&stat.block, visitor)?;
228 }
229 visitor.end_while();
230 Ok(())
231 }
232
233 pub fn walk_doblockstat<T: AstVisitor<E>, E>(stat: &DoBlock, visitor: &mut T) -> Result<(), E> {
234 if !visitor.begin_do_block(&stat.block)? {
235 walk_block(&stat.block, visitor)?;
236 }
237 visitor.end_do_block();
238 Ok(())
239 }
240
241 pub fn walk_forstat<T: AstVisitor<E>, E>(stat: &ForStat, visitor: &mut T) -> Result<(), E> {
242 match stat {
243 ForStat::ForNum(fornum) => walk_forenum(fornum, visitor),
244 ForStat::ForList(forlist) => walk_forlist(forlist, visitor),
245 }
246 }
247
248 pub fn walk_forenum<T: AstVisitor<E>, E>(stat: &ForNum, visitor: &mut T) -> Result<(), E> {
249 if !visitor.for_num(stat)? {
250 walk_expr(&stat.init, visitor)?;
251 visitor.expr_sep();
252 walk_expr(&stat.limit, visitor)?;
253 if let Some(expr) = &stat.step {
254 visitor.expr_sep();
255 walk_expr(expr, visitor)?;
256 }
257 }
258 if !visitor.begin_for_block(&stat.body)? {
259 walk_block(&stat.body, visitor)?;
260 }
261 visitor.end_for();
262 Ok(())
263 }
264
265 pub fn walk_forlist<T: AstVisitor<E>, E>(stat: &ForList, visitor: &mut T) -> Result<(), E> {
266 if !visitor.for_list(stat)? {
267 walk_exprlist(&stat.exprs, visitor)?;
268 }
269 if !visitor.begin_for_block(&stat.body)? {
270 walk_block(&stat.body, visitor)?;
271 }
272 visitor.end_for();
273 Ok(())
274 }
275
276 pub fn walk_repeatstat<T: AstVisitor<E>, E>(
277 stat: &RepeatStat,
278 visitor: &mut T,
279 ) -> Result<(), E> {
280 if !visitor.begin_repeat(&stat.block)? {
281 walk_block(&stat.block, visitor)?;
282 visitor.until();
283 walk_expr(&stat.cond, visitor)?;
284 }
285 visitor.end_repeat();
286 Ok(())
287 }
288
289 pub fn walk_funcstat<T: AstVisitor<E>, E>(stat: &FuncStat, visitor: &mut T) -> Result<(), E> {
290 visitor.func(stat);
291 walk_funcbody(&stat.body, visitor)
292 }
293
294 pub fn walk_localstat<T: AstVisitor<E>, E>(stat: &LocalStat, visitor: &mut T) -> Result<(), E> {
295 visitor.local_stat(stat)
296 }
297
298 pub fn walk_labelstat<T: AstVisitor<E>, E>(stat: &LabelStat, visitor: &mut T) -> Result<(), E> {
299 visitor.label_stat(stat)
300 }
301
302 pub fn walk_retstat<T: AstVisitor<E>, E>(stat: &RetStat, visitor: &mut T) -> Result<(), E> {
303 visitor.ret_stat(stat)
304 }
305
306 pub fn walk_breakstat<T: AstVisitor<E>, E>(stat: &BreakStat, visitor: &mut T) -> Result<(), E> {
307 visitor.break_stat(stat)
308 }
309
310 pub fn walk_gotostat<T: AstVisitor<E>, E>(stat: &GotoStat, visitor: &mut T) -> Result<(), E> {
311 visitor.goto_stat(stat)
312 }
313
314 pub fn walk_assignstat<T: AstVisitor<E>, E>(
315 stat: &AssignStat,
316 visitor: &mut T,
317 ) -> Result<(), E> {
318 visitor.assign_stat(stat)
319 }
320
321 pub fn walk_callstat<T: AstVisitor<E>, E>(stat: &CallStat, visitor: &mut T) -> Result<(), E> {
322 visitor.call_stat(stat)
323 }
324
325 pub fn walk_comment<T: AstVisitor<E>, E>(stat: &CommentStat, visitor: &mut T) -> Result<(), E> {
326 visitor.comment(stat);
327 Ok(())
328 }
329
330 pub fn walk_expr<T: AstVisitor<E>, E>(expr: &Expr, visitor: &mut T) -> Result<(), E> {
331 if !visitor.expr(expr)? {
332 match expr {
333 Expr::Nil => visitor.nil(),
334 Expr::True => visitor.true_(),
335 Expr::False => visitor.false_(),
336 Expr::Float(f) => visitor.float(*f),
337 Expr::Int(i) => visitor.int(*i),
338 Expr::String(string) => visitor.string(string),
339 Expr::VarArg => visitor.vararg(),
340 Expr::Name(s) => visitor.name(s),
341 Expr::ParenExpr(expr) => walk_parenexpr(expr, visitor)?,
342 Expr::FuncBody(body) => {
343 visitor.anonymous_func();
344 walk_funcbody(body, visitor)?
345 }
346 Expr::Table(t) => walk_table(t, visitor)?,
347 Expr::BinExpr(expr) => walk_binexpr(expr, visitor)?,
348 Expr::UnExpr(expr) => walk_unexpr(expr, visitor)?,
349 Expr::SuffixedExpr(expr) => walk_suffixedexpr(expr, visitor)?,
350 };
351 }
352 Ok(())
353 }
354
355 pub fn walk_funcbody<T: AstVisitor<E>, E>(body: &FuncBody, visitor: &mut T) -> Result<(), E> {
356 if !visitor.begin_func_body(body)? {
357 walk_block(&body.block, visitor)?;
358 }
359 visitor.end_func_body();
360 Ok(())
361 }
362
363 pub fn walk_binexpr<T: AstVisitor<E>, E>(expr: &BinExpr, visitor: &mut T) -> Result<(), E> {
364 if !visitor.begin_bin_expr(expr)? {
365 walk_expr(&expr.left, visitor)?;
366 visitor.binop(expr.op);
367 walk_expr(&expr.right, visitor)?;
368 }
369 visitor.end_bin_expr();
370 Ok(())
371 }
372
373 pub fn walk_unexpr<T: AstVisitor<E>, E>(expr: &UnExpr, visitor: &mut T) -> Result<(), E> {
374 if !visitor.begin_un_expr(expr)? {
375 visitor.unop(expr.op);
376 walk_expr(&expr.expr, visitor)?;
377 }
378 visitor.end_un_expr();
379 Ok(())
380 }
381
382 pub fn walk_suffixedexpr<T: AstVisitor<E>, E>(
383 expr: &SuffixedExpr,
384 visitor: &mut T,
385 ) -> Result<(), E> {
386 if !visitor.begin_suffixed_expr(expr)? {
387 walk_expr(&expr.primary, visitor)?;
388 for suf in expr.suffixes.iter() {
389 if !visitor.suffix(suf)? {
390 match suf {
391 Suffix::Attr(attr) => visitor.attr(attr),
392 Suffix::Method(method) => visitor.method(method),
393 Suffix::Index(index) => walk_index(index, visitor)?,
394 Suffix::FuncArgs(args) => walk_funcargs(args, visitor)?,
395 }
396 }
397 }
398 }
399 visitor.end_suffixed_expr();
400 Ok(())
401 }
402
403 pub fn walk_assinable<T: AstVisitor<E>, E>(
404 assignable: &Assignable,
405 visitor: &mut T,
406 ) -> Result<(), E> {
407 match assignable {
408 Assignable::SuffixedExpr(s) => walk_suffixedexpr(s, visitor)?,
409 Assignable::Name(s) => visitor.name(s)
410 };
411 Ok(())
412 }
413
414 pub fn walk_index<T: AstVisitor<E>, E>(expr: &Expr, visitor: &mut T) -> Result<(), E> {
415 if !visitor.begin_index(expr)? {
416 walk_expr(expr, visitor)?;
417 }
418 visitor.end_index();
419 Ok(())
420 }
421
422 pub fn walk_funcargs<T: AstVisitor<E>, E>(args: &FuncArgs, visitor: &mut T) -> Result<(), E> {
423 if !visitor.begin_func_args(args)? {
424 match args {
425 FuncArgs::String(s) => visitor.string(s),
426 FuncArgs::Table(t) => walk_table(t, visitor)?,
427 FuncArgs::Exprs(exprs) => walk_exprlist(exprs, visitor)?,
428 }
429 }
430 visitor.end_func_args();
431 Ok(())
432 }
433
434 pub fn walk_parenexpr<T: AstVisitor<E>, E>(expr: &Expr, visitor: &mut T) -> Result<(), E> {
435 if !visitor.begin_paren_expr(expr)? {
436 walk_expr(expr, visitor)?;
437 }
438 visitor.end_paren_expr();
439 Ok(())
440 }
441
442 pub fn walk_table<T: AstVisitor<E>, E>(table: &Table, visitor: &mut T) -> Result<(), E> {
443 if !visitor.begin_table(table)? {
444 walk_fields(&table.fields, visitor)?;
445 }
446 visitor.end_table(table);
447 Ok(())
448 }
449
450 pub fn walk_fields<T: AstVisitor<E>, E>(fields: &Vec<Field>, visitor: &mut T) -> Result<(), E> {
451 for field in fields.iter() {
452 walk_field(field, visitor)?;
453 visitor.field_sep();
454 }
455 Ok(())
456 }
457
458 pub fn walk_field<T: AstVisitor<E>, E>(field: &Field, visitor: &mut T) -> Result<(), E> {
459 match field {
460 Field::RecField(field) => walk_recfield(field, visitor),
461 Field::ListField(field) => walk_expr(field, visitor),
462 }
463 }
464
465 pub fn walk_recfield<T: AstVisitor<E>, E>(field: &RecField, visitor: &mut T) -> Result<(), E> {
466 if !visitor.begin_rec_field(field)? {
467 walk_fieldkey(&field.key, visitor)?;
468 visitor.field_kv_sep();
469 walk_expr(&field.value, visitor)?;
470 }
471 visitor.end_rec_field();
472 Ok(())
473 }
474
475 pub fn walk_fieldkey<T: AstVisitor<E>, E>(key: &FieldKey, visitor: &mut T) -> Result<(), E> {
476 if !visitor.begin_field_key(key)? {
477 match key {
478 FieldKey::Name(s) => visitor.name(s),
479 FieldKey::Expr(expr) => walk_expr(expr, visitor)?,
480 };
481 }
482 visitor.end_field_key(key);
483 Ok(())
484 }
485
486 pub fn walk_exprlist<T: AstVisitor<E>, E>(
487 exprlist: &Vec<Expr>,
488 visitor: &mut T,
489 ) -> Result<(), E> {
490 for (n, expr) in exprlist.iter().enumerate() {
491 walk_expr(expr, visitor)?;
492 if n < exprlist.len() - 1 {
493 visitor.expr_sep();
494 }
495 }
496 Ok(())
497 }
498}