rslua_march1917/
ast_walker.rs

1use crate::ast::*;
2use crate::types::*;
3
4// if visitor return `Ok(true)`, walker will not travel its children
5// if visitor return `Ok(false)`, walker will travel its children recursively.
6// if visitor return `Err(E)`, walker will stop travelling.
7pub 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}