Skip to content
Snippets Groups Projects
Commit b149a8dc authored by Sapphie's avatar Sapphie
Browse files

Implement Closure Conversion

parent 77081479
No related branches found
No related tags found
No related merge requests found
......@@ -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 = ???
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment