Commit e160007d authored by Sapphie's avatar Sapphie
Browse files

Refactor LetP translation

parent e9c08c8d
......@@ -8,9 +8,7 @@ import l3.{CPSTestPrimitive => CPST}
object CPSValueRepresenter extends (H.Tree => L.Tree) {
def apply(tree: H.Tree): L.Tree = tree match {
case H.LetP(n, prim, Seq(x), body) => applyLetPUnary(n, prim, x, body)
case H.LetP(n, prim, Seq(x, y), body) => applyLetPBinary(n, prim, x, y, body)
case H.LetP(n, prim, Seq(x, y, z), body) => applyLetPTernary(n, prim, x, y, z, body)
case H.LetP(n, prim, args, body) => applyLetP(n, prim, args, body)
case H.LetF(funs, body) =>
val lFuns = funs.map(f => L.Fun(f.name, f.retC, f.args, apply(f.body)))
L.LetF(lFuns, apply(body))
......@@ -62,56 +60,14 @@ object CPSValueRepresenter extends (H.Tree => L.Tree) {
private def getMaskR(numBits: Int): Either[H.Atom, L.Atom] = Right(L.AtomL((1 << numBits) -1))
private def applyLetP(n: H.Name, prim: L3, args: Seq[H.Atom], body: H.Tree): L.LetP = {
/*
// Only to be used in cases where you can be reasonably sure you're
// dealing with integers
private def lit2Int(l: CL3Literal): Int = {
l match {
case IntLit(i) => i.toInt
case _ => 0
}
}
private def addrConv(x: H.Atom): L.Atom = {
x match {
case H.AtomL(l) => L.AtomL(lit2Int(l))
case H.AtomN(n) => L.AtomN(n)
}
}
// */
// In hindsight, splitting the functions wasn't the cleanest decision
// TODO: refactor
// Transforms value primitives that take a single argument
private def applyLetPUnary(n: H.Name, prim: L3, x: H.Atom, body: H.Tree): L.LetP = {
prim match {
case L3.BlockAlloc(tag) => ???
case L3.BlockTag =>
// Unsure how I'm doing this, but in theory, addresses can never be
// literals, therefore we can assume x is a name
L.LetP(n, CPS.BlockTag, Seq(rewrite(x)), apply(body))
case L3.BlockLength => ???
case L3.ByteWrite => ???
case L3.CharToInt =>
L.LetP(n, CPS.ShiftRight, Seq(rewrite(x), L.AtomL(2)), apply(body))
case L3.Id =>
L.LetP(n, CPS.Id, Seq(rewrite(x)), apply(body))
case L3.IntToChar => ???
case _ => throw new Exception("Unreachable code (unary letP) " + prim.getClass)
}
}
// Transforms value primitives that take 2 arguments
private def applyLetPBinary(n: H.Name, prim: L3, x: H.Atom, y: H.Atom, body: H.Tree): L.LetP = {
val lAtomOne: Either[H.Atom, L.Atom] = Right(L.AtomL(1))
// Generates the LetP tree for a brute "untag, apply, retag" operation
def rawTree(op: CPS): L.LetP = {
lazy val x = args(0)
lazy val y = args(1)
lazy val z = args(2)
def rawBinaryTree(op: CPS): L.LetP = {
// Untag both values
tempLetP(CPS.ShiftRight, Seq(Left(x), lAtomOne)) { x1 =>
tempLetP(CPS.ShiftRight, Seq(Left(y), lAtomOne)) { y1 =>
......@@ -127,6 +83,7 @@ object CPSValueRepresenter extends (H.Tree => L.Tree) {
}
prim match {
case L3.BlockSet => ???
case L3.BlockGet =>
// In theory, x has to be a name, since there cannot be pointer literals
val block = rewrite(x)
......@@ -151,8 +108,8 @@ object CPSValueRepresenter extends (H.Tree => L.Tree) {
}
// I don't think there is a way to do this in a smart way
case L3.IntDiv => rawTree(CPS.Div)
case L3.IntMod => rawTree(CPS.Mod)
case L3.IntDiv => rawBinaryTree(CPS.Div)
case L3.IntMod => rawBinaryTree(CPS.Mod)
case L3.IntShiftLeft =>
tempLetP(CPS.Sub, Seq(Left(x), lAtomOne)) { x1 =>
......@@ -181,17 +138,26 @@ object CPSValueRepresenter extends (H.Tree => L.Tree) {
L.LetP(n, CPS.XOr, Seq(x1, rewrite(y)), apply(body))
}
case _ => throw new Exception("Unreachable code (binary letP)")
}
}
private def applyLetPTernary(n: H.Name, prim: L3, x: H.Atom, y: H.Atom, z: H.Atom, body: H.Tree): L.LetP = {
prim match {
case L3.BlockSet => ???
case _ => throw new Exception("Unreachable code (ternary letP)")
case L3.BlockAlloc(tag) => ???
case L3.BlockTag =>
// Unsure how I'm doing this, but in theory, addresses can never be
// literals, therefore we can assume x is a name
L.LetP(n, CPS.BlockTag, Seq(rewrite(x)), apply(body))
case L3.BlockLength => ???
case L3.ByteWrite => ???
case L3.CharToInt =>
L.LetP(n, CPS.ShiftRight, Seq(rewrite(x), L.AtomL(2)), apply(body))
case L3.Id =>
L.LetP(n, CPS.Id, Seq(rewrite(x)), apply(body))
case L3.IntToChar => ???
case _ => throw new Exception("Unreachable code (unary letP) " + prim.getClass)
}
}
// Creates an outer LetP, and binds the result to a name,
// then passes the name to mkBody
// Works similarly to transform in the CL3->CPS translation
......
Supports Markdown
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