Commit b149a8dc authored by Sapphie's avatar Sapphie
Browse files

Implement Closure Conversion

parent 77081479
......@@ -15,10 +15,10 @@ object CPSValueRepresenter extends (H.Tree => L.Tree) {
val lCnts = cnts.map(c => L.Cnt(c.name, c.args, apply(c.body)))
L.LetC(lCnts, apply(body))
case H.AppF(fun, retC, args) =>
// Assuming a function is just a pointer to its first instruction
val lFun = rewrite(fun)
val lArgs = args.map(rewrite)
L.AppF(lFun, retC, lArgs)
val f = Symbol.fresh("f")
val newBody = L.AppF(L.AtomN(f), retC, rewrite(fun) +: args.map(rewrite))
val newArgs = Seq(rewrite(fun), L.AtomL(0))
L.LetP(f, CPS.BlockGet, newArgs, newBody)
case H.AppC(cnt, args) =>
val lArgs = args.map(rewrite)
L.AppC(cnt, lArgs)
......@@ -32,10 +32,11 @@ object CPSValueRepresenter extends (H.Tree => L.Tree) {
private def transformLetF(initialFuns: Seq[H.Fun], body: H.Tree): L.LetF = {
// for each function, closes it and returns all the variables that used be free in it
def transformFunAbs(funs: Seq[H.Fun]): Seq[(L.Fun, Seq[Symbol])] = funs match {
// as well as the associated worker function
def transformFunAbs(funs: Seq[H.Fun]): Seq[(L.Fun, Seq[Symbol], Symbol)] = funs match {
case Nil => Nil
case f :: fs =>
val w = Symbol.fresh("w")
val workerFun = Symbol.fresh("w")
val envName = Symbol.fresh("env")
val newArgs = envName +: f.args
val funBody = apply(f.body)
......@@ -54,14 +55,36 @@ object CPSValueRepresenter extends (H.Tree => L.Tree) {
}
val newFunBody = argsBindings(fv, 1, Map())
val newFun = L.Fun(w, f.retC, newArgs, newFunBody)
(newFun, fv) +: transformFunAbs(fs)
val newFun = L.Fun(workerFun, f.retC, newArgs, newFunBody)
(newFun, fv, workerFun) +: transformFunAbs(fs)
}
def allocInitFun(funsAndVars: Seq[(L.Fun, Seq[Symbol], Symbol)], lastBody: L.Tree): L.Tree = {
def initFun(remVars: Seq[Symbol], counter: Int, rest: Seq[(L.Fun, Seq[Symbol], Symbol)]): L.Tree = remVars match {
case Nil => allocInitFun(rest, lastBody)
case v :: vs =>
val nextBody = initFun(vs, counter + 1, rest)
val args = Seq(L.AtomL(counter), L.AtomN(v))
L.LetP(Symbol.fresh("blockset_unused"), CPS.BlockSet, args, nextBody)
}
funsAndVars match {
case Nil => lastBody
case (fun, vars, workerFun) :: rest =>
val varInits = initFun(vars, 1, rest)
val t1 = Symbol.fresh("t1")
val primArgs = Seq(L.AtomL(0), L.AtomN(workerFun))
val nextBody = L.LetP(t1, CPS.BlockSet, primArgs, varInits)
L.LetP(fun.name, CPS.BlockAlloc(202), Seq(L.AtomL(vars.length + 1)), nextBody)
}
}
val funsAndVars = transformFunAbs(initialFuns)
val newBody = apply(body)
// TODO: tree of letFs, tree of letPs to create the closure
???
val lastBody = apply(body)
val closureAllocInit = allocInitFun(funsAndVars, lastBody)
L.LetF(funsAndVars.unzip3._1, closureAllocInit)
}
def substitute(subst: Map[Symbol, Symbol])(tree: L.Tree): L.Tree = ???
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment