use super::super::form::SsaExpr;
use super::Subst;
pub(super) fn resolve_once(subst: &Subst, expr: &SsaExpr) -> SsaExpr {
if let SsaExpr::Variable(v) = expr {
if let Some(rep) = subst.get(v) {
return rep.clone();
}
}
expr.clone()
}
pub(super) fn rewrite_expr(expr: &SsaExpr, subst: &Subst) -> SsaExpr {
match expr {
SsaExpr::Variable(v) => subst
.get(v)
.cloned()
.unwrap_or_else(|| SsaExpr::var(v.clone())),
SsaExpr::Binary { op, left, right } => {
SsaExpr::binary(*op, rewrite_expr(left, subst), rewrite_expr(right, subst))
}
SsaExpr::Unary { op, operand } => SsaExpr::unary(*op, rewrite_expr(operand, subst)),
SsaExpr::Call { name, args } => SsaExpr::call(
name.clone(),
args.iter().map(|arg| rewrite_expr(arg, subst)).collect(),
),
SsaExpr::Index { base, index } => SsaExpr::Index {
base: Box::new(rewrite_expr(base, subst)),
index: Box::new(rewrite_expr(index, subst)),
},
SsaExpr::Member { base, name } => SsaExpr::Member {
base: Box::new(rewrite_expr(base, subst)),
name: name.clone(),
},
SsaExpr::Cast { expr, target_type } => SsaExpr::Cast {
expr: Box::new(rewrite_expr(expr, subst)),
target_type: target_type.clone(),
},
SsaExpr::Array(elements) => SsaExpr::Array(
elements
.iter()
.map(|element| rewrite_expr(element, subst))
.collect(),
),
SsaExpr::Map(pairs) => SsaExpr::Map(
pairs
.iter()
.map(|(key, value)| (rewrite_expr(key, subst), rewrite_expr(value, subst)))
.collect(),
),
SsaExpr::Ternary {
condition,
then_expr,
else_expr,
} => SsaExpr::Ternary {
condition: Box::new(rewrite_expr(condition, subst)),
then_expr: Box::new(rewrite_expr(then_expr, subst)),
else_expr: Box::new(rewrite_expr(else_expr, subst)),
},
other => other.clone(),
}
}