use crate::node::{ BinOp, Block, Br, BrIf, BrTable, Call, CallIndirect, CmpOp, Expression, FuncData, GetGlobal, GetLocal, GetTemporary, If, LoadAt, MemoryGrow, MemorySize, Select, SetGlobal, SetLocal, SetTemporary, Statement, StoreAt, Terminator, UnOp, Value, }; pub trait Visitor { fn visit_select(&mut self, _: &Select) {} fn visit_get_temporary(&mut self, _: &GetTemporary) {} fn visit_get_local(&mut self, _: &GetLocal) {} fn visit_get_global(&mut self, _: &GetGlobal) {} fn visit_load_at(&mut self, _: &LoadAt) {} fn visit_memory_size(&mut self, _: &MemorySize) {} fn visit_value(&mut self, _: &Value) {} fn visit_un_op(&mut self, _: &UnOp) {} fn visit_bin_op(&mut self, _: &BinOp) {} fn visit_cmp_op(&mut self, _: &CmpOp) {} fn visit_expression(&mut self, _: &Expression) {} fn visit_unreachable(&mut self) {} fn visit_br(&mut self, _: &Br) {} fn visit_br_table(&mut self, _: &BrTable) {} fn visit_terminator(&mut self, _: &Terminator) {} fn visit_block(&mut self, _: &Block) {} fn visit_br_if(&mut self, _: &BrIf) {} fn visit_if(&mut self, _: &If) {} fn visit_call(&mut self, _: &Call) {} fn visit_call_indirect(&mut self, _: &CallIndirect) {} fn visit_set_temporary(&mut self, _: &SetTemporary) {} fn visit_set_local(&mut self, _: &SetLocal) {} fn visit_set_global(&mut self, _: &SetGlobal) {} fn visit_store_at(&mut self, _: &StoreAt) {} fn visit_memory_grow(&mut self, _: &MemoryGrow) {} fn visit_statement(&mut self, _: &Statement) {} } pub trait Driver { fn accept(&self, visitor: &mut T); } impl Driver for Select { fn accept(&self, visitor: &mut T) { self.condition().accept(visitor); self.on_true().accept(visitor); self.on_false().accept(visitor); visitor.visit_select(self); } } impl Driver for GetTemporary { fn accept(&self, visitor: &mut T) { visitor.visit_get_temporary(self); } } impl Driver for GetLocal { fn accept(&self, visitor: &mut T) { visitor.visit_get_local(self); } } impl Driver for GetGlobal { fn accept(&self, visitor: &mut T) { visitor.visit_get_global(self); } } impl Driver for LoadAt { fn accept(&self, visitor: &mut T) { self.pointer().accept(visitor); visitor.visit_load_at(self); } } impl Driver for MemorySize { fn accept(&self, visitor: &mut T) { visitor.visit_memory_size(self); } } impl Driver for Value { fn accept(&self, visitor: &mut T) { visitor.visit_value(self); } } impl Driver for UnOp { fn accept(&self, visitor: &mut T) { self.rhs().accept(visitor); visitor.visit_un_op(self); } } impl Driver for BinOp { fn accept(&self, visitor: &mut T) { self.lhs().accept(visitor); self.rhs().accept(visitor); visitor.visit_bin_op(self); } } impl Driver for CmpOp { fn accept(&self, visitor: &mut T) { self.lhs().accept(visitor); self.rhs().accept(visitor); visitor.visit_cmp_op(self); } } impl Driver for Expression { fn accept(&self, visitor: &mut T) { match self { Self::Select(v) => v.accept(visitor), Self::GetTemporary(v) => v.accept(visitor), Self::GetLocal(v) => v.accept(visitor), Self::GetGlobal(v) => v.accept(visitor), Self::LoadAt(v) => v.accept(visitor), Self::MemorySize(v) => v.accept(visitor), Self::Value(v) => v.accept(visitor), Self::UnOp(v) => v.accept(visitor), Self::BinOp(v) => v.accept(visitor), Self::CmpOp(v) => v.accept(visitor), } visitor.visit_expression(self); } } impl Driver for Br { fn accept(&self, visitor: &mut T) { visitor.visit_br(self); } } impl Driver for BrTable { fn accept(&self, visitor: &mut T) { self.condition().accept(visitor); visitor.visit_br_table(self); } } impl Driver for Terminator { fn accept(&self, visitor: &mut T) { match self { Self::Unreachable => visitor.visit_unreachable(), Self::Br(v) => v.accept(visitor), Self::BrTable(v) => v.accept(visitor), } visitor.visit_terminator(self); } } impl Driver for Block { fn accept(&self, visitor: &mut T) { for v in self.code() { v.accept(visitor); } if let Some(v) = self.last() { v.accept(visitor); } visitor.visit_block(self); } } impl Driver for BrIf { fn accept(&self, visitor: &mut T) { self.condition().accept(visitor); visitor.visit_br_if(self); } } impl Driver for If { fn accept(&self, visitor: &mut T) { self.condition().accept(visitor); self.on_true().accept(visitor); if let Some(v) = self.on_false() { v.accept(visitor); } visitor.visit_if(self); } } impl Driver for Call { fn accept(&self, visitor: &mut T) { for v in self.param_list() { v.accept(visitor); } visitor.visit_call(self); } } impl Driver for CallIndirect { fn accept(&self, visitor: &mut T) { self.index().accept(visitor); for v in self.param_list() { v.accept(visitor); } visitor.visit_call_indirect(self); } } impl Driver for SetTemporary { fn accept(&self, visitor: &mut T) { self.value().accept(visitor); visitor.visit_set_temporary(self); } } impl Driver for SetLocal { fn accept(&self, visitor: &mut T) { self.value().accept(visitor); visitor.visit_set_local(self); } } impl Driver for SetGlobal { fn accept(&self, visitor: &mut T) { self.value().accept(visitor); visitor.visit_set_global(self); } } impl Driver for StoreAt { fn accept(&self, visitor: &mut T) { self.pointer().accept(visitor); self.value().accept(visitor); visitor.visit_store_at(self); } } impl Driver for MemoryGrow { fn accept(&self, visitor: &mut T) { self.size().accept(visitor); visitor.visit_memory_grow(self); } } impl Driver for Statement { fn accept(&self, visitor: &mut T) { match self { Self::Block(v) => v.accept(visitor), Self::BrIf(v) => v.accept(visitor), Self::If(v) => v.accept(visitor), Self::Call(v) => v.accept(visitor), Self::CallIndirect(v) => v.accept(visitor), Self::SetTemporary(v) => v.accept(visitor), Self::SetLocal(v) => v.accept(visitor), Self::SetGlobal(v) => v.accept(visitor), Self::StoreAt(v) => v.accept(visitor), Self::MemoryGrow(v) => v.accept(visitor), } visitor.visit_statement(self); } } impl Driver for FuncData { fn accept(&self, visitor: &mut T) { self.code().accept(visitor); } }