neo-decompiler 0.10.1

Neo N3 NEF decompiler: parse, disassemble, lift bytecode to high-level pseudocode and C# skeletons, with a CLI, JSON reports, and optional WebAssembly bindings.
Documentation
use super::super::form::SsaExpr;
use super::Subst;

/// Resolve a single level of substitution through a variable reference.
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()
}

/// Recursively apply `subst` to every variable reference inside `expr`.
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(),
    }
}