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

First function compiles :)

parent 6e6292ff
Branches
Tags
No related merge requests found
...@@ -4,11 +4,40 @@ package codegen ...@@ -4,11 +4,40 @@ package codegen
import purescala.Common._ import purescala.Common._
import purescala.Definitions._ import purescala.Definitions._
import cafebabe._
import cafebabe.ClassFileTypes.U2
import cafebabe.Flags._
object CodeGenPhase extends LeonPhase[Program,CompilationResult] { object CodeGenPhase extends LeonPhase[Program,CompilationResult] {
val name = "CodeGen" val name = "CodeGen"
val description = "Compiles a Leon program into Java methods" val description = "Compiles a Leon program into Java methods"
def run(ctx : LeonContext)(p : Program) : CompilationResult = { def run(ctx : LeonContext)(p : Program) : CompilationResult = {
import CodeGeneration._
implicit val env = CompilationEnvironment.fromProgram(p)
val cName = programToClassName(p)
val cf = new ClassFile(cName, None)
cf.setFlags(
(cf.getFlags | CLASS_ACC_PUBLIC | CLASS_ACC_FINAL).asInstanceOf[U2]
)
// This assumes that all functions of a given program get compiled
// as methods of a single class file.
for(funDef <- p.definedFunctions;
(_,mn) <- env.funDefToMethod(funDef)) {
val m = cf.addMethod(
typeToJVM(funDef.returnType),
mn,
funDef.args.map(a => typeToJVM(a.tpe)) : _*
)
CodeGeneration.compileFunDef(funDef, m.codeHandler)
}
CompilationResult(successful = true) CompilationResult(successful = true)
} }
} }
package leon
package codegen
import purescala.Common._
import purescala.Definitions._
import purescala.Trees._
import purescala.TypeTrees._
import cafebabe._
import cafebabe.ByteCodes._
import cafebabe.AbstractByteCodes._
object CodeGeneration {
def programToClassName(p : Program) : String = "Leon$CodeGen$" + p.mainObject.id.uniqueName
def typeToJVM(tpe : TypeTree)(implicit env : CompilationEnvironment) : String = tpe match {
case Int32Type => "I"
case BooleanType => "Z"
case _ => throw CompilationException("Unsupported type : " + tpe)
}
// Assumes the CodeHandler has never received any bytecode.
// Generates method body, and freezes the handler at the end.
def compileFunDef(funDef : FunDef, ch : CodeHandler)(implicit env : CompilationEnvironment) {
// TODO, change environment to include args.
mkExpr(funDef.getBody, ch)
funDef.returnType match {
case Int32Type | BooleanType =>
ch << IRETURN
case other =>
throw CompilationException("Unsupported return type : " + other)
}
ch.freeze
}
private def mkExpr(e : Expr, ch : CodeHandler)(implicit env : CompilationEnvironment) {
e match {
case IntLiteral(v) => ch << Ldc(v)
case BooleanLiteral(true) => ch << Ldc(1)
case BooleanLiteral(false) => ch << Ldc(0)
case Plus(l, r) =>
mkExpr(l, ch)
mkExpr(r, ch)
ch << IADD
case Minus(l, r) =>
mkExpr(l, ch)
mkExpr(r, ch)
ch << ISUB
case UMinus(e) =>
mkExpr(Minus(IntLiteral(0), e), ch)
case _ => throw CompilationException("Unsupported expr : " + e)
}
}
}
package leon
package codegen
import purescala.Common._
import purescala.Definitions._
abstract class CompilationEnvironment() {
// Should contain:
// - a mapping of function defs to class + method name
// - a mapping of class defs to class names
// - a mapping of class fields to fields
def funDefToMethod(funDef : FunDef) : Option[(String,String)]
}
object CompilationEnvironment {
def fromProgram(p : Program) : CompilationEnvironment = {
val className = CodeGeneration.programToClassName(p)
val fs = p.definedFunctions.filter(_.hasImplementation)
val fPairs : Map[FunDef,String] = fs.map(fd => (fd -> fd.id.uniqueName)).toMap
new CompilationEnvironment {
def funDefToMethod(funDef : FunDef) = fPairs.get(funDef).map(n => (className, n))
}
}
}
package leon
package codegen
case class CompilationException(msg : String) extends Exception {
override def getMessage = msg
}
object Prog001 { object Prog001 {
def plus(x : Int, y : Int) : Int = x + y def fortyTwo() = 42
// def plus(x : Int, y : Int) = x + y
} }
No preview for this file type
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment