{ Let analyze. analyze } Where Let analyze program. Let {_ program}. (LIST.fold program {1 []} Func package {i packages}. Let {i init functions}. (lift_functions i $ analyze_variables package.tree) In Let package. { Let path. package.path Let imports. package.imports Let init. init Let functions. functions } In {i (package::packages)}) In program Where Let analyze_variables expr. Let SET. (SEARCH.SET STRING.compare) Let MAP. (SEARCH.MAP STRING.compare Func var. var.name) In Let reduce_binder reduce_expr env depth free binders binder. Match binder | `let.{pat expr} Let {expr free}. (reduce_expr env depth free expr) In {(`let.{pat expr}::binders) free} | `do.expr Let {expr free}. (reduce_expr env depth free expr) In {(`do.expr::binders) free} ; In Define reduce_expr env depth free expr. Let trivial. {expr free} In Match expr | `true trivial | `false trivial | `num._ trivial | `str._ trivial | `package._ trivial | `prim._ trivial | `var.name Match (MAP.search env name) | `just.var Let free. If (var.depth < depth) (SET.insert free name) free In {expr free} | `nothing (die (STRING.concat ["Variable \"" name "\" is not bound."])) ; | `chain.{expr chain} Let {expr free}. (reduce_expr env depth free expr) In {`chain.{expr chain} free} | `tuple.exprs Let {exprs free}. (LIST.fold exprs {[] free} Func expr {exprs free}. Let {expr free}. (reduce_expr env depth free expr) In {(expr::exprs) free}) In {`tuple.exprs free} | `module.binders Let {binders free}. (LIST.fold binders {[] free} Func binder {binders free}. (reduce_binder reduce_expr env depth free binders binder)) In {`module.binders free} | `block.{binder_groups expr} Let {env binder_groups free}. (LIST.fold binder_groups {env [] free} Func binder_group {env binder_groups free}. Let {vars binder_group free}. (LIST.fold binder_group {[] [] free} Func binder {vars binders free}. Let {binders free}. (reduce_binder reduce_expr env depth free binders binder) Let vars. (LIST.append (binder_variables binder) vars) In {vars binders free}) In Let env. (LIST.reduce vars env Func env var. (MAP.insert env {Let name. var Let depth. depth})) In {env (binder_group::binder_groups) free}) In Let {expr free}. (reduce_expr env depth free expr) In {`block.{binder_groups expr} free} | `app.{func args} Let {func free}. (reduce_expr env depth free func) In Let {args free}. (LIST.fold args {[] free} Func arg {args free}. Let {arg free}. (reduce_expr env depth free arg) In {(arg::args) free}) In {`app.{func args} free} | `func.{self param_pats expr} Let {expr func_free}. Let env. Let depth. (depth + 1) Let vars. (LIST.fold param_pats Match self | `nothing [] | `just.var [var] ; Func pat vars. (LIST.append (pattern_variables pat) vars)) In (LIST.reduce vars env Func env var. (MAP.insert env {Let name. var Let depth. depth})) In (reduce_expr env (depth + 1) SET.empty expr) In Let free. (LIST.reduce (SET.list func_free) free Func free name. Match (MAP.search env name) | `just.var If (var.depth < depth) (SET.insert free name) free ;) In {`func.{self (SET.list func_free) param_pats expr} free} | `goto.expr Let {expr free}. (reduce_expr env depth free expr) In {`goto.expr free} | `switch.{expr clauses} Let {expr free}. (reduce_expr env depth free expr) In Let {clauses free}. (LIST.fold clauses {[] free} Func {pat body} {clauses free}. Let {body free}. Match pat | `default.pat Match pat | `just.name Let env. (MAP.insert env {Let name. name Let depth. depth}) In (reduce_expr env depth free body) | `nothing (reduce_expr env depth free body) ; | `value._ (reduce_expr env depth free body) ; In {({pat body}::clauses) free}) In {`switch.{expr clauses} free} | `cond.clauses Let {clauses free}. (LIST.fold clauses {[] free} Func {test body} {clauses free}. Let {test free}. (reduce_expr env depth free test) In Let {body free}. (reduce_expr env depth free body) In {({test body}::clauses) free}) In {`cond.clauses free} | `if.{test_expr then_expr else_expr} Let {test_expr free}. (reduce_expr env depth free test_expr) In Let {then_expr free}. (reduce_expr env depth free then_expr) In Let {else_expr free}. (reduce_expr env depth free else_expr) In {`if.{test_expr then_expr else_expr} free} | `not.expr Let {expr free}. (reduce_expr env depth free expr) In {`not.expr free} | `and.{test_expr then_expr} Let {test_expr free}. (reduce_expr env depth free test_expr) In Let {then_expr free}. (reduce_expr env depth free then_expr) In {`and.{test_expr then_expr} free} | `or.{test_expr else_expr} Let {test_expr free}. (reduce_expr env depth free test_expr) In Let {else_expr free}. (reduce_expr env depth free else_expr) In {`or.{test_expr else_expr} free} | `list.exprs Let {exprs free}. (LIST.fold exprs {[] free} Func expr {exprs free}. Let {expr free}. (reduce_expr env depth free expr) In {(expr::exprs) free}) In {`list.exprs free} | `labeled.{label expr} Let {expr free}. (reduce_expr env depth free expr) In {`labeled.{label expr} free} | `match.{expr clauses} Let {expr free}. (reduce_expr env depth free expr) In Let {clauses free}. (LIST.fold clauses {[] free} Func {pat body} {clauses free}. Let env. Match pat | `default env | `labeled.{label vars} Let names. Match vars | `default [] | `var.name [name] | `tuple.names names ; In (LIST.reduce names env Func env name. (MAP.insert env {Let name. name Let depth. depth})) ; In Let {body free}. (reduce_expr env depth free body) In {({pat body}::clauses) free}) In {`match.{expr clauses} free} ; In Let {expr _}. Let env. MAP.empty Let depth. 0 Let free. SET.empty In (reduce_expr env depth free expr) In expr Let lift_functions i expr. Let reduce_list items i funcs reduce. (LIST.fold items {i [] funcs} Func item {i items funcs}. Let {i item funcs}. (reduce i funcs item) In {i (item::items) funcs}) Let reduce_binder reduce_expr i funcs binder. Match binder | `let.{pat expr} Let {i expr funcs}. (reduce_expr i funcs expr) In {i `let.{pat expr} funcs} | `do.expr Let {i expr funcs}. (reduce_expr i funcs expr) In {i `do.expr funcs} ; In Define reduce_expr i funcs expr. Let reduce_binder i funcs binder. (reduce_binder reduce_expr i funcs binder) Let trivial. {i expr funcs} In Match expr | `true trivial | `false trivial | `num._ trivial | `str._ trivial | `package._ trivial | `prim._ trivial | `var._ trivial | `chain.{expr chain} Let {i expr funcs}. (reduce_expr i funcs expr) In {i `chain.{expr chain} funcs} | `tuple.exprs Let {i exprs funcs}. (reduce_list exprs i funcs reduce_expr) In {i `tuple.exprs funcs} | `module.binders Let {i binders funcs}. (reduce_list binders i funcs reduce_binder) In {i `module.binders funcs} | `block.{binder_groups expr} Let {i binder_groups funcs}. (reduce_list binder_groups i funcs Func i funcs binder_group. (reduce_list binder_group i funcs reduce_binder)) In Let {i expr funcs}. (reduce_expr i funcs expr) In {i `block.{binder_groups expr} funcs} | `app.{func args} Let {i func funcs}. (reduce_expr i funcs func) In Let {i args funcs}. (reduce_list args i funcs reduce_expr) In {i `app.{func args} funcs} | `func.{self free param_pats expr} Let {i expr funcs}. (reduce_expr i funcs expr) In Let closure. `closure.{i free (LIST.length param_pats)} In Let func. `func.{i self free param_pats expr} In {(i + 1) closure (func::funcs)} | `goto.expr Let {i expr funcs}. (reduce_expr i funcs expr) In {i `goto.expr funcs} | `switch.{expr clauses} Let {i expr funcs}. (reduce_expr i funcs expr) In Let {i clauses funcs}. (LIST.fold clauses {i [] funcs} Func {pat body} {i clauses funcs}. Let {i body funcs}. (reduce_expr i funcs body) In {i ({pat body}::clauses) funcs}) In {i `switch.{expr clauses} funcs} | `cond.clauses Let {i clauses funcs}. (LIST.fold clauses {i [] funcs} Func {test body} {i clauses funcs}. Let {i test funcs}. (reduce_expr i funcs test) In Let {i body funcs}. (reduce_expr i funcs body) In {i ({test body}::clauses) funcs}) In {i `cond.clauses funcs} | `if.{test_expr then_expr else_expr} Let {i test_expr funcs}. (reduce_expr i funcs test_expr) In Let {i then_expr funcs}. (reduce_expr i funcs then_expr) In Let {i else_expr funcs}. (reduce_expr i funcs else_expr) In {i `if.{test_expr then_expr else_expr} funcs} | `not.expr Let {i expr funcs}. (reduce_expr i funcs expr) In {i `not.expr funcs} | `and.{test_expr then_expr} Let {i test_expr funcs}. (reduce_expr i funcs test_expr) In Let {i then_expr funcs}. (reduce_expr i funcs then_expr) In {i `and.{test_expr then_expr} funcs} | `or.{test_expr else_expr} Let {i test_expr funcs}. (reduce_expr i funcs test_expr) In Let {i else_expr funcs}. (reduce_expr i funcs else_expr) In {i `or.{test_expr else_expr} funcs} | `list.exprs Let {i exprs funcs}. (LIST.fold exprs {i [] funcs} Func expr {i exprs funcs}. Let {i expr funcs}. (reduce_expr i funcs expr) In {i (expr::exprs) funcs}) In {i `list.exprs funcs} | `labeled.{label expr} Let {i expr funcs}. (reduce_expr i funcs expr) In {i `labeled.{label expr} funcs} | `match.{expr clauses} Let {i expr funcs}. (reduce_expr i funcs expr) In Let {i clauses funcs}. (LIST.fold clauses {i [] funcs} Func {pat body} {i clauses funcs}. Let {i body funcs}. (reduce_expr i funcs body) In {i ({pat body}::clauses) funcs}) In {i `match.{expr clauses} funcs} ; In (reduce_expr i [] expr) Where Let pattern_variables pat. Match pat | `tuple.vars vars | `var.var [var] | `ignore [] ; Let binder_variables binder. Match binder | `let.{pat _} Match pat | `tuple.vars vars | `var.var [var] ; | `do._ [] ; Where Let die. Prim die Where Let LIST. Package "list" Let SEARCH. Package "search" Let STDIO. Package "stdio" Let STRING. Package "string"