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