{ 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"