From 94177ebee03e7987e68943fe0b578d4c212855aa Mon Sep 17 00:00:00 2001 From: Philippe Suter <philippe.suter@gmail.com> Date: Fri, 12 Jun 2009 16:36:00 +0000 Subject: [PATCH] --- src/funcheck/CodeExtraction.scala | 61 +++++++++++++++--------- src/funcheck/Extractors.scala | 16 +++++++ src/funcheck/purescala/Definitions.scala | 37 +++++++++++--- src/funcheck/purescala/Trees.scala | 14 ++++-- 4 files changed, 95 insertions(+), 33 deletions(-) diff --git a/src/funcheck/CodeExtraction.scala b/src/funcheck/CodeExtraction.scala index 1563e5251..c63e61cd4 100644 --- a/src/funcheck/CodeExtraction.scala +++ b/src/funcheck/CodeExtraction.scala @@ -21,32 +21,45 @@ trait CodeExtraction extends Extractors { case None => stopIfErrors; throw new Error("unreachable") } - def trav(tree: Tree): Unit = tree match { - case t : Tree if t.symbol != null && t.symbol.hasFlag(symtab.Flags.SYNTHETIC) => { - println("Synth! " + t) - } - case d @ DefDef(mods, name, tparams, vparamss, tpt, body) if !(d.symbol.hasFlag(symtab.Flags.SYNTHETIC) || d.symbol.isConstructor) => { - 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 _ => ; - } +// def trav(tree: Tree): Unit = tree match { +// case t : Tree if t.symbol != null && t.symbol.hasFlag(symtab.Flags.SYNTHETIC) => { +// println("Synth! " + t) +// } +// case d @ DefDef(mods, name, tparams, vparamss, tpt, body) if !(d.symbol.hasFlag(symtab.Flags.SYNTHETIC) || d.symbol.isConstructor) => { +// 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 _ => ; +// } - // Finds all vals in a template + def extractObject(name: Identifier, tmpl: Template): ObjectDef = { + var funDefs: List[FunDef] = Nil + var valDefs: List[ValDef] = Nil + var asserts: List[Expr] = Nil - // Finds all defs in a template + val tTrees: List[Tree] = tmpl.body - // Finds all class definitions in a template + println(tTrees) - // Finds all assertions in a template + tTrees.foreach(tree => tree match { + case cd @ ClassDef(_, name, tparams, impl) => { + println("--- " + name.toString) + println(cd.symbol.info) + println(cd.symbol.info.parents) + } + case _ => ; + }) - // Extraction of the program. + ObjectDef(name, Nil, Nil) + } + + // Extraction of the definitions. val program = unit.body match { case p @ PackageDef(name, lst) if lst.size == 0 => { unit.error(p.pos, "No top-level definition found.") @@ -61,14 +74,16 @@ trait CodeExtraction extends Extractors { case PackageDef(name, lst) => { assert(lst.size == 1) lst(0) match { - case ExObjectDef(n, templ) => Some(Program(name.toString, ObjectDef(n.toString, Nil, Nil))) + case ExObjectDef(n, templ) => Some(Program(name.toString, extractObject(n.toString, templ))) case other @ _ => unit.error(other.pos, "Expected: top-level single object.") None } } } - (new ForeachTreeTraverser(trav)).traverse(unit.body) + // Extraction of the expressions. + +// (new ForeachTreeTraverser(trav)).traverse(unit.body) stopIfErrors program.get diff --git a/src/funcheck/Extractors.scala b/src/funcheck/Extractors.scala index cd44ac23c..69fe4dec6 100644 --- a/src/funcheck/Extractors.scala +++ b/src/funcheck/Extractors.scala @@ -58,6 +58,22 @@ trait Extractors { } } + object ExAbstractClass { + /** Matches an abstract class with no type parameters, no constructor + * arguments, at most one parent class and an empty template. (Does _not_ + * match such a trait). */ + def unapply(cd: ClassDef): Option[(String)] = cd match { + case _ => None + } + } + + object ExCaseClass { + /** Matches a case class definition with no type parameters, at most one + * parent class and an empty template. */ + + + } + object ExFunctionDef { /** Matches a function with a single list of arguments, no type * parameters and regardless of its visibility. */ diff --git a/src/funcheck/purescala/Definitions.scala b/src/funcheck/purescala/Definitions.scala index 3debcbc32..dc5d6a206 100644 --- a/src/funcheck/purescala/Definitions.scala +++ b/src/funcheck/purescala/Definitions.scala @@ -5,32 +5,53 @@ object Definitions { import Trees._ import TypeTrees._ + private object UniqueID { + import scala.collection.mutable.HashMap + + private val counts: HashMap[String,Int] = new HashMap[String,Int] + + def apply(prefix: String): Int = { + val count = counts.getOrElse(prefix, 0) + counts(prefix) = count + 1 + count + } + } + /** Scopes add new definitions to the surrounding scope. */ trait Scope { import scala.collection.immutable.Map - val parentScope: Option[Scope] = None + def parentScope: Option[Scope] = None + def lookupVar(id: Identifier): Option[VarDecl] = None def lookupObject(id: Identifier): Option[ObjectDef] = None def lookupClassType(id: Identifier): Option[ClassTypeDef] = None def lookupAbstractClass(id: Identifier): Option[AbstractClassDef] = None def lookupCaseClass(id: Identifier): Option[CaseClassDef] = None def lookupClass(id: Identifier): Option[ClassDef] = None - def lookupVal(id: Identifier): Option[ValDef] = None def lookupFun(id: Identifier): Option[FunDef] = None } - /** A definition is anything "structural", ie. anything that's part of the + /** A declaration is anything "structural", ie. anything that's part of the * syntax of a program but not in an expression. */ sealed abstract class Definition extends Scope { val id: Identifier override def toString: String = PrettyPrinter(this) } - final case class VarDecl(id: Identifier, tpe: TypeTree) + /** A VarDecl declares a new identifier to be of a certain type. */ + final case class VarDecl(id: Identifier, tpe: TypeTree) { + val uniqueID: Int = UniqueID(id.toString) + override val toString: String = id + uniqueID + override def equals(other: Any) = other match { + case v: VarDecl => this.equals(v) && uniqueID == v.uniqueID + case _ => false + } + } + type VarDecls = Seq[VarDecl] /** A wrapper for a program. For now a program is simply a single object. The - * name is meaningless and we can just the package name. */ + * name is meaningless and we just use the package name. */ final case class Program(id: Identifier, mainObject: ObjectDef) extends Definition { override val parentScope = None @@ -45,7 +66,7 @@ object Definitions { /** Objects work as containers for class definitions, functions (def's) and * val's. */ - case class ObjectDef(id: Identifier, defs : Seq[Definition], invariants: Seq[Expr]) extends Definition + case class ObjectDef(id: Identifier, defs : Seq[Definition], invariants: Seq[Expr]) extends Definition /** Useful because case classes and classes are somewhat unified in some * patterns (of pattern-matching, that is) */ @@ -69,7 +90,9 @@ object Definitions { case class ClassDef(id: Identifier, parent: Option[AbstractClassDef], fields: VarDecls) extends ClassTypeDef /** Values */ - case class ValDef(id: Identifier, value: Expr) extends Definition + case class ValDef(varDecl: VarDecl, value: Expr) extends Definition { + val id: Identifier = varDecl.id + } /** Functions (= 'methods' of objects) */ case class FunDef(id: Identifier, args: VarDecls, body: Expr, precondition: Option[Expr], postcondition: Option[Expr]) extends Definition { diff --git a/src/funcheck/purescala/Trees.scala b/src/funcheck/purescala/Trees.scala index c2086f236..7c1739e1b 100644 --- a/src/funcheck/purescala/Trees.scala +++ b/src/funcheck/purescala/Trees.scala @@ -16,13 +16,21 @@ object Trees { sealed abstract class Expr extends Typed { override def toString: String = PrettyPrinter(this) - var _scope: Scope = null + private var _scope: Option[Scope] = None def scope: Scope = - if(_scope == null) + if(_scope.isEmpty) throw new Exception("Undefined scope.") else - _scope + _scope.get + + def scope_=(s: Scope): Unit = { + if(_scope.isEmpty) { + _scope = Some(s) + } else { + throw new Exception("Redefining scope.") + } + } } /** -- GitLab