{
    Let analyze. analyze
}

Where

Let analyze program.
    Let program. (place_packages program)
    In
    Let program. (collect_constants program)
    In
    Let program. (collect_labels_and_layouts program)
    In
    Let program. (place_variables program)
    In
    Let program. (flatten program)
    In
    program

Where

Let place_packages program.
    Let MAP. (SEARCH.MAP STRING.compare Func {key _}. key)
    In
    Let {_ packages}.
        (LIST.reduce program {0 MAP.empty}
            Func {i packages} package.
                {(i + 1) (MAP.insert packages {package.path i})})
    In
    Define rewrite_expr expr.
        Match expr
        | `true expr
        | `false expr
        | `num._ expr
        | `str._ expr
        | `package.path
            Let i.
                Match (MAP.search packages path)
                | `just.{_ i} i
                | `nothing (die "Package not found.")
                ;
            In
            `package.i
        | `prim._ expr
        | `var._ expr
        | `chain.{expr chain}
            `chain.{(rewrite_expr expr) chain}
        | `tuple.exprs
            `tuple.(LIST.map exprs rewrite_expr)
        | `module.binders
            Let binders.
                (LIST.map binders
                    Func binder.
                        Match binder
                        | `let.{pat expr} `let.{pat (rewrite_expr expr)}
                        ;)
            In
            `module.binders
        | `block.{binder_groups expr}
            Let binder_groups.
                (LIST.map binder_groups
                    Func binder_group.
                        (LIST.map binder_group
                            Func binder.
                                Match binder
                                | `let.{pat expr} `let.{pat (rewrite_expr expr)}
                                | `do.expr `do.(rewrite_expr expr)
                                ;))
            Let expr. (rewrite_expr expr)
            In
            `block.{binder_groups expr}
        | `app.{func args}
            Let func. (rewrite_expr func)
            Let args. (LIST.map args rewrite_expr)
            In
            `app.{func args}
        | `closure._ expr
        | `func.{i self free param_pats expr}
            `func.{i self free param_pats (rewrite_expr expr)}
        | `goto.expr
            `goto.(rewrite_expr expr)
        | `switch.{expr clauses}
            Let expr. (rewrite_expr expr)
            Let clauses.
                (LIST.map clauses
                    Func {pat body}. {pat (rewrite_expr body)})
            In
            `switch.{expr clauses}
        | `cond.clauses
            Let clauses.
                (LIST.map clauses
                    Func {test body}.
                        {(rewrite_expr test) (rewrite_expr body)})
            In
            `cond.clauses
        | `if.{test_expr then_expr else_expr}
            Let test_expr. (rewrite_expr test_expr)
            Let then_expr. (rewrite_expr then_expr)
            Let else_expr. (rewrite_expr else_expr)
            In
            `if.{test_expr then_expr else_expr}
        | `not.expr
            `not.(rewrite_expr expr)
        | `and.{test_expr then_expr}
            Let test_expr. (rewrite_expr test_expr)
            Let then_expr. (rewrite_expr then_expr)
            In
            `and.{test_expr then_expr}
        | `or.{test_expr else_expr}
            Let test_expr. (rewrite_expr test_expr)
            Let else_expr. (rewrite_expr else_expr)
            In
            `or.{test_expr else_expr}
        | `list.exprs
            `list.(LIST.map exprs rewrite_expr)
        | `labeled.{label expr}
            `labeled.{label (rewrite_expr expr)}
        | `match.{expr clauses}
            Let expr. (rewrite_expr expr)
            Let clauses.
                (LIST.map clauses
                    Func {pat body}. {pat (rewrite_expr body)})
            In
            `match.{expr clauses}
        ;
    In
    (LIST.map program
        Func package.
            {
                Let path. package.path
                Let imports. package.imports
                Let init. (rewrite_expr package.init)
                Let functions. (LIST.map package.functions rewrite_expr)
            })

Let collect_constants program.
    Let MAP.
        (SEARCH.MAP
            Func a b.
                Match a
                | `str.sa
                    Match b
                    | `str.sb (STRING.compare sa sb)
                    | `prim._ `greater
                    ;
                | `prim.sa
                    Match b
                    | `str._ `less
                    | `prim.sb (STRING.compare sa sb)
                    ;
                | _ (die "Unexpected constant.")
                ;
            Func {key _}. key)
    Let counter. &0
    In
    Let constants. &MAP.empty
    In
    Let intern const.
        Match (MAP.search ?constants const)
        | `just.{_ i} i
        | `nothing
            Let i. ?counter
            In
            Do (counter ! i + 1)
            Do (constants ! MAP.insert ?constants {const i})
            In
            i
        ;
    In
    Define rewrite_expr expr.
        Match expr
        | `true expr
        | `false expr
        | `num._ expr
        | `str._ `const.(intern expr)
        | `package._ expr
        | `prim._ `const.(intern expr)
        | `var._ expr
        | `chain.{expr chain}
            `chain.{(rewrite_expr expr) chain}
        | `tuple.exprs
            `tuple.(LIST.map exprs rewrite_expr)
        | `module.binders
            Let binders.
                (LIST.map binders
                    Func binder.
                        Match binder
                        | `let.{pat expr} `let.{pat (rewrite_expr expr)}
                        ;)
            In
            `module.binders
        | `block.{binder_groups expr}
            Let binder_groups.
                (LIST.map binder_groups
                    Func binder_group.
                        (LIST.map binder_group
                            Func binder.
                                Match binder
                                | `let.{pat expr} `let.{pat (rewrite_expr expr)}
                                | `do.expr `do.(rewrite_expr expr)
                                ;))
            Let expr. (rewrite_expr expr)
            In
            `block.{binder_groups expr}
        | `app.{func args}
            Let func. (rewrite_expr func)
            Let args. (LIST.map args rewrite_expr)
            In
            `app.{func args}
        | `closure._ expr
        | `func.{i self free param_pats expr}
            `func.{i self free param_pats (rewrite_expr expr)}
        | `goto.expr
            `goto.(rewrite_expr expr)
        | `switch.{expr clauses}
            Let expr. (rewrite_expr expr)
            Let clauses.
                (LIST.map clauses
                    Func {pat body}. {pat (rewrite_expr body)})
            In
            `switch.{expr clauses}
        | `cond.clauses
            Let clauses.
                (LIST.map clauses
                    Func {test body}.
                        {(rewrite_expr test) (rewrite_expr body)})
            In
            `cond.clauses
        | `if.{test_expr then_expr else_expr}
            Let test_expr. (rewrite_expr test_expr)
            Let then_expr. (rewrite_expr then_expr)
            Let else_expr. (rewrite_expr else_expr)
            In
            `if.{test_expr then_expr else_expr}
        | `not.expr
            `not.(rewrite_expr expr)
        | `and.{test_expr then_expr}
            Let test_expr. (rewrite_expr test_expr)
            Let then_expr. (rewrite_expr then_expr)
            In
            `and.{test_expr then_expr}
        | `or.{test_expr else_expr}
            Let test_expr. (rewrite_expr test_expr)
            Let else_expr. (rewrite_expr else_expr)
            In
            `or.{test_expr else_expr}
        | `list.exprs
            `list.(LIST.map exprs rewrite_expr)
        | `labeled.{label expr}
            `labeled.{label (rewrite_expr expr)}
        | `match.{expr clauses}
            Let expr. (rewrite_expr expr)
            Let clauses.
                (LIST.map clauses
                    Func {pat body}. {pat (rewrite_expr body)})
            In
            `match.{expr clauses}
        ;
    In
    Let packages.
        (LIST.map program
            Func package.
                {
                    Let path. package.path
                    Let imports. package.imports
                    Let init. (rewrite_expr package.init)
                    Let functions. (LIST.map package.functions rewrite_expr)
                })
    In
    {
        Let constants.
            (LIST.map
                (SORT.list_insertion
                    Func {_ i} {_ j}. (Z.compare i j)
                    (MAP.list ?constants))
                Func {const _}. const)
        Let packages. packages
    }

Let collect_labels_and_layouts program.
    Let LABEL_MAP.
        (SEARCH.MAP STRING.compare
            Func {key _}. key)
    Let LABEL_NAME_MAP.
        (SEARCH.MAP Z.compare
            Func {key _}. key)
    Let LAYOUT_MAP.
        (SEARCH.MAP
            Func a b.
                Let m. (LIST.length a)
                Let n. (LIST.length b)
                In
                Cond
                | (m < n) `less
                | (m > n) `greater
                | True
                    (LIST.reduce (LIST.zip a b) `equal
                        Func relation pair.
                            Match relation
                            | `equal
                                Let {ai bi}. pair
                                In
                                Cond
                                | (ai < bi) `less
                                | (ai > bi) `greater
                                | True `equal
                                ;
                            | _ relation
                            ;)
                ;
            Func {key _}. key)
    In
    Let labels. &LABEL_MAP.empty
    Let label_names. &LABEL_NAME_MAP.empty
    Let layouts. &LAYOUT_MAP.empty
    Let module_indexes. &[]
    Let label_counter. &0
    Let layout_counter. &0
    In
    Let intern_label name.
        Match (LABEL_MAP.search ?labels name)
        | `just.{_ i} i
        | `nothing
            Let i. ?label_counter
            In
            Do (label_counter ! (i + 1))
            Do (labels ! (LABEL_MAP.insert ?labels {name i}))
            Do (label_names ! (LABEL_NAME_MAP.insert ?label_names {i name}))
            In
            i
        ;
    In
    Let intern_layout labels.
        Match (LAYOUT_MAP.search ?layouts labels)
        | `just.{_ i} i
        | `nothing
            Let i. ?layout_counter
            In
            Do (layout_counter ! (i + (LIST.length labels) + 1))
            Do (layouts ! (LAYOUT_MAP.insert ?layouts {labels i}))
            Do (module_indexes ! (labels::?module_indexes))
            In
            i
        ;
    In
    Define rewrite_expr expr.
        Match expr
        | `true expr
        | `false expr
        | `num._ expr
        | `const._ expr
        | `package._ expr
        | `var._ expr
        | `chain.{expr chain}
            Let chain.
                (LIST.map chain
                    Func access.
                        Match access
                        | `id.name `module_fetch.(intern_label name)
                        | `num.i `tuple_fetch.i
                        ;)
            In
            `chain.{(rewrite_expr expr) chain}
        | `tuple.exprs
            `tuple.(LIST.map exprs rewrite_expr)
        | `module.binders
            Let {binders labels}.
                (LIST.fold binders {[] []}
                    Func binder {binders labels}.
                        Match binder
                        | `let.{pat expr}
                            Let binder. `let.{pat (rewrite_expr expr)}
                            Let label.
                                Match pat
                                | `var.var (intern_label var)
                                | _ (die "Invalid label in module expression.")
                                ;
                            In
                            {(binder::binders) (label::labels)}
                        ;)
            In
            Let labels. (SORT.list_insertion Z.compare labels)
            In
            Let layout. (intern_layout labels)
            In
            Let binders.
                (LIST.fold labels []
                    Func label sorted_binders.
                        Let maybe_binder.
                            (LIST.reduce binders `nothing
                                Func choice binder.
                                    Match choice
                                    | `nothing
                                        Match binder
                                        | `let.{pat expr}
                                            Match pat
                                            | `var.var
                                                If (label = (intern_label var))
                                                    `just.binder
                                                    `nothing
                                            ;
                                        ;
                                    | `just._ choice
                                    ;)
                        In
                        Match maybe_binder
                        | `just.binder (binder::sorted_binders)
                        | `nothing (die "Label sorting bug in module expr.")
                        ;)
            In
            `module.{layout binders}
        | `block.{binder_groups expr}
            Let binder_groups.
                (LIST.map binder_groups
                    Func binder_group.
                        (LIST.map binder_group
                            Func binder.
                                Match binder
                                | `let.{pat expr} `let.{pat (rewrite_expr expr)}
                                | `do.expr `do.(rewrite_expr expr)
                                ;))
            Let expr. (rewrite_expr expr)
            In
            `block.{binder_groups expr}
        | `app.{func args}
            Let func. (rewrite_expr func)
            Let args. (LIST.map args rewrite_expr)
            In
            `app.{func args}
        | `closure._ expr
        | `func.{i self free param_pats expr}
            `func.{i self free param_pats (rewrite_expr expr)}
        | `goto.expr
            `goto.(rewrite_expr expr)
        | `switch.{expr clauses}
            Let expr. (rewrite_expr expr)
            Let clauses.
                (LIST.map clauses
                    Func {pat body}. {pat (rewrite_expr body)})
            In
            `switch.{expr clauses}
        | `cond.clauses
            Let clauses.
                (LIST.map clauses
                    Func {test body}.
                        {(rewrite_expr test) (rewrite_expr body)})
            In
            `cond.clauses
        | `if.{test_expr then_expr else_expr}
            Let test_expr. (rewrite_expr test_expr)
            Let then_expr. (rewrite_expr then_expr)
            Let else_expr. (rewrite_expr else_expr)
            In
            `if.{test_expr then_expr else_expr}
        | `not.expr
            `not.(rewrite_expr expr)
        | `and.{test_expr then_expr}
            Let test_expr. (rewrite_expr test_expr)
            Let then_expr. (rewrite_expr then_expr)
            In
            `and.{test_expr then_expr}
        | `or.{test_expr else_expr}
            Let test_expr. (rewrite_expr test_expr)
            Let else_expr. (rewrite_expr else_expr)
            In
            `or.{test_expr else_expr}
        | `list.exprs
            `list.(LIST.map exprs rewrite_expr)
        | `labeled.{label expr}
            `labeled.{(intern_label label) (rewrite_expr expr)}
        | `match.{expr clauses}
            Let expr. (rewrite_expr expr)
            Let clauses.
                (LIST.fold clauses []
                    Func clause clauses.
                        Let {pat body}. clause
                        In
                        Let pat.
                            Match pat
                            | `default pat
                            | `labeled.{label vars}
                                Let label. (intern_label label)
                                In
                                `labeled.{label vars}
                            ;
                        In
                        ({pat (rewrite_expr body)}::clauses))
            In
            `match.{expr clauses}
        ;
    In
    Let packages.
        (LIST.map program.packages
            Func package.
                {
                    Let path. package.path
                    Let imports. package.imports
                    Let init. (rewrite_expr package.init)
                    Let functions. (LIST.map package.functions rewrite_expr)
                })
    In
    Let nil_label. (intern_label "nil")
    Let cons_label. (intern_label "cons")
    In
    {
        Let constants. program.constants
        Let label_names. (LABEL_MAP.list ?label_names)
        Let module_indexes. (LIST.reverse ?module_indexes)
        Let packages. packages
        Let nil_label. nil_label
        Let cons_label. cons_label
    }

Let place_variables program.
    Let MAP.
        (SEARCH.MAP STRING.compare
            Func {key _}. key)
    In
    Define reduce_expr env i expr.
        Match expr
        | `true expr
        | `false expr
        | `num._ expr
        | `const._ expr
        | `package._ expr
        | `var.name
            Match (MAP.search env name)
            | `just.{_ place} place
            | `nothing (die "place_variables: Unexpected unbound variable.")
            ;
        | `chain.{expr chain}
            `chain.{(reduce_expr env i expr) chain}
        | `tuple.exprs
            Let {i exprs}.
                (LIST.reduce exprs {i []}
                    Func {i exprs} expr.
                        Let expr. (reduce_expr env i expr)
                        In
                        {(i + 1) (expr::exprs)})
            In
            `tuple.(LIST.reverse exprs)
        | `module.{layout binders}
            Let {_ binders}.
                (LIST.reduce binders {i []}
                    Func {i binders} binder.
                        Match binder
                        | `let.{var expr}
                            Let binder.
                                `let.{var (reduce_expr env i expr)}
                            In
                            {(i + 1) (binder::binders)}
                        ;)
            In
            `module.{layout (LIST.reverse binders)}
        | `block.{binder_groups expr}
            Let {binder_groups i env}.
                (LIST.fold binder_groups {[] i env}
                    Func binder_group {binder_groups i env}.
                        Let {binder_group i env}.
                            (LIST.fold binder_group {[] i env}
                                Func binder {binder_group i env'}.
                                    Let binder.
                                        Match binder
                                        | `let.{pat expr}
                                            Let pat.
                                                Match pat
                                                | `tuple.vars
                                                    `tuple.(LIST.length vars)
                                                | `var._ `var
                                                ;
                                            In
                                            `let.{pat (reduce_expr env i expr)}
                                        | `do.expr
                                            `do.(reduce_expr env i expr)
                                        ;
                                    Let {env' i}.
                                        (LIST.reduce (binder_variables binder)
                                            {env' i}
                                            Func {env' i} var.
                                                Let env'.
                                                    (MAP.insert env' {var `stack.i})
                                                Let i. (i + 1)
                                                In
                                                {env' i})
                                    In
                                    Let binder_group. (binder::binder_group)
                                    In
                                    {binder_group i env'})
                        In
                        {(binder_group::binder_groups) i env})
            In
            Let expr. (reduce_expr env i expr)
            In
            `block.{binder_groups expr}
        | `app.{func args}
            Let n. (i + 3 + (LIST.length args))
            In
            Let func. (reduce_expr env n func)
            Let {_ args}.
                (LIST.fold args {(n + -1) []}
                    Func arg {i args}.
                        {(i + -1) ((reduce_expr env i arg)::args)})
            In
            `app.{func args}
        | `closure.{j free num_params}
            Let free.
                (LIST.map free
                    Func name. (reduce_expr env i `var.name))
            In
            `closure.{j free num_params}
        | `func.{j self free param_pats expr}
            Let env.
                Match self
                | `nothing env
                | `just.name (MAP.insert env {name `self})
                ;
            In
            Let {_ env}.
                (LIST.reduce free {0 env}
                    Func {k env} name.
                        Let env. (MAP.insert env {name `free.k})
                        Let k. (k + 1)
                        In
                        {k env})
            In
            Let n. (LIST.length param_pats)
            In
            Let {i k env}.
                (LIST.reduce param_pats {0 n env}
                    Func {i k env} pat.
                        Let {k env}.
                            Match pat
                            | `ignore {k env}
                            | `var.name {k (MAP.insert env {name `stack.i})}
                            | `tuple.names
                                (LIST.reduce names {k env}
                                    Func {k env} name.
                                        Let env.
                                            (MAP.insert env {name `stack.k})
                                        In
                                        {(k + 1) env})
                            ;
                        In
                        {(i + 1) k env})
            In
            Let expr. (reduce_expr env k expr)
            In
            `func.{j param_pats expr}
        | `goto.expr
            Let {func args}. Match expr | `app.pair pair ;
            In
            Let n. (i + (LIST.length args))
            In
            Let func. (reduce_expr env n func)
            Let {_ args}.
                (LIST.fold args {(n + -1) []}
                    Func arg {i args}.
                        {(i + -1) ((reduce_expr env i arg)::args)})
            In
            `goto.`app.{func args}
        | `switch.{expr clauses}
            Let expr. (reduce_expr env i expr)
            In
            Let clauses.
                (LIST.fold clauses []
                    Func clause clauses.
                        Let {pat body}. clause
                        In
                        Let {i env pat}.
                            Match pat
                            | `default.maybe_name
                                Match maybe_name
                                | `just.name
                                    Let i. (i + 1)
                                    Let env. (MAP.insert env {name `stack.i})
                                    In
                                    {i env `default.`push}
                                | `nothing {i env `default.`no_push}
                                ;
                            | `value._ {i env pat}
                            ;
                        In
                        Let body. (reduce_expr env i body)
                        In
                        ({pat body}::clauses))
            In
            `switch.{expr clauses}
        | `cond.clauses
            Let clauses.
                (LIST.map clauses
                    Func {test body}.
                        {(reduce_expr env i test) (reduce_expr env i body)})
            In
            `cond.clauses
        | `if.{test_expr then_expr else_expr}
            Let test_expr. (reduce_expr env i test_expr)
            Let then_expr. (reduce_expr env i then_expr)
            Let else_expr. (reduce_expr env i else_expr)
            In
            `if.{test_expr then_expr else_expr}
        | `not.expr
            `not.(reduce_expr env i expr)
        | `and.{test_expr then_expr}
            `and.{(reduce_expr env i test_expr) (reduce_expr env i then_expr)}
        | `or.{test_expr else_expr}
            `or.{(reduce_expr env i test_expr) (reduce_expr env i else_expr)}
        | `list.exprs
            `list.(LIST.map exprs Func expr. (reduce_expr env i expr))
        | `labeled.{label expr}
            `labeled.{label (reduce_expr env i expr)}
        | `match.{expr clauses}
            Let expr. (reduce_expr env i expr)
            In
            Let clauses.
                (LIST.fold clauses []
                    Func clause clauses.
                        Let {pat body}. clause
                        In
                        Let {pat names}.
                            Match pat
                            | `default {`default []}
                            | `labeled.{label vars}
                                Let {vars names}.
                                    Match vars
                                    | `default {`default []}
                                    | `var.name {`var [name]}
                                    | `tuple.names
                                        {`tuple.(LIST.length names) names}
                                    ;
                                In
                                {`labeled.{label vars} names}
                            ;
                        In
                        Let {i env}.
                            (LIST.reduce names {i env}
                                Func {i env} name.
                                    {(i + 1) (MAP.insert env {name `stack.i})})
                        In
                        Let body. (reduce_expr env i body)
                        In
                        ({pat body}::clauses))
            In
            `match.{expr clauses}
        ;
    In
    Let packages.
        (LIST.map program.packages
            Func package.
                {
                    Let path. package.path
                    Let imports. package.imports
                    Let init. (reduce_expr MAP.empty 0 package.init)
                    Let functions.
                        (LIST.map package.functions
                            Func func.
                                (reduce_expr MAP.empty 0 func))
                })
    In
    {
        Let constants. program.constants
        Let label_names. program.label_names
        Let module_indexes. program.module_indexes
        Let packages. packages
        Let nil_label. program.nil_label
        Let cons_label. program.cons_label
    }

Let flatten program.
    Let num_packages. (LIST.length program.packages)
    In
    Let {i _ init_code}.
        (LIST.fold program.packages {0 (num_packages + -1) []}
            Func package {i j instrs}.
                Let {i instrs}.
                    (flatten_expr package.init `nontail i $
                        `package_env_store.j::instrs)
                In
                {i (j + -1) instrs})
    In
    Let {_ function_code}.
        (LIST.fold program.packages {i []}
            Func package {i instrs}.
                (LIST.fold package.functions {i instrs}
                    Func func {i instrs}.
                        (flatten_expr func `tail i instrs)))
    In
    {
        Let constants. program.constants
        Let label_names. program.label_names
        Let module_indexes. program.module_indexes
        Let packages. program.packages
        Let nil_label. program.nil_label
        Let cons_label. program.cons_label
        Let init_code. init_code
        Let function_code. function_code
    }

Where

Define flatten_expr expr position i instrs.
    Let instrs.
        Match position
        | `tail
            Match expr
            | `goto._ instrs
            | `block._ instrs
            | `if._ instrs
            | `match._ instrs
            | `cond._ instrs
            | `switch._ instrs
            | `func._ instrs
            | _ (`pop_frame::instrs)
            ;
        | `nontail
            Match expr
            | `goto._ (die "Goto used in nontail position.")
            | _ instrs
            ;
        ;
    In
    Let trivial. {i (expr::instrs)}
    In
    Match expr
    | `true trivial
    | `false trivial
    | `num._ trivial
    | `const._ trivial
    | `package._ trivial
    | `stack._ trivial
    | `free._ trivial
    | `self trivial
    | `chain.{expr chain}
        Let instrs.
            (LIST.fold chain instrs
                Func access instrs. (access::instrs))
        In
        (flatten_expr expr `nontail i instrs)
    | `tuple.exprs
        Let size. (LIST.length exprs)
        In
        (LIST.fold exprs {i (`alloc_tuple.size::instrs)}
            Func expr {i instrs}.
                (flatten_expr expr `nontail i $ `push::instrs))
    | `module.{layout binders}
        (LIST.fold binders
            {i (`alloc_module.{layout (LIST.length binders)}::instrs)}
            Func binder {i instrs}.
                Match binder
                | `let.{var expr}
                    Goto (flatten_expr expr `nontail i $ `push::instrs)
                ;)
    | `block.{binder_groups expr}
        Let num_vars.
            (LIST.reduce binder_groups 0
                Func sum binder_group.
                    (LIST.reduce binder_group sum
                        Func sum binder.
                            (sum + (binder_num_placed_variables binder))))
        In
        Let instrs.
            If (num_vars = 0)
                instrs
                Match position
                | `tail instrs
                | `nontail (`pop_vars.num_vars::instrs)
                ;
        In
        (LIST.reduce binder_groups (flatten_expr expr position i instrs)
            Func {i instrs} binder_group.
                (LIST.reduce binder_group {i instrs}
                    Func {i instrs} binder.
                        Match binder
                        | `let.{pat expr}
                            Let instrs.
                                Match pat
                                | `tuple.n
                                    Switch n
                                    | 0 instrs
                                    | _ (`open_tuple.n::instrs)
                                    ;
                                | `var (`push::instrs)
                                ;
                            In
                            Goto (flatten_expr expr `nontail i instrs)
                        | `do.expr
                            Goto (flatten_expr expr `nontail i instrs)
                        ;))
    | `app.{func args}
        Let num_args. (LIST.length args)
        Let j. i
        In
        Let {i instrs}.
            (flatten_expr func `nontail (i + 1) $
                `call.num_args::`block.j::instrs)
        In
        Let {i instrs}.
            (LIST.fold args {i instrs}
                Func arg {i instrs}.
                    Goto (flatten_expr arg `nontail i $ `push::instrs))
        In
        {i (`push_frame.j::instrs)}
    | `closure.{j free num_params}
        {i (`alloc_closure.{j free num_params}::instrs)}
    | `func.{j param_pats expr}
        Let {i instrs}. (flatten_expr expr `tail i instrs)
        Let k. ((LIST.length param_pats) + -1)
        In
        Let {_ instrs}.
            (LIST.fold param_pats {k instrs}
                Func pat {k instrs}.
                    Let instrs.
                        Match pat
                        | `ignore instrs
                        | `var._ instrs
                        | `tuple.names
                            (`stack.k::`open_tuple.(LIST.length names)::instrs)
                        ;
                    In
                    {(k + -1) instrs})
        In
        {i (`entry.j::instrs)}
    | `goto.expr
        Match expr
        | `app.{func args}
            Let num_args. (LIST.length args)
            In
            Let {i instrs}.
                (flatten_expr func `nontail i $ `tailcall.num_args::instrs)
            In
            (LIST.fold args {i instrs}
                Func arg {i instrs}.
                    Goto (flatten_expr arg `nontail i $ `push::instrs))
        ;
    | `switch.{expr clauses}
        Let j. i
        Let {i instrs}.
            Match position
            | `tail {i instrs}
            | `nontail {(i + 1) (`block.i::instrs)}
            ;
        In
        Let {i instrs clauses}.
            (LIST.fold clauses {i instrs []}
                Func {pat body} {i instrs clauses}.
                    Let instrs.
                        Match position
                        | `tail instrs
                        | `nontail
                            Match pat
                            | `default.maybe_push
                                Match maybe_push
                                | `push (`pop_vars.1::`jump.j::instrs)
                                | `no_push (`jump.j::instrs)
                                ;
                            | `value._ (`jump.j::instrs)
                            ;
                        ;
                    In
                    Let {i instrs}. (flatten_expr body position i instrs)
                    In
                    {(i + 1) (`block.i::instrs) ({pat i}::clauses)})
        In
        Let {clauses default}.
            (LIST.fold clauses {[] `nothing}
                Func {pat i} {clauses default}.
                    Match pat
                    | `default.maybe_push
                        Match maybe_push
                        | `push {clauses `just.`push_and_jump.i}
                        | `no_push {clauses `just.`jump.i}
                        ;
                    | `value.n {({n i}::clauses) default}
                    ;)
        In
        Let instrs. (`switch.{clauses default}::instrs)
        In
        (flatten_expr expr `nontail i instrs)
    | `cond.clauses
        Let j. i
        Let {i instrs}.
            Match position
            | `nontail {(i + 1) (`block.i::instrs)}
            | `tail {i instrs}
            ;
        In
        Let instrs. (`block.i::`halt::instrs)
        In
        Let {i instrs _}.
            (LIST.fold clauses {(i + 1) instrs i}
                Func {test body} {i instrs k}.
                    Let instrs.
                        Match position
                        | `tail instrs
                        | `nontail (`jump.j::instrs)
                        ;
                    In
                    Let {i instrs}. (flatten_expr body position i instrs)
                    In
                    Let instrs. (`jump_if_false.k::instrs)
                    In
                    Let {i instrs}. (flatten_expr test `nontail i instrs)
                    In
                    {(i + 1) (`block.i::instrs) i})
        In
        {i instrs}
    | `if.{test_expr then_expr else_expr}
        Let j. i
        Let {i instrs}.
            Match position
            | `nontail {(i + 1) (`block.i::instrs)}
            | `tail {i instrs}
            ;
        In
        Let k. i
        Let {i instrs}. (flatten_expr else_expr position (i + 1) instrs)
        In
        Let instrs. (`block.k::instrs)
        In
        Let instrs.
            Match position | `tail instrs | `nontail (`jump.j::instrs) ;
        In
        Let {i instrs}. (flatten_expr then_expr position i instrs)
        In
        (flatten_expr test_expr `nontail i $ `jump_if_false.k::instrs)
    | `not.expr
        (flatten_expr expr `nontail i $ `not::instrs)
    | `and.{test_expr then_expr}
        Let j. i
        Let i. (i + 1)
        Let instrs. (`block.i::instrs)
        In
        Let {i instrs}. (flatten_expr then_expr position i instrs)
        In
        (flatten_expr test_expr `nontail i $ `jump_if_false.j::instrs)
    | `or.{test_expr else_expr}
        Let j. i
        Let i. (i + 1)
        Let instrs. (`block.i::instrs)
        In
        Let {i instrs}. (flatten_expr else_expr position i instrs)
        In
        (flatten_expr test_expr `nontail i $ `jump_if_true.j::instrs)
    | `list.exprs
        Let {i instrs}.
            (LIST.reduce exprs {i instrs}
                Func {i instrs} expr.
                    Let instrs.
                        (`push::`swap::`alloc_tuple.2::`cons::instrs)
                    In
                    Let {i instrs}. (flatten_expr expr `nontail i instrs)
                    In
                    {i (`push::instrs)})
        In
        {i (`nil::instrs)}
    | `labeled.{label expr}
        Match expr
        | `tuple.exprs
            Match exprs
            | `nil {i (`labeled_empty_tuple.label::instrs)}
            | `cons._ (flatten_expr expr `nontail i $ `label.label::instrs)
            ;
        | _ (flatten_expr expr `nontail i $ `label.label::instrs)
        ;
    | `match.{expr clauses}
        Let j. i
        Let {i instrs}.
            Match position
            | `tail {i instrs}
            | `nontail {(i + 1) (`block.i::instrs)}
            ;
        In
        Let {i instrs clauses}.
            (LIST.fold clauses {i instrs []}
                Func {pat body} {i instrs clauses}.
                    Let instrs.
                        Match position
                        | `tail instrs
                        | `nontail
                            Let instrs. (`jump.j::instrs)
                            In
                            Match pat
                            | `default instrs
                            | `labeled.{_ vars}
                                Match vars
                                | `default instrs
                                | `var (`pop_vars.1::instrs)
                                | `tuple.num_vars (`pop_vars.num_vars::instrs)
                                ;
                            ;
                        ;
                    In
                    Let {i instrs}. (flatten_expr body position i instrs)
                    In
                    {(i + 1) (`block.i::instrs) ({pat i}::clauses)})
        In
        Let {clauses default}.
            (LIST.fold clauses {[] `nothing}
                Func {pat i} {clauses default}.
                    Match pat
                    | `default {clauses `just.i}
                    | `labeled.{label vars}
                        Match vars
                        | `default {({`default.label i}::clauses) default}
                        | `var {({`var.label i}::clauses) default}
                        | `tuple.num_vars
                            {({`tuple.{label num_vars} i}::clauses) default}
                        ;
                    ;)
        In
        Let instrs. (`match.{clauses default}::instrs)
        In
        (flatten_expr expr `nontail i instrs)
    ;

Where

Let binder_variables binder.
    Match binder
    | `let.{pat _} Match pat | `tuple.vars vars | `var.var [var] ;
    | `do._ []
    ;

Let binder_num_placed_variables binder.
    Match binder
    | `let.{pat _} Match pat | `tuple.n n | `var 1 ;
    | `do._ 0
    ;

Where

Let die. Prim die

Where

Let LIST. Package "list"
Let SEARCH. Package "search"
Let SORT. Package "sort"
Let STDIO. Package "stdio"
Let STRING. Package "string"
Let Z. Package "z"