Commit 68ff58c4 authored by Sapphie's avatar Sapphie
Browse files

Import value repr skeleton

parent a33194fe
......@@ -165,3 +165,84 @@ object CPSInterpreterHigh extends CPSInterpreter(SymbolicCPSTreeModule)
case (Eq, Seq(v1, v2)) => v1 == v2
}
}
class CPSInterpreterLow(log: SymbolicCPSTreeModuleLow.Tree => Unit)
extends CPSInterpreter(SymbolicCPSTreeModuleLow, log)
with (SymbolicCPSTreeModuleLow.Tree => TerminalPhaseResult) {
import treeModule._
import CPSValuePrimitive._
import CPSTestPrimitive._
import scala.language.implicitConversions
protected case class BlockV(addr: Bits32,
tag: L3BlockTag,
contents: Array[Value])
extends Value
protected case class BitsV(value: Bits32) extends Value
private var nextBlockAddr = 0
protected def allocBlock(tag: L3BlockTag, contents: Array[Value]): BlockV = {
val block = BlockV(nextBlockAddr, tag, contents)
nextBlockAddr += 4
block
}
private implicit def valueToBits(v: Value): Bits32 = v match {
case BlockV(addr, _, _) => addr
case BitsV(value) => value
case _: FunV | _: CntV => sys.error(s"cannot convert $v to bits")
}
protected def extractInt(v: Value): Int = v match { case BitsV(i) => i }
protected def wrapFunV(funV: FunV): Value = funV
protected def unwrapFunV(v: Value): FunV = v.asInstanceOf[FunV]
protected def evalLit(l: Literal): Value = BitsV(l)
protected def evalValuePrim(p: ValuePrimitive, args: Seq[Value]): Value =
(p, args) match {
case (Add, Seq(v1, v2)) => BitsV(v1 + v2)
case (Sub, Seq(v1, v2)) => BitsV(v1 - v2)
case (Mul, Seq(v1, v2)) => BitsV(v1 * v2)
case (Div, Seq(v1, v2)) => BitsV(v1 / v2)
case (Mod, Seq(v1, v2)) => BitsV(v1 % v2)
case (ShiftLeft, Seq(v1, v2)) => BitsV(v1 << v2)
case (ShiftRight, Seq(v1, v2)) => BitsV(v1 >> v2)
case (And, Seq(v1, v2)) => BitsV(v1 & v2)
case (Or, Seq(v1, v2)) => BitsV(v1 | v2)
case (XOr, Seq(v1, v2)) => BitsV(v1 ^ v2)
case (ByteRead, Seq()) => BitsV(readByte())
case (ByteWrite, Seq(c)) => writeByte(c); BitsV(0)
case (BlockAlloc(t), Seq(BitsV(s))) =>
allocBlock(t, Array.fill(s)(BitsV(0)))
case (BlockTag, Seq(BlockV(_, t, _))) => BitsV(t)
case (BlockLength, Seq(BlockV(_, _, c))) => BitsV(c.length)
case (BlockGet, Seq(BlockV(_, _, c), BitsV(i))) => c(i)
case (BlockSet, Seq(BlockV(_, _, c), BitsV(i), v)) =>
c(i) = v; BitsV(0)
case (Id, Seq(o)) => o
}
protected def evalTestPrim(p: TestPrimitive, args: Seq[Value]): Boolean =
(p, args) match {
case (Lt, Seq(v1, v2)) => v1 < v2
case (Le, Seq(v1, v2)) => v1 <= v2
case (Eq, Seq(v1, v2)) => v1 == v2
}
}
object CPSInterpreterLow extends CPSInterpreterLow(_ => ())
object CPSInterpreterLowNoCC extends CPSInterpreterLow(_ => ()) {
override protected def wrapFunV(funV: FunV): Value =
allocBlock(BlockTag.Function.id, Array(funV))
override protected def unwrapFunV(v: Value): FunV = v match {
case BlockV(_, _, Array(funV: FunV)) => funV
}
}
package l3
/**
* A class for value-producing primitives.
*
* @author Michel Schinz <Michel.Schinz@epfl.ch>
*/
sealed abstract class CPSValuePrimitive(val name: String) {
override def toString: String = name
}
object CPSValuePrimitive {
case object Add extends CPSValuePrimitive("+")
case object Sub extends CPSValuePrimitive("-")
case object Mul extends CPSValuePrimitive("*")
case object Div extends CPSValuePrimitive("/")
case object Mod extends CPSValuePrimitive("%")
case object ShiftLeft extends CPSValuePrimitive("shift-left")
case object ShiftRight extends CPSValuePrimitive("shift-right")
case object And extends CPSValuePrimitive("and")
case object Or extends CPSValuePrimitive("or")
case object XOr extends CPSValuePrimitive("xor")
case object ByteRead extends CPSValuePrimitive("byte-read")
case object ByteWrite extends CPSValuePrimitive("byte-write")
case class BlockAlloc(tag: L3BlockTag)
extends CPSValuePrimitive(s"block-alloc-${tag}")
case object BlockTag extends CPSValuePrimitive("block-tag")
case object BlockLength extends CPSValuePrimitive("block-length")
case object BlockGet extends CPSValuePrimitive("block-get")
case object BlockSet extends CPSValuePrimitive("block-set!")
case object Id extends CPSValuePrimitive("id")
}
/**
* A class for testing primitives.
*
* @author Michel Schinz <Michel.Schinz@epfl.ch>
*/
sealed abstract class CPSTestPrimitive(val name: String) {
override def toString: String = name
}
object CPSTestPrimitive {
case object Lt extends CPSTestPrimitive("<")
case object Le extends CPSTestPrimitive("<=")
case object Eq extends CPSTestPrimitive("=")
}
......@@ -52,3 +52,15 @@ object SymbolicCPSTreeModule extends CPSTreeModule {
type ValuePrimitive = L3ValuePrimitive
type TestPrimitive = L3TestPrimitive
}
/**
* Module for "low-level" CPS trees: the only literal values are
* integers, and the primitives work on integers and/or pointers to
* heap-allocated blocks.
*/
object SymbolicCPSTreeModuleLow extends CPSTreeModule {
type Name = Symbol
type Literal = Bits32
type ValuePrimitive = CPSValuePrimitive
type TestPrimitive = CPSTestPrimitive
}
......@@ -85,4 +85,7 @@ abstract class CPSTreeChecker[T <: CPSTreeModule](treeModule: T)
object CPSTreeChecker {
implicit object SymbolicCPSTreeChecker
extends CPSTreeChecker(SymbolicCPSTreeModule)
implicit object SymbolicCPSTreeLowChecker
extends CPSTreeChecker(SymbolicCPSTreeModuleLow)
}
......@@ -50,4 +50,6 @@ class CPSTreeFormatter[T <: CPSTreeModule](treeModule: T)
object CPSTreeFormatter {
implicit object SymbolicCPSTreeFormatter
extends CPSTreeFormatter(SymbolicCPSTreeModule)
implicit object SymbolicCPSTreeLowFormatter
extends CPSTreeFormatter(SymbolicCPSTreeModuleLow)
}
package l3
object CPSValueRepresenter extends (Any => Nothing) {
def apply(tree: Any): Nothing =
???
}
......@@ -13,9 +13,10 @@ object Main {
def main(args: Array[String]): Unit = {
val backEnd: Tree => TerminalPhaseResult = (
CL3ToCPSTranslator
andThen treePrinter("---------- After translation to CPS")
andThen CPSValueRepresenter
andThen treePrinter("---------- After value representation")
andThen treeChecker
andThen CPSInterpreterHigh
andThen CPSInterpreterLowNoCC
)
val basePath = Paths.get(".").toAbsolutePath
......
......@@ -53,3 +53,7 @@ object ExamplesTests1 extends TestSuite with ExamplesTests {
object ExamplesTests2 extends TestSuite with ExamplesTests {
val backEnd = L3Tester.backEnd2
}
object ExamplesTests3 extends TestSuite with ExamplesTests {
val backEnd = L3Tester.backEnd3
}
......@@ -49,4 +49,10 @@ object L3Tester {
CL3ToCPSTranslator
andThen CPSInterpreterHigh
)
val backEnd3 = (
CL3ToCPSTranslator
andThen CPSValueRepresenter
andThen CPSInterpreterLowNoCC
)
}
......@@ -89,3 +89,7 @@ object SyntheticTests1 extends TestSuite with SyntheticTests {
object SyntheticTests2 extends TestSuite with SyntheticTests {
val backEnd = L3Tester.backEnd2
}
object SyntheticTests3 extends TestSuite with SyntheticTests {
val backEnd = L3Tester.backEnd3
}
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