From 0f51db75093fa83a410ac7c31ef86fe07cec8582 Mon Sep 17 00:00:00 2001 From: "Emmanouil (Manos) Koukoutos" <emmanouil.koukoutos@epfl.ch> Date: Mon, 17 Mar 2014 20:18:00 +0100 Subject: [PATCH] Scope information in Definition --- src/main/scala/leon/Main.scala | 1 + .../scala/leon/purescala/Definitions.scala | 24 +++++++++++++++++++ .../scala/leon/utils/PreprocessingPhase.scala | 1 + src/main/scala/leon/utils/ScopingPhase.scala | 24 +++++++++++++++++++ 4 files changed, 50 insertions(+) create mode 100644 src/main/scala/leon/utils/ScopingPhase.scala diff --git a/src/main/scala/leon/Main.scala b/src/main/scala/leon/Main.scala index 325ba92de..77772b1cf 100644 --- a/src/main/scala/leon/Main.scala +++ b/src/main/scala/leon/Main.scala @@ -11,6 +11,7 @@ object Main { frontends.scalac.ExtractionPhase, utils.TypingPhase, FileOutputPhase, + ScopingPhase, xlang.ArrayTransformation, xlang.EpsilonElimination, xlang.ImperativeCodeElimination, diff --git a/src/main/scala/leon/purescala/Definitions.scala b/src/main/scala/leon/purescala/Definitions.scala index e3ad66bef..e2d22bbb0 100644 --- a/src/main/scala/leon/purescala/Definitions.scala +++ b/src/main/scala/leon/purescala/Definitions.scala @@ -15,11 +15,22 @@ object Definitions { sealed abstract class Definition extends Tree { val id: Identifier + var enclosing : Option[Definition] = None // The definition/scope enclosing this definition + def subDefinitions : Seq[Definition] // The enclosed scopes/definitions by this definition override def hashCode : Int = id.hashCode override def equals(that : Any) : Boolean = that match { case t : Definition => t.id == this.id case _ => false } + override def copiedFrom(o : Tree) : this.type = { + super.copiedFrom(o) + o match { + case df : Definition => enclosing = df.enclosing + case _ => // FIXME should this ever happen? + } + this + } + } /** A ValDef declares a new identifier to be of a certain type. */ @@ -28,6 +39,7 @@ object Definitions { val fixedType = tpe + def subDefinitions = Seq() override def hashCode : Int = id.hashCode override def equals(that : Any) : Boolean = that match { case t : ValDef => t.id == this.id @@ -40,6 +52,9 @@ object Definitions { /** A wrapper for a program. For now a program is simply a single object. The * name is meaningless and we just use the package name as id. */ case class Program(id: Identifier, modules: List[ModuleDef]) extends Definition { + enclosing = None + def subDefinitions = modules + def definedFunctions = modules.flatMap(_.definedFunctions) def definedClasses = modules.flatMap(_.definedClasses) def classHierarchyRoots = modules.flatMap(_.classHierarchyRoots) @@ -77,12 +92,16 @@ object Definitions { } case class TypeParameterDef(tp: TypeParameter) extends Definition { + def subDefinitions = Seq() val id = tp.id } /** Objects work as containers for class definitions, functions (def's) and * val's. */ case class ModuleDef(id: Identifier, defs : Seq[Definition]) extends Definition { + + def subDefinitions = defs + lazy val definedFunctions : Seq[FunDef] = defs.collect { case fd: FunDef => fd } lazy val definedClasses : Seq[ClassDef] = defs.collect { case ctd: ClassDef => ctd } @@ -106,6 +125,8 @@ object Definitions { sealed trait ClassDef extends Definition { self => + def subDefinitions = methods + val id: Identifier val tparams: Seq[TypeParameterDef] def fields: Seq[ValDef] @@ -206,6 +227,8 @@ object Definitions { fullBody = withPostcondition(fullBody, op) } + def subDefinitions = Seq() + // Metadata kept here after transformations var parent: Option[FunDef] = None var orig: Option[FunDef] = None @@ -220,6 +243,7 @@ object Definitions { this.fullBody = from.fullBody this.parent = from.parent this.orig = from.orig + this.enclosing = from.enclosing this.addAnnotation(from.annotations.toSeq : _*) } diff --git a/src/main/scala/leon/utils/PreprocessingPhase.scala b/src/main/scala/leon/utils/PreprocessingPhase.scala index 9d1c277e9..9a27ea1c5 100644 --- a/src/main/scala/leon/utils/PreprocessingPhase.scala +++ b/src/main/scala/leon/utils/PreprocessingPhase.scala @@ -16,6 +16,7 @@ object PreprocessingPhase extends TransformationPhase { def apply(ctx: LeonContext, p: Program): Program = { val phases = + ScopingPhase andThen MethodLifting andThen TypingPhase andThen ConvertWithOracle andThen diff --git a/src/main/scala/leon/utils/ScopingPhase.scala b/src/main/scala/leon/utils/ScopingPhase.scala new file mode 100644 index 000000000..deb2e8a13 --- /dev/null +++ b/src/main/scala/leon/utils/ScopingPhase.scala @@ -0,0 +1,24 @@ +/* Copyright 2009-2013 EPFL, Lausanne */ + +package leon.utils + +import leon._ +import purescala.Definitions._ + +object ScopingPhase extends UnitPhase[Program] { + + val name = "Scoping phase" + val description = "Insert scoping information to all definitions in the program" + + def apply(ctx: LeonContext, p: Program) { + insertScopingInformation(p, None) + } + + private def insertScopingInformation(df : Definition , parent : Option[Definition]) { + df.enclosing = parent + for (sub <- df.subDefinitions){ + insertScopingInformation(sub, Some(df)) + } + } + +} \ No newline at end of file -- GitLab