use crate::ast::*;
pub trait AstDescend<'a> {
fn descend_mut<T: VisitorMut<'a>>(&mut self, visitor: &mut T);
}
macro_rules! visitor {
(Descend: { $( $name1:ident ( $arg1:ident: $ty1:ty ) , )+ };
Terminal: { $( $name2:ident ( $arg2:ident: $ty2:ty ) , )+ };) => {
pub trait VisitorMut<'a>
where
Self: Sized,
{
$(
fn $name1(&mut self, $arg1: $ty1) {
$arg1.descend_mut(self);
}
)+
$(
#[allow(unused_variables)]
fn $name2(&mut self, $arg2: $ty2) {}
)+
}
};
}
visitor! {
Descend: {
visit_expr(expr: &mut Expr<'a>),
visit_prefix_expr(prefix_expr: &mut PrefixExpr<'a>),
visit_var_field(var_field: &mut VarField<'a>),
visit_table_constructor(table_constructor: &mut TableConstructor<'a>),
visit_callee(callee: &mut FunctionCallee<'a>),
visit_args(args: &mut FunctionArgs<'a>),
visit_var(var: &mut Var<'a>),
visit_function_call(function_call: &mut FunctionCall<'a>),
visit_un_op(un_op: &mut UnOpExpr<'a>),
visit_bin_op(bin_op: &mut BinOpExpr<'a>),
visit_function_expr(function_expr: &mut FunctionExpr<'a>),
visit_table_field(table_field: &mut TableField<'a>),
visit_table_key(table_key: &mut TableKey<'a>),
visit_stmt(stmt: &mut Statement<'a>),
visit_block(block: &mut Block<'a>),
visit_return_stmt(stmt: &mut ReturnStat<'a>),
visit_assignment_stmt(stmt: &mut AssignmentStat<'a>),
visit_while_stmt(stmt: &mut WhileStat<'a>),
visit_for_stmt(stmt: &mut ForStat<'a>),
visit_repeat_stmt(stmt: &mut RepeatStat<'a>),
visit_local_decl(stmt: &mut LocalDeclarationStat<'a>),
visit_function_decl(stmt: &mut FunctionDeclarationStat<'a>),
visit_label_stmt(stmt: &mut LabelStat<'a>),
visit_goto_stmt(stmt: &mut GotoStat<'a>),
visit_if_stmt(stmt: &mut IfStat<'a>),
visit_generic_for(stmt: &mut GenericFor<'a>),
visit_numerical_for(stmt: &mut NumericalFor<'a>),
visit_function_body(body: &mut FunctionBody<'a>),
};
Terminal: {
visit_name(name: &mut Name<'a>),
visit_string_lit(string_lit: &mut StringLit<'a>),
visit_nil_lit(nil_lit: &mut NilLit<'a>),
visit_boolean_lit(boolean_lit: &mut BooleanLit<'a>),
visit_number_lit(number_lit: &mut NumberLit<'a>),
visit_vararg(vararg: &mut Vararg<'a>),
visit_empty_stmt(stmt: &mut EmptyStat<'a>),
visit_break_stmt(stmt: &mut BreakStat<'a>),
};
}