Skip to content
Snippets Groups Projects
Commit bcbb30b1 authored by Philippe Suter's avatar Philippe Suter
Browse files

Tests for Set codegen and faster evaluation of primitive arguments.

parent ddda3580
No related branches found
No related tags found
No related merge requests found
......@@ -12,6 +12,8 @@ import cafebabe.ByteCodes._
import cafebabe.ClassFileTypes._
import cafebabe.Flags._
import scala.collection.JavaConverters._
import CodeGeneration._
class CompilationUnit(val program: Program, val classes: Map[Definition, ClassFile], implicit val env: CompilationEnvironment) {
......@@ -33,8 +35,19 @@ class CompilationUnit(val program: Program, val classes: Map[Definition, ClassFi
_nextExprId
}
private[codegen] def valueToJVM(e: Expr): Any = {
compileExpression(e, Seq()).evalToJVM(Seq())
// Currently, this method is only used to prepare arguments to reflective calls.
// This means it is safe to return AnyRef (and never native values), because
// reflection needs this anyway.
private[codegen] def valueToJVM(e: Expr): AnyRef = e match {
case IntLiteral(v) =>
new java.lang.Integer(v)
case BooleanLiteral(v) =>
new java.lang.Boolean(v)
// just slightly overkill...
case _ =>
compileExpression(e, Seq()).evalToJVM(Seq())
}
private[codegen] def jvmToValue(e: AnyRef): Expr = e match {
......@@ -58,10 +71,12 @@ class CompilationUnit(val program: Program, val classes: Map[Definition, ClassFi
val elems = for (i <- 0 until tpl.getArity) yield {
jvmToValue(tpl.get(i))
}
Tuple(elems)
case _ =>
case set : runtime.Set =>
FiniteSet(set.getElements().asScala.map(jvmToValue).toSeq)
case _ =>
throw CompilationException("MEH Unsupported return value : " + e.getClass)
}
......@@ -103,7 +118,7 @@ class CompilationUnit(val program: Program, val classes: Map[Definition, ClassFi
case Int32Type | BooleanType =>
ch << IRETURN
case UnitType | TupleType(_) | SetType(_) | MapType(_, _) | AbstractClassType(_) | CaseClassType(_) =>
case UnitType | TupleType(_) | SetType(_) | MapType(_, _) | AbstractClassType(_) | CaseClassType(_) =>
ch << ARETURN
case other =>
......@@ -130,7 +145,7 @@ object CompilationUnit {
for (c <- children) {
classes += c -> compileCaseClassDef(p, c)
}
}
}
val mainClassName = defToJVMName(p, p.mainObject)
val cf = new ClassFile(mainClassName, None)
......@@ -160,7 +175,7 @@ object CompilationUnit {
METHOD_ACC_FINAL |
METHOD_ACC_STATIC
).asInstanceOf[U2])
compileFunDef(funDef, m.codeHandler)
}
......
......@@ -145,4 +145,48 @@ object Prog002 {
assert(javaEval(unit)(expr1) === CaseClass(ccCons, Seq(IntLiteral(0), CaseClass(ccCons, Seq(IntLiteral(1), CaseClass(ccNil, Seq()))))))
}
forProgram("Set Evaluation")(
"""
object Sets {
def s0() : Set[Int] = Set()
def s1() : Set[Int] = Set(1, 2, 3)
def s2() : Set[Int] = Set(2, 4, 6)
def s3() : Set[Int] = s1() ++ s2()
def s4() : Set[Int] = s2() ++ s1()
def s5() : Set[Int] = s1() ** s2()
def s6() : Set[Int] = s2() ** s1()
def s7() : Set[Int] = s1() -- s2()
def s8() : Set[Int] = s2() -- s1()
}
"""
){ out =>
assert(out.result.isDefined === true)
val unit = out.result.get
def asIntSet(e : Expr) : Option[Set[Int]] = e match {
case EmptySet(_) => Some(Set.empty)
case FiniteSet(es) =>
val ois = es.map(_ match {
case IntLiteral(v) => Some(v)
case _ => None
})
if(ois.forall(_.isDefined))
Some(ois.map(_.get).toSet)
else
None
case _ => None
}
def eval(f : String) : Option[Set[Int]] = asIntSet(javaEval(unit)(FunctionInvocation(getFunction(unit, f), Seq())))
assert(eval("s0") === Some(Set.empty[Int]))
assert(eval("s1") === Some(Set(1, 2, 3)))
assert(eval("s2") === Some(Set(2, 4, 6)))
assert(eval("s3") === Some(Set(1, 2, 3, 4, 6)))
assert(eval("s4") === Some(Set(2, 4, 6, 1, 3)))
assert(eval("s5") === Some(Set(2)))
assert(eval("s6") === Some(Set(2)))
assert(eval("s7") === Some(Set(1, 3)))
assert(eval("s8") === Some(Set(4, 6)))
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment