diff --git a/ParseMe.scala b/ParseMe.scala index 06e6c03b278f693138a65439011ed44d3720c705..bfe3dfc96cbd7ed37879acb25179d4cb1a270c61 100644 --- a/ParseMe.scala +++ b/ParseMe.scala @@ -2,6 +2,7 @@ import scala.collection.immutable.Set object ParseMe { sealed abstract class Tree + //case class Node(value: Int) extends Tree case class Node(left: Tree, value: Int, right: Tree) extends Tree case class Leaf() extends Tree diff --git a/src/funcheck/CodeExtraction.scala b/src/funcheck/CodeExtraction.scala index c9d257546d391a892612b7916dbb7e42891b563f..a391b51b95505291fbff664be8009815bad73f25 100644 --- a/src/funcheck/CodeExtraction.scala +++ b/src/funcheck/CodeExtraction.scala @@ -19,6 +19,8 @@ trait CodeExtraction extends Extractors { private lazy val setTraitSym = definitions.getClass("scala.collection.immutable.Set") private val varSubsts: scala.collection.mutable.Map[Identifier,Function0[Expr]] = scala.collection.mutable.Map.empty[Identifier,Function0[Expr]] + private val classesToClasses: scala.collection.mutable.Map[Symbol,ClassTypeDef] = + scala.collection.mutable.Map.empty[Symbol,ClassTypeDef] def extractCode(unit: CompilationUnit): Program = { import scala.collection.mutable.HashMap @@ -70,6 +72,8 @@ trait CodeExtraction extends Extractors { val scalaClassSyms: scala.collection.mutable.Map[Symbol,Identifier] = scala.collection.mutable.Map.empty[Symbol,Identifier] + val scalaClassArgs: scala.collection.mutable.Map[Symbol,Seq[(Identifier,Tree)]] = + scala.collection.mutable.Map.empty[Symbol,Seq[(Identifier,Tree)]] val scalaClassNames: scala.collection.mutable.Set[Identifier] = scala.collection.mutable.Set.empty[Identifier] @@ -84,16 +88,14 @@ trait CodeExtraction extends Extractors { scalaClassNames += o2 } } - case ExCaseClass(o2, sym, tpl) => { + case ExCaseClass(o2, sym, args) => { if(scalaClassNames.contains(o2)) { unit.error(t.pos, "A class with the same name already exists.") } else { - scalaClassSyms += (sym -> o2) + scalaClassSyms += (sym -> o2) scalaClassNames += o2 + scalaClassArgs += (sym -> args) } - // println("***") - // println(tpl) - // println("***") } case _ => ; } @@ -101,8 +103,6 @@ trait CodeExtraction extends Extractors { stopIfErrors - val classesToClasses: scala.collection.mutable.Map[Symbol,ClassTypeDef] = - scala.collection.mutable.Map.empty[Symbol,ClassTypeDef] scalaClassSyms.foreach(p => { if(p._1.isAbstractClass) { @@ -113,7 +113,6 @@ trait CodeExtraction extends Extractors { }) classesToClasses.foreach(p => { - println(p._1) val superC: List[ClassTypeDef] = p._1.tpe.baseClasses.filter(bcs => scalaClassSyms.exists(pp => pp._1 == bcs) && bcs != p._1).map(s => classesToClasses(s)).toList val superAC: List[AbstractClassDef] = superC.map(c => { @@ -132,12 +131,14 @@ trait CodeExtraction extends Extractors { if(superAC.length == 1) { p._2.parent = Some(superAC.head) } - }) - // TODO - // add all fields to case classes + if(p._2.isInstanceOf[CaseClassDef]) { + // this should never fail + val ccargs = scalaClassArgs(p._1) + p._2.asInstanceOf[CaseClassDef].fields = ccargs.map(cca => VarDecl(cca._1, st2ps(cca._2.tpe))) + } + }) - // println(classesToClasses) classDefs = classesToClasses.valuesIterator.toList tmpl.body.foreach( @@ -153,10 +154,6 @@ trait CodeExtraction extends Extractors { } ) - // val theSym = new purescala.Symbols.ObjectSymbol(name, classSyms.reverse, objectSyms.reverse) - // we register the tree associated to the symbol to be able to fill in - // the rest later - // symbolDefMap(theSym) = tmpl val theDef = new ObjectDef(name, objectDefs.reverse ::: classDefs.reverse ::: funDefs.reverse, Nil) theDef @@ -270,6 +267,10 @@ trait CodeExtraction extends Extractors { case tpe if tpe == IntClass.tpe => Int32Type case tpe if tpe == BooleanClass.tpe => BooleanType case TypeRef(_, sym, btt :: Nil) if sym == setTraitSym => SetType(rec(btt)) + case TypeRef(_, sym, Nil) if classesToClasses.keySet.contains(sym) => classesToClasses(sym) match { + case a: AbstractClassDef => AbstractClassType(a) + case c: CaseClassDef => CaseClassType(c) + } case _ => { if(!silent) { diff --git a/src/funcheck/Extractors.scala b/src/funcheck/Extractors.scala index 72c4d6f785b4a59f108d580e6221f96e6ee331d5..7711d5373ab1a3f3e754861e892f082f6bd8b182 100644 --- a/src/funcheck/Extractors.scala +++ b/src/funcheck/Extractors.scala @@ -74,13 +74,16 @@ trait Extractors { } object ExCaseClass { - def unapply(cd: ClassDef): Option[(String,Symbol,Tree)] = cd match { + def unapply(cd: ClassDef): Option[(String,Symbol,Seq[(String,Tree)])] = cd match { case ClassDef(_, name, tparams, impl) if (cd.symbol.isCase && !cd.symbol.isAbstractClass && tparams.isEmpty && impl.body.size >= 8) => { - impl.children.filter(child => child match { - case DefDef(_, nn, _, _, _, _) => true + val constructor: DefDef = impl.children.find(child => child match { + case ExConstructorDef() => true case _ => false - }).foreach(child => println(child)) - Some((name.toString, cd.symbol, impl)) + }).get.asInstanceOf[DefDef] + + val args = constructor.vparamss(0).map(vd => (vd.name.toString, vd.tpt)) + + Some((name.toString, cd.symbol, args)) } case _ => None } @@ -95,7 +98,7 @@ trait Extractors { object ExConstructorDef { def unapply(dd: DefDef): Boolean = dd match { - case DefDef(_, name, tparams, vparamss, tpt, rhs) if(name.toString == "<init>" && tparams.isEmpty && vparamss.size == 1 && vparamss(0).size == 0) => true + case DefDef(_, name, tparams, vparamss, tpt, rhs) if(name.toString == "<init>" && tparams.isEmpty && vparamss.size == 1) => true case _ => false } } diff --git a/src/purescala/Definitions.scala b/src/purescala/Definitions.scala index 48d22082e095bb99703b469d5419f5165b592224..68d0fe5af909e065ace403188482a8bdd6ca080b 100644 --- a/src/purescala/Definitions.scala +++ b/src/purescala/Definitions.scala @@ -18,22 +18,22 @@ object Definitions { } /** Scopes add new definitions to the surrounding scope. */ - trait Scope { - import scala.collection.immutable.Map - - 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 lookupFun(id: Identifier): Option[FunDef] = None - } + // trait Scope { + // import scala.collection.immutable.Map + + // 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 lookupFun(id: Identifier): Option[FunDef] = None + // } /** 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 { + sealed abstract class Definition /*extends Scope*/ { val id: Identifier override def toString: String = PrettyPrinter(this) } @@ -58,15 +58,15 @@ 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, mainObject: ObjectDef) extends Definition { - override val parentScope = None - - override def lookupObject(id: Identifier) = { - if(id == mainObject.id) { - Some(mainObject) - } else { - None - } - } + //override val parentScope = None + + // override def lookupObject(id: Identifier) = { + // if(id == mainObject.id) { + // Some(mainObject) + // } else { + // None + // } + // } } /** Objects work as containers for class definitions, functions (def's) and @@ -109,10 +109,10 @@ object Definitions { } /** "Regular" classes */ - class ClassDef(val id: Identifier, var parent: Option[AbstractClassDef]) extends ClassTypeDef { - var fields: VarDecls = Nil - val isAbstract = false - } + //class ClassDef(val id: Identifier, var parent: Option[AbstractClassDef]) extends ClassTypeDef { + // var fields: VarDecls = Nil + // val isAbstract = false + //} /** Values */ case class ValDef(varDecl: VarDecl, value: Expr) extends Definition { diff --git a/src/purescala/PrettyPrinter.scala b/src/purescala/PrettyPrinter.scala index 3d302749deabcfc89866ee948e9287e1ae62f990..aa17e1d16daaa28c08e044e4f7faaa4b21bd5fad 100644 --- a/src/purescala/PrettyPrinter.scala +++ b/src/purescala/PrettyPrinter.scala @@ -103,6 +103,7 @@ object PrettyPrinter { case Int32Type => sb.append("Int") case BooleanType => sb.append("Boolean") case SetType(bt) => pp(bt, sb.append("Set[")).append("]") + case c: ClassType => sb.append(c.classDef.id) case _ => sb.append("Type?") } @@ -162,9 +163,9 @@ object PrettyPrinter { val sz = varDecls.size varDecls.foreach(vd => { - nsb = pp(vd.tpe, nsb) - nsb.append(" ") nsb.append(vd.id.toString) + nsb.append(": ") + nsb = pp(vd.tpe, nsb) if(c < sz - 1) { nsb.append(", ") } diff --git a/src/purescala/TypeTrees.scala b/src/purescala/TypeTrees.scala index f6f52a2726018df7175cbdbfc1e0a6172577084c..5bd212f146b1804f2b589558d8bf0f46863924c5 100644 --- a/src/purescala/TypeTrees.scala +++ b/src/purescala/TypeTrees.scala @@ -37,7 +37,12 @@ object TypeTrees { 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 + + sealed abstract class ClassType extends TypeTree { + val classDef: ClassTypeDef + } + + case class AbstractClassType(classDef: AbstractClassDef) extends ClassType + case class CaseClassType(classDef: CaseClassDef) extends ClassType case class OptionType(base: TypeTree) extends TypeTree }