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

stub for purescala pretty printer, some (really) basic extraction is in place... looking good

parent 33b377cf
No related branches found
No related tags found
No related merge requests found
...@@ -27,8 +27,7 @@ class AnalysisComponent(val global: Global, val pluginInstance: FunCheckPlugin) ...@@ -27,8 +27,7 @@ class AnalysisComponent(val global: Global, val pluginInstance: FunCheckPlugin)
// stopIfErrors // stopIfErrors
// (new ForeachTreeTraverser(findContracts)).traverse(unit.body) // (new ForeachTreeTraverser(findContracts)).traverse(unit.body)
// stopIfErrors // stopIfErrors
(new ForeachTreeTraverser(showObjects)).traverse(unit.body) (new ForeachTreeTraverser(extractCode(unit))).traverse(unit.body)
// (new ForeachTreeTraverser(mircoTraverser(unit))).traverse(unit.body)
if(pluginInstance.stopAfterAnalysis) { if(pluginInstance.stopAfterAnalysis) {
println("Analysis complete. Now terminating the compiler process.") println("Analysis complete. Now terminating the compiler process.")
......
...@@ -2,12 +2,14 @@ package funcheck ...@@ -2,12 +2,14 @@ package funcheck
import scala.tools.nsc._ import scala.tools.nsc._
import scala.tools.nsc.plugins._ import scala.tools.nsc.plugins._
import purescala.Trees._
trait CodeExtraction { trait CodeExtraction {
self: AnalysisComponent => self: AnalysisComponent =>
import global._ import global._
import StructuralExtractors._ import StructuralExtractors._
import ExpressionExtractors._
def findContracts(tree: Tree): Unit = tree match { def findContracts(tree: Tree): Unit = tree match {
case DefDef(/*mods*/ _, name, /*tparams*/ _, /*vparamss*/ _, /*tpt*/ _, body) => { case DefDef(/*mods*/ _, name, /*tparams*/ _, /*vparamss*/ _, /*tpt*/ _, body) => {
...@@ -34,8 +36,49 @@ trait CodeExtraction { ...@@ -34,8 +36,49 @@ trait CodeExtraction {
case _ => ; case _ => ;
} }
def showObjects(tree: Tree): Unit = tree match { def extractCode(unit: CompilationUnit)(tree: Tree): Unit = tree match {
case ObjectDefn(name) => println(name + " appears to be an object.") case d @ DefDef(mods, name, tparams, vparamss, tpt, body) => {
println("In: " + name)
println(d.symbol)
println(d.mods)
toPureScala(unit)(body) match {
case Some(t) => println(" the body was extracted as: " + t)
case None => println(" the body could not be extracted. Is it pure Scala?")
}
}
case _ => ; case _ => ;
} }
/** An exception thrown when non-purescala compatible code is encountered. */
sealed case class ImpureCodeEncounteredException(tree: Tree) extends Exception
/** Attempts to convert a scalac AST to a pure scala AST. */
def toPureScala(unit: CompilationUnit)(tree: Tree): Option[Expr] = {
try {
Some(scala2PureScala(unit, false)(tree))
} catch {
case ImpureCodeEncounteredException(_) => None
}
}
/** Forces conversion from scalac AST to purescala AST, throws an Exception
* if impossible. If not in 'silent mode', non-pure AST nodes are reported as
* errors. */
private def scala2PureScala(unit: CompilationUnit, silent: Boolean)(tree: Tree): Expr = {
tree match {
case ExInt32Literal(v) => IntLiteral(v)
case ExBooleanLiteral(v) => BooleanLiteral(v)
// default behaviour is to complain :)
case _ => {
if(!silent) {
unit.error(tree.pos, "Could not extract as PureScala.")
}
throw ImpureCodeEncounteredException(tree)
}
}
}
} }
...@@ -54,7 +54,7 @@ trait Extractors { ...@@ -54,7 +54,7 @@ trait Extractors {
case c @ ClassDef(_, name, tparams, impl) => { case c @ ClassDef(_, name, tparams, impl) => {
println(name.toString + " is being traversed.") println(name.toString + " is being traversed.")
println(c.symbol) println(c.symbol)
if(c.symbol.hasFlag(symtab.Flags.MODULE)) { if(c.symbol.isModuleClass) {
Some(name.toString) Some(name.toString)
} else { } else {
None None
...@@ -67,13 +67,19 @@ trait Extractors { ...@@ -67,13 +67,19 @@ trait Extractors {
object ExpressionExtractors { object ExpressionExtractors {
object ExBooleanLiteral { object ExBooleanLiteral {
/** Extracts the 'true' of 'false' constants. */
def unapply(tree: Tree): Option[Boolean] = tree match { def unapply(tree: Tree): Option[Boolean] = tree match {
case Literal(Constant(true)) => Some(true) case Literal(Constant(true)) => Some(true)
case Literal(Constant(false)) => Some(false) case Literal(Constant(false)) => Some(false)
case _ => None case _ => None
} }
} }
object ExInt32Literal {
def unapply(tree: Tree): Option[Int] = tree match {
case Literal(c @ Constant(i)) if c.tpe == IntClass.tpe => Some(c.intValue)
case _ => None
}
}
} }
object TypeExtractors { object TypeExtractors {
......
...@@ -11,7 +11,9 @@ object Trees { ...@@ -11,7 +11,9 @@ object Trees {
* correctly typed at construction time. Each AST node checks that the * correctly typed at construction time. Each AST node checks that the
* children provided satisfy whatever typing constraints are required by the * children provided satisfy whatever typing constraints are required by the
* node, and each node is then responsible for communicating its type. */ * node, and each node is then responsible for communicating its type. */
sealed abstract class Expr extends Typed sealed abstract class Expr extends Typed {
override def toString: String = PrettyPrinter(this)
}
/** /**
Go through each type, add the operations. Go through each type, add the operations.
...@@ -132,6 +134,11 @@ see examples in: ...@@ -132,6 +134,11 @@ see examples in:
val getType = Int32Type val getType = Int32Type
} }
case class UMinus(expr: Expr) extends Expr {
assert(expr.getType == Int32Type)
val getType = Int32Type
}
case class Times(lhs: Expr, rhs: Expr) extends Expr { case class Times(lhs: Expr, rhs: Expr) extends Expr {
assert(lhs.getType == Int32Type && rhs.getType == Int32Type) assert(lhs.getType == Int32Type && rhs.getType == Int32Type)
val getType = Int32Type val getType = Int32Type
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment