1use crate::arena::{ExprArena, ExprId, ExprNode};
2
3pub trait Visitor {
6 fn visit(&mut self, arena: &ExprArena, id: ExprId, node: &ExprNode);
7}
8
9pub fn walk<V: Visitor>(arena: &ExprArena, id: ExprId, visitor: &mut V) {
11 let node = arena.get(id);
12 visitor.visit(arena, id, node);
13 match node {
14 ExprNode::Add(children) | ExprNode::Mul(children) => {
15 let kids: Vec<ExprId> = children.iter().copied().collect();
16 for child in kids {
17 walk(arena, child, visitor);
18 }
19 }
20 ExprNode::Neg(inner)
21 | ExprNode::Sin(inner)
22 | ExprNode::Cos(inner)
23 | ExprNode::Exp(inner)
24 | ExprNode::Log(inner)
25 | ExprNode::Abs(inner) => {
26 let inner = *inner;
27 walk(arena, inner, visitor);
28 }
29 ExprNode::Pow(base, exp) => {
30 let base = *base;
31 let exp = *exp;
32 walk(arena, base, visitor);
33 walk(arena, exp, visitor);
34 }
35 ExprNode::Div(num, den) => {
36 let num = *num;
37 let den = *den;
38 walk(arena, num, visitor);
39 walk(arena, den, visitor);
40 }
41 ExprNode::Const(_) | ExprNode::Var(_) | ExprNode::Param(_) | ExprNode::Linear { .. } => {}
42 }
43}