pub fn ast_to_sir(expr: &Expr) -> WeldResult<SirProgram> {
    if let ExprKind::Lambda {
        ref params,
        ref body,
    } = expr.kind
    {
        let mut prog = SirProgram::new(&body.ty, params);
        prog.sym_gen = SymbolGenerator::from_expression(expr);
        for tp in params {
            prog.funcs[0].params.insert(tp.name.clone(), tp.ty.clone());
        }
        let first_block = prog.funcs[0].add_block();
        let (res_func, res_block, res_sym) = gen_expr(
            body,
            &mut prog,
            0,
            first_block,
            &mut StatementTracker::new(),
        )?;
        prog.funcs[res_func].blocks[res_block].terminator = Terminator::ProgramReturn(res_sym);
        sir_param_correction(&mut prog)?;
        // second call is necessary in the case where there are loops in the call graph, since
        // some parameter dependencies may not have been propagated through back edges
        sir_param_correction(&mut prog)?;
        assign_return_types(&mut prog)?;
        Ok(prog)
    } else {
        compile_err!("Expression passed to ast_to_sir was not a Lambda")
    }
}
Convert an AST to a SIR program. Symbols must be unique in expr.
weld/src/sir/mod.rs