1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
use super::Binary;
use super::Expr;
use super::ExprKind;
pub fn rewrite<E, F: Fn(&Expr) -> Result<Option<Expr>, E>>(e: Expr, f: F) -> Result<Expr, E> {
let e = f(&e)?.unwrap_or(e);
Ok(match &e.kind {
ExprKind::Binary(binary) => match (f(&binary.lhs)?, f(&binary.rhs)?) {
(None, None) => e,
(l, r) => Expr {
kind: Binary {
op: binary.op.clone(),
lhs: Box::new(l.unwrap_or(*binary.lhs.clone())),
rhs: Box::new(r.unwrap_or(*binary.rhs.clone())),
}
.into(),
..e
},
},
ExprKind::Ident(_) => f(&e)?.unwrap_or(e), ExprKind::GlobalVars(_) => f(&e)?.unwrap_or(e),
ExprKind::Literal(_) => f(&e)?.unwrap_or(e),
})
}