summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorDavid MacIver <david.maciver@gmail.com>2008-11-09 18:52:19 +0000
committerDavid MacIver <david.maciver@gmail.com>2008-11-09 18:52:19 +0000
commit23fdf0b4e28ca528513a00c2a6675e824face34a (patch)
treebf68143c17771c2c5d310403b03a107d6236cf05 /src/compiler
parentcdbd7d9a019483ff94a479f1031592f721f2c44c (diff)
downloadscala-23fdf0b4e28ca528513a00c2a6675e824face34a.tar.gz
scala-23fdf0b4e28ca528513a00c2a6675e824face34a.tar.bz2
scala-23fdf0b4e28ca528513a00c2a6675e824face34a.zip
Separating out a single Binding from a collecti...
Separating out a single Binding from a collection of Bindings.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/matching/CodeFactory.scala19
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala20
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternNodes.scala39
3 files changed, 29 insertions, 49 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
index 6e33be24d1..24b4a908c8 100644
--- a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
+++ b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
@@ -37,17 +37,6 @@ trait CodeFactory {
val FALSE = Const(false)
val NULL = Const(null)
- // I am guessing implicits and object creation are prohibitively expensive in the
- // compiler to achieve syntax improvement, but if someone wanted to add methods such
- // as these to Tree directly, it would enable much more readable code generation.
- // Combinators would be even better, but also too expensive (?)
- //
- // class RichTree(t: Tree) {
- // def ===(rhs: Tree) = Equals(t, rhs)
- // def GTE(rhs: Tree) = GreaterThanOrEquals(t, rhs)
- // }
- // implicit def enrichTree(t: Tree) = new RichTree(t)
-
object Const {
def apply(x: Any) = Literal(Constant(x))
def unapply(x: Any) = x match {
@@ -69,14 +58,6 @@ trait CodeFactory {
final def mkIdent(sym: Symbol) = Ident(sym) setType sym.tpe
final def mk_(tpe: Type) = Ident(nme.WILDCARD) setType tpe
- /**
- * Convert a pattern binding into a list of value definitions.
- */
- final def targetParams(subst:Binding)(implicit typer : Typer):List[ValDef] = subst match {
- case NoBinding => Nil;
- case Binding(v,t,n) => ValDef(v, typer.typed(mkIdent(t)))::targetParams(n)
- }
-
/** returns A for T <: Sequence[ A ]
*/
final def getElemType_Sequence(tpe: Type): Type = {
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 263e1b6ba4..40bc0c6203 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -122,13 +122,13 @@ trait ParallelMatching {
}
/** {case ... if guard => bx} else {guardedRest} */
- case class VariableRule(subst:Binding, guard: Tree, guardedRest:Rep, bx: Int)(implicit rep:RepFactory) extends RuleApplication(rep) {
+ case class VariableRule(subst: Bindings, guard: Tree, guardedRest: Rep, bx: Int)(implicit rep:RepFactory) extends RuleApplication(rep) {
def scrutinee: Symbol = impossible
final def tree(implicit theOwner: Symbol, failTree: Tree): Tree = {
val body = typer.typed { rep.requestBody(bx, subst) }
if (guard eq EmptyTree)
return body
- val vdefs = targetParams(subst)
+ val vdefs = subst.targetParams
val typedElse = repToTree(guardedRest)
val typedIf = typer.typed { If(guard.duplicate, body, typedElse) }
@@ -192,8 +192,8 @@ trait ParallelMatching {
}
//lazy
- private def bindVars(Tag:Int, orig: Binding): Binding = {
- def myBindVars(rest:List[(Int,List[Symbol])], bnd: Binding): Binding = rest match {
+ private def bindVars(Tag: Int, orig: Bindings): Bindings = {
+ def myBindVars(rest:List[(Int,List[Symbol])], bnd: Bindings): Bindings = rest match {
case Nil => bnd
case (Tag,vs)::xs => myBindVars(xs, bnd.add(vs, scrutinee))
case (_, vs)::xs => myBindVars(xs, bnd)
@@ -587,10 +587,10 @@ trait ParallelMatching {
final def repToTree(r: Rep)(implicit theOwner: Symbol, failTree: Tree, rep: RepFactory): Tree =
r.applyRule.tree
- case class Row(pat:List[Tree], subst: Binding, guard: Tree, bx: Int) {
+ case class Row(pat: List[Tree], subst: Bindings, guard: Tree, bx: Int) {
def insert(h: Tree) = Row(h :: pat, subst, guard, bx) // prepends supplied tree
def insert(hs: List[Tree]) = Row(hs ::: pat, subst, guard, bx)
- def insert2(hs: List[Tree], b: Binding) = Row(hs ::: pat, b, guard, bx) // prepends and substitutes
+ def insert2(hs: List[Tree], b: Bindings) = Row(hs ::: pat, b, guard, bx) // prepends and substitutes
def replace(hs: List[Tree]) = Row(hs, subst, guard, bx) // replaces pattern list
}
@@ -654,7 +654,7 @@ trait ParallelMatching {
/** first time bx is requested, a LabelDef is returned. next time, a jump.
* the function takes care of binding
*/
- final def requestBody(bx:Int, subst:Binding)(implicit theOwner: Symbol): Tree = {
+ final def requestBody(bx: Int, subst: Bindings)(implicit theOwner: Symbol): Tree = {
if (bx < 0) { // is shortcut
val jlabel = shortCuts(-bx-1)
return Apply(mkIdent(jlabel), Nil)
@@ -662,7 +662,7 @@ trait ParallelMatching {
if (!isReached(bx)) { // first time this bx is requested
// might be bound elsewhere ( see `x @ unapply' ) <-- this comment refers to null check
val (vsyms, argts, vdefs) : (List[Symbol], List[Type], List[Tree]) = unzip3(
- for (v <- vss(bx) ; val substv = subst(v) ; if substv ne null) yield
+ for (v <- vss(bx) ; substv <- subst(v)) yield
(v, v.tpe, typedValDef(v, substv))
)
@@ -680,7 +680,7 @@ trait ParallelMatching {
// if some bx is not reached twice, its LabelDef is replaced with body itself
markReachedTwice(bx)
- val args: List[Ident] = vss(bx).map(subst)
+ val args: List[Ident] = vss(bx).flatMap(subst(_))
val label = labels(bx)
val body = targets(bx)
val MethodType(fmls, _) = label.tpe
@@ -698,7 +698,7 @@ trait ParallelMatching {
body match {
case _: Throw | _: Literal => // might be bound elsewhere (see `x @ unapply')
- val vdefs = for (v <- vss(bx) ; val substv = subst(v) ; if substv ne null) yield typedValDef(v, substv)
+ val vdefs = for (v <- vss(bx) ; substv <- subst(v)) yield typedValDef(v, substv)
squeezedBlock(vdefs, body.duplicate setType resultType)
case _ =>
Apply(mkIdent(label),args)
diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
index 6b78770af0..57ff8faeaf 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
@@ -12,8 +12,10 @@ import scala.tools.nsc.util.{Position, NoPosition}
* @author Burak Emir
*/
trait PatternNodes { self: transform.ExplicitOuter =>
- import global._
+ import global.{typer => _, _}
+ import analyzer.Typer;
import symtab.Flags
+
final def DBG(x: => String) = if (settings.debug.value) Console.println(x)
final def getDummies(i: Int): List[Tree] = List.make(i, EmptyTree)
@@ -115,27 +117,24 @@ trait PatternNodes { self: transform.ExplicitOuter =>
/** pvar: the symbol of the pattern variable
* temp: the temp variable that holds the actual value
- * next: next binding
*/
- case class Binding(pvar:Symbol, temp:Symbol, private val next: Binding) extends Function1[Symbol, Ident]{
- def add(vs : Iterable[Symbol], temp : Symbol): Binding =
- vs.foldLeft(this)((x, y) => Binding(y, temp, x))
-
- /** this is just to produce debug output, ListBuffer needs an equals method?! */
- override def equals(x:Any) = {
- x match {
- case NoBinding => false
- case Binding(pv2,tmp2,next2) => (pvar eq pv2) && (temp eq tmp2) && (next==next2)
- }
- }
- def apply(v:Symbol): Ident = {
- if (v eq pvar) Ident(temp).setType(v.tpe) else next(v)
+ case class Binding(pvar: Symbol, temp: Symbol)
+
+ case class Bindings(bindings: Binding*) extends Function1[Symbol, Option[Ident]] {
+ def add(vs: Iterable[Symbol], temp: Symbol): Bindings =
+ Bindings(vs.toList.map(Binding(_, temp)) ++ bindings : _*)
+
+ def apply(v: Symbol): Option[Ident] = bindings.find(_.pvar eq v) match {
+ case Some(b) => Some(Ident(b.temp) setType v.tpe)
+ case None => None // abort("Symbol " + v + " has no binding in " + bindings)
}
- }
- object NoBinding extends Binding(null, null, null) {
- override def apply(v:Symbol) = null // not found, means bound elsewhere (x @ unapply-call)
- override def toString = "."
- override def equals(x:Any) = x.isInstanceOf[Binding] && (x.asInstanceOf[Binding] eq this)
+ /**
+ * The corresponding list of value definitions.
+ */
+ final def targetParams(implicit typer: Typer): List[ValDef] =
+ bindings.toList.map{ case Binding(v, t) => ValDef(v, typer.typed(mkIdent(t))) }
}
+
+ val NoBinding: Bindings = Bindings()
}