From c4378993884567988a954e65727fe43ed59bb7f7 Mon Sep 17 00:00:00 2001
From: Philippe Suter <philippe.suter@gmail.com>
Date: Wed, 10 Jun 2009 12:32:57 +0000
Subject: [PATCH] some refactoring in the trees. Moving on to extracting
 definitions.

---
 src/funcheck/purescala/Definitions.scala   | 49 +++++++++++
 src/funcheck/purescala/PrettyPrinter.scala | 98 +++++++++++++++-------
 src/funcheck/purescala/Trees.scala         | 59 +------------
 src/funcheck/purescala/TypeTrees.scala     | 29 +++++++
 4 files changed, 148 insertions(+), 87 deletions(-)
 create mode 100644 src/funcheck/purescala/Definitions.scala
 create mode 100644 src/funcheck/purescala/TypeTrees.scala

diff --git a/src/funcheck/purescala/Definitions.scala b/src/funcheck/purescala/Definitions.scala
new file mode 100644
index 000000000..f7b638f5f
--- /dev/null
+++ b/src/funcheck/purescala/Definitions.scala
@@ -0,0 +1,49 @@
+package funcheck.purescala
+
+object Definitions {
+  import Common._
+  import Trees._
+  import TypeTrees._
+
+  sealed abstract class Definition {
+    val id: Identifier
+    override def toString: String = PrettyPrinter(this)
+  }
+
+  final case class VarDecl(id: Identifier, tpe: TypeTree)
+  type VarDecls = Seq[VarDecl]
+
+  /** Objects work as containers for class definitions, functions (def's) and
+   * val's. */
+  case class ObjectDef(id: Identifier, defs : Seq[Definition]) extends Definition
+
+  /** Useful because case classes and classes are somewhat unified in some
+   * patterns (of pattern-matching, that is) */
+  sealed trait ClassTypeDef extends Definition {
+    val id: Identifier
+    val parent: Option[AbstractClassDef]
+    val fields: VarDecls
+  }
+
+  /** Will be used at some point as a common ground for case classes (which
+   * implicitely define extractors) and explicitely defined unapply methods. */
+  sealed trait ExtractorTypeDef
+
+  /** Abstract classes. */
+  case class AbstractClassDef(id: Identifier, parent: Option[AbstractClassDef], fields: VarDecls) extends ClassTypeDef
+
+  /** Case classes. */
+  case class CaseClassDef(id: Identifier, parent: Option[AbstractClassDef], fields: VarDecls) extends ClassTypeDef with ExtractorTypeDef
+
+  /** "Regular" classes */
+  case class ClassDef(id: Identifier, parent: Option[AbstractClassDef], fields: VarDecls) extends ClassTypeDef
+  
+  /** Values */
+  case class ValDef(id: Identifier, value: Expr) extends Definition
+
+  /** Functions (= 'methods' of objects) */
+  case class FunDef(id: Identifier, args: VarDecls, body: Expr) extends Definition {
+    lazy val argTypes : Seq[TypeTree] = args.map(_.tpe) 
+    lazy val returnType : TypeTree = body.getType
+  }
+}
diff --git a/src/funcheck/purescala/PrettyPrinter.scala b/src/funcheck/purescala/PrettyPrinter.scala
index ed45f77e2..dcde2788a 100644
--- a/src/funcheck/purescala/PrettyPrinter.scala
+++ b/src/funcheck/purescala/PrettyPrinter.scala
@@ -1,48 +1,84 @@
 package funcheck.purescala
 
-import Trees._
-import Common._
 
+/** This pretty-printer uses Unicode for some operators, to make sure we
+ * distinguish PureScala from "real" Scala (and also because it's cute). */
 object PrettyPrinter {
+  import Common._
+  import Trees._
+  import TypeTrees._
+  import Definitions._
+
+  import java.lang.StringBuffer
+
   def apply(tree: Expr): String = {
     val retSB = pp(tree, new StringBuffer)
     retSB.toString
   }
 
-  import java.lang.StringBuffer
+  def apply(tpe: TypeTree): String = {
+    val retSB = pp(tpe, new StringBuffer)
+    retSB.toString
+  }
 
-  private def pp(tree: Expr, sb: StringBuffer): StringBuffer = tree match {
-    case And(exprs) => {
-      var nsb = sb
-      nsb.append("(")
-      val sz = exprs.size
-      var c = 0
-      exprs.foreach(ex => { nsb = pp(ex, nsb) ; c += 1 ; if(c < sz) nsb.append(" \u2227 ") })
-      nsb.append(")")
-      nsb
-    }
-
-    case Or(exprs) => {
-      var nsb = sb
-      nsb.append("(")
-      val sz = exprs.size
-      var c = 0
-      exprs.foreach(ex => { nsb = pp(ex, nsb) ; c += 1 ; if(c < sz) nsb.append(" \u2228 ") })
-      nsb.append(")")
-      nsb
-    }
-
-    case Not(expr) => {
-      sb.append("\u00AC(")
-      pp(expr, sb)
-      sb.append(")")
-    }
+  def apply(defn: Definition): String = {
+    val retSB = pp(defn, new StringBuffer, 0)
+    retSB.toString
+  }
 
-    case IntLiteral(v) => sb.append(v)
+  // EXPRESSIONS
+  private def ppUnary(sb: StringBuffer, expr: Expr, op: String): StringBuffer = {
+    var nsb: StringBuffer = sb
+    nsb.append(op)
+    nsb.append("(")
+    nsb = pp(expr, nsb)
+    nsb.append(")")
+    nsb
+  }
 
+  private def ppBinary(sb: StringBuffer, left: Expr, right: Expr, op: String): StringBuffer = {
+    var nsb: StringBuffer = sb
+    nsb.append("(")
+    nsb = pp(left, nsb)
+    nsb.append(op)
+    nsb = pp(right, nsb)
+    nsb.append(")")
+    nsb
+  }
+
+  private def ppNary(sb: StringBuffer, exprs: Seq[Expr], op: String): StringBuffer = {
+    var nsb = sb
+    nsb.append("(")
+    val sz = exprs.size
+    var c = 0
+
+    exprs.foreach(ex => {
+      nsb = pp(ex, nsb) ; c += 1 ; if(c < sz) nsb.append(op)
+    })
+
+    nsb.append(")")
+    nsb
+  }
+
+  private def pp(tree: Expr, sb: StringBuffer): StringBuffer = tree match {
+    case And(exprs) => ppNary(sb, exprs, " \u2227 ")            // \land
+    case Or(exprs) => ppNary(sb, exprs, " \u2228 ")             // \lor
+    case Not(Equals(l, r)) => ppBinary(sb, l, r, " \u2260 ")    // \neq
+    case Not(expr) => ppUnary(sb, expr, "\u00AC")               // \neg
+    case Equals(l,r) => ppBinary(sb, l, r, " = ")
+    case IntLiteral(v) => sb.append(v)
     case BooleanLiteral(v) => sb.append(v)
 
-    case _ => sb.append("?")
+    case _ => sb.append("Expr?")
   }
 
+  // TYPE TREES
+  private def pp(tpe: TypeTree, sb: StringBuffer): StringBuffer = tpe match {
+    case _ => sb.append("Type?")
+  }
+
+  // DEFINITIONS
+  private def pp(defn: Definition, sb: StringBuffer, lvl: Int): StringBuffer = defn match {
+    case _ => sb.append("Defn?")
+  }
 }
diff --git a/src/funcheck/purescala/Trees.scala b/src/funcheck/purescala/Trees.scala
index 75c7595b8..beeebc0f1 100644
--- a/src/funcheck/purescala/Trees.scala
+++ b/src/funcheck/purescala/Trees.scala
@@ -1,9 +1,11 @@
 package funcheck.purescala
 
-import Common._
 
 /** AST definitions for Pure Scala. */
 object Trees {
+  import Common._
+  import TypeTrees._
+  import Definitions._
 
   /* EXPRESSIONS */
 
@@ -16,16 +18,6 @@ object Trees {
   }
 
   /** 
-   Go through each type, add the operations.
-     map update
-     concatenation of lists
-     random access on lists
-     set union, intersection, etc.
-
-   Lambda abstraction and application of function values
-
-   Separately, function calls
-
    equality on sets, ADTs etc. (equality on function types?!)
 
    forall, exists - optionally bounded quantifiers
@@ -331,49 +323,4 @@ see examples in:
     assert(list.getType.isInstanceOf[ListType] && index.getType == Int32Type)
     lazy val getType = OptionType(list.getType.asInstanceOf[ListType].base)
   }
-
-  /* TYPES */
-
-  trait Typed {
-    def getType: TypeTree
-  }
-
-  sealed abstract class TypeTree
-
-  case object AnyType extends TypeTree
-  case object BooleanType extends TypeTree
-  case object Int32Type extends TypeTree
-
-  case class ListType(base: TypeTree) extends TypeTree
-  case class TupleType(bases: Seq[TypeTree]) extends TypeTree { lazy val dimension: Int = bases.length }
-  case class FunctionType(arg: TypeTree, res: TypeTree) extends TypeTree
-  case class SetType(base: TypeTree) extends TypeTree
-  case class MultisetType(base: TypeTree) extends TypeTree
-  case class MapType(from: TypeTree, to: TypeTree) extends TypeTree
-  case class ClassType(id: Identifier) extends TypeTree
-  case class CaseClassType(id: Identifier) extends TypeTree
-  case class OptionType(base: TypeTree) extends TypeTree
-
-  /* DEFINTIONS */
-
-  type VarDecl = (Identifier,TypeTree)
-  type VarDecls = Seq[VarDecl]
-
-  sealed abstract class Definition(name : Identifier)
-
-  /** Useful because case classes and classes are somewhat unified in some
-   * patterns (of pattern-matching, that is) */
-  sealed trait ClassTypeDef
-  sealed trait ExtractorTypeDef
-
-  case class CaseClassDef(name : Identifier, fields : VarDecls) extends Definition(name) with ClassTypeDef with ExtractorTypeDef
-  case class ClassDef(name : Identifier, fields : VarDecls) extends Definition(name) with ClassTypeDef
-  // case class ExtractorDef extends FunDef ...
-  
-  case class ValDef(name : Identifier, value : Expr) extends Definition(name)
-  case class FunDef(name : Identifier, args : VarDecls, body : Expr) extends Definition(name) {
-    lazy val argTypes : Seq[TypeTree] = args.map(_._2) 
-    lazy val returnType : TypeTree = body.getType
-  }
-  case class ObjectDef(name : Identifier, defs : Seq[Definition]) extends Definition(name)
 }
diff --git a/src/funcheck/purescala/TypeTrees.scala b/src/funcheck/purescala/TypeTrees.scala
new file mode 100644
index 000000000..54ec17162
--- /dev/null
+++ b/src/funcheck/purescala/TypeTrees.scala
@@ -0,0 +1,29 @@
+package funcheck.purescala
+
+object TypeTrees {
+  import Common._
+  import Trees._
+  import Definitions._
+
+  trait Typed {
+    def getType: TypeTree
+  }
+
+  sealed abstract class TypeTree {
+    override def toString: String = PrettyPrinter(this)
+  }
+
+  case object AnyType extends TypeTree
+  case object BooleanType extends TypeTree
+  case object Int32Type extends TypeTree
+
+  case class ListType(base: TypeTree) extends TypeTree
+  case class TupleType(bases: Seq[TypeTree]) extends TypeTree { lazy val dimension: Int = bases.length }
+  case class FunctionType(arg: TypeTree, res: TypeTree) extends TypeTree
+  case class SetType(base: TypeTree) extends TypeTree
+  case class MultisetType(base: TypeTree) extends TypeTree
+  case class MapType(from: TypeTree, to: TypeTree) extends TypeTree
+  case class ClassType(id: Identifier) extends TypeTree
+  case class CaseClassType(id: Identifier) extends TypeTree
+  case class OptionType(base: TypeTree) extends TypeTree
+}
-- 
GitLab