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