Move compile::visit mod to crate root
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
90
src/visit.rs
Normal file
90
src/visit.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
use crate::syn::ast::prelude::*;
|
||||
|
||||
pub trait Visit<A: Accept> {
|
||||
type Out;
|
||||
fn visit(&mut self, acceptor: &A) -> Self::Out;
|
||||
}
|
||||
|
||||
pub trait Accept {
|
||||
fn accept<V: Visit<Self>>(&self, visitor: &mut V) -> V::Out
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
pub trait DefaultAccept<V: Visit<Self>>: Accept + Sized {
|
||||
fn default_accept(&self, visitor: &mut V) -> V::Out;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! default_visitor {
|
||||
($default:ident for $visitor:ty where Out = $out:ty) => {
|
||||
impl crate::visit::Visit<$default> for $visitor {
|
||||
type Out = $out;
|
||||
fn visit(&mut self, acceptor: &$default) -> Self::Out {
|
||||
acceptor.default_accept(self)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! empty_visitor {
|
||||
($default:ident for $visitor:ty) => {
|
||||
impl crate::visit::Visit<$default> for $visitor {
|
||||
type Out = ();
|
||||
fn visit(&mut self, _: &$default) -> Self::Out {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_accept {
|
||||
($what:ident) => {
|
||||
impl crate::visit::Accept for $what {
|
||||
fn accept<V: Visit<Self>>(&self, visitor: &mut V) -> V::Out {
|
||||
visitor.visit(self)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_default_accept {
|
||||
($what:ident : $($requires:ident),+ => $($tail:tt)+) => {
|
||||
impl<V, Out> DefaultAccept<V> for $what
|
||||
where V: Visit<Self, Out=Out> $(+ Visit<$requires, Out=Out>)+
|
||||
{
|
||||
$($tail)+
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_accept!(Stmt);
|
||||
impl_default_accept!(Stmt : AssignStmt, Expr =>
|
||||
fn default_accept(&self, visitor: &mut V) -> Out {
|
||||
match self {
|
||||
Stmt::Assign(a) => visitor.visit(a),
|
||||
Stmt::Expr(e) => visitor.visit(e),
|
||||
}
|
||||
}
|
||||
);
|
||||
impl_accept!(AssignStmt);
|
||||
impl_accept!(Expr);
|
||||
|
||||
impl_default_accept!(Expr: BinExpr, UnExpr, FunCallExpr, IndexExpr, FunExpr, BaseExpr =>
|
||||
fn default_accept(&self, visitor: &mut V) -> Out {
|
||||
match self {
|
||||
Expr::Bin(b) => visitor.visit(b.as_ref()),
|
||||
Expr::Un(u) => visitor.visit(u.as_ref()),
|
||||
Expr::FunCall(f) => visitor.visit(f.as_ref()),
|
||||
Expr::Index(i) => visitor.visit(i.as_ref()),
|
||||
Expr::Fun(f) => visitor.visit(f.as_ref()),
|
||||
Expr::Base(b) => visitor.visit(b),
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
impl_accept!(BinExpr);
|
||||
impl_accept!(UnExpr);
|
||||
impl_accept!(FunCallExpr);
|
||||
impl_accept!(IndexExpr);
|
||||
impl_accept!(FunExpr);
|
||||
impl_accept!(BaseExpr);
|
||||
Reference in New Issue
Block a user