From 901ce7a85bec6cda170ec0949bada3f9c8d6213a Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 11 Oct 2009 18:40:08 +0000 Subject: More transitioning bindings to pattern vars. --- src/compiler/scala/tools/nsc/matching/Matrix.scala | 19 +++++++++-- .../tools/nsc/matching/ParallelMatching.scala | 38 +++++++++++++--------- .../scala/tools/nsc/matching/PatternBindings.scala | 24 ++------------ 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/compiler/scala/tools/nsc/matching/Matrix.scala b/src/compiler/scala/tools/nsc/matching/Matrix.scala index cd66c9c5ce..96b665f2ea 100644 --- a/src/compiler/scala/tools/nsc/matching/Matrix.scala +++ b/src/compiler/scala/tools/nsc/matching/Matrix.scala @@ -96,6 +96,7 @@ trait Matrix extends MatrixAdditions { ) { def tvars = roots map (_.lhs) def valDefs = roots map (_.valDef) + override def toString() = "MatrixInit(roots = %s, %d cases)".format(pp(roots), cases.size) } implicit def pvlist2pvgroup(xs: List[PatternVar]): PatternVarGroup = @@ -104,6 +105,20 @@ trait Matrix extends MatrixAdditions { object PatternVarGroup { def apply(xs: PatternVar*) = new PatternVarGroup(xs.toList) def apply(xs: List[PatternVar]) = new PatternVarGroup(xs) + + // XXX - transitional + def fromBindings(vlist: List[Binding], freeVars: List[Symbol] = Nil) = { + def vmap(v: Symbol): Option[Binding] = vlist find (_.pvar eq v) + val info = + if (freeVars.isEmpty) vlist + else (freeVars map vmap).flatten + + val xs = + for (Binding(lhs, rhs) <- info) yield + new PatternVar(lhs, Ident(rhs) setType lhs.tpe, !(rhs hasFlag TRANS_FLAG)) + + new PatternVarGroup(xs) + } } val emptyPatternVarGroup = PatternVarGroup() @@ -135,8 +150,8 @@ trait Matrix extends MatrixAdditions { class PatternVar(val lhs: Symbol, val rhs: Tree, val checked: Boolean) { def sym = lhs def valsym = valDef.symbol - - def tpe = valsym.tpe // XXX how will sym.tpe differ from sym.tpe ? + // XXX how will valsym.tpe differ from sym.tpe ? + def tpe = valsym.tpe lazy val ident = ID(lhs) lazy val valDef = tracing("typedVal", typer typedValDef (VAL(lhs) === rhs)) diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index 6ba9ad3b18..0e08c0eaf5 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -57,20 +57,15 @@ trait ParallelMatching extends ast.TreeDSL * the function takes care of binding */ final def requestBody(bx: Int, subst: Bindings): Tree = { - implicit val ctx = context val target @ FinalState(tbx, body, freeVars) = targets(bx) - val substInfo = subst infoFor freeVars - import substInfo._ - - // XXX when is this not true? - // assert(tbx == bx) + val pvgroup = PatternVarGroup.fromBindings(subst.get(), freeVars) // shortcut if (bx < 0) Apply(ID(shortCuts(-bx-1)), Nil) // first time this bx is requested - might be bound elsewhere - else if (target.isNotReached) target.createLabelBody(bx, patternVars, patternValDefs) + else if (target.isNotReached) target.createLabelBody(bx, pvgroup) // call label "method" if possible - else target.getLabelBody(idents, patternValDefs) + else target.getLabelBody(pvgroup) } /** the injection here handles alternatives and unapply type tests */ @@ -179,7 +174,10 @@ trait ParallelMatching extends ast.TreeDSL def apply(i: Int): Pattern = ps(i) def pzip() = ps.zipWithIndex - def pzip[T](others: List[T]) = ps zip others + def pzip[T](others: List[T]) = { + assert(ps.size == others.size, "Internal error: ps = %s, others = %s".format(ps, others)) + ps zip others + } // Any unapply - returns Some(true) if a type test is needed before the unapply can // be called (e.g. def unapply(x: Foo) = { ... } but our scrutinee is type Any.) @@ -223,6 +221,10 @@ trait ParallelMatching extends ast.TreeDSL /***** Rule Applications *****/ sealed abstract class RuleApplication { + // def isFinal = false + // def body = tree + // def freeVars = (scrut.pv :: rest.tvars).syms + def pmatch: PatternMatch def rest: Rep def cond: Tree @@ -242,7 +244,7 @@ trait ParallelMatching extends ast.TreeDSL pvgroup: PatternVarGroup = emptyPatternVarGroup, includeScrut: Boolean = true): Rep = { - val scrutpvs = if (includeScrut) List(pmatch.scrut.pv) else Nil + val scrutpvs = if (includeScrut) List(scrut.pv) else Nil make(pvgroup.pvs ::: scrutpvs ::: rest.tvars, rows) } @@ -263,10 +265,9 @@ trait ParallelMatching extends ast.TreeDSL lazy val success = requestBody(bx, subst) lazy val failure = guardedRest.toTree - final def tree(): Tree = { - implicit val ctx = context - squeezedBlock(subst.infoForAll.patternValDefs, codegen) - } + lazy val pvgroup = PatternVarGroup.fromBindings(subst.get()) + + final def tree(): Tree = squeezedBlock(pvgroup.valDefs, codegen) } /** Mixture rule for all literal ints (and chars) i.e. hopefully a switch @@ -721,7 +722,10 @@ trait ParallelMatching extends ast.TreeDSL abort(msg.format(name, pp(labelParamTypes), pp(idents), pp(vdefs))) } - def createLabelBody(index: Int, args: List[Symbol], vdefs: List[Tree]) = { + def createLabelBody(index: Int, pvgroup: PatternVarGroup) = { + def args = pvgroup.syms + def vdefs = pvgroup.valDefs + val name = "body%" + index require(_labelSym == null) referenceCount += 1 @@ -744,7 +748,9 @@ trait ParallelMatching extends ast.TreeDSL ifLabellable(vdefs, squeezedBlock(vdefs, label)) } - def getLabelBody(idents: List[Tree], vdefs: List[Tree]): Tree = { + def getLabelBody(pvgroup: PatternVarGroup): Tree = { + def idents = pvgroup map (_.rhs) + def vdefs = pvgroup.valDefs referenceCount += 1 // if (idents.size != labelParamTypes.size) // consistencyFailure(idents, vdefs) diff --git a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala index 6c44cde880..e8dec7ff1d 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala @@ -115,39 +115,19 @@ trait PatternBindings extends ast.TreeDSL if (tvar.info containsTp WildcardType) tvar setInfo pvar.info - def toIdent = Ident(tvar) setType pvar.tpe - def castIfNeeded = - if (tvar.tpe <:< pvar.tpe) ID(tvar) - else ID(tvar) AS_ANY pvar.tpe - override def toString() = pp(pvar -> tvar) } - case class BindingsInfo(xs: List[Binding]) { - def patternVars = xs map (_.pvar) - def temporaryVars = xs map (_.tvar) - def idents = xs map (_.toIdent) - - def patternValDefs(implicit context: MatrixContext) = - for (b @ Binding(pvar, tvar) <- xs) yield - context.typedValDef(pvar, b.toIdent) - } - - class Bindings(private val vlist: List[Binding]) extends Function1[Symbol, Option[Ident]] { + class Bindings(private val vlist: List[Binding]) { if (!vlist.isEmpty) traceCategory("Bindings", this.toString) - def vmap(v: Symbol): Option[Binding] = vlist find (_.pvar eq v) - - // filters the given list down to those defined in these bindings - def infoFor(vs: List[Symbol]) = BindingsInfo(vs map vmap flatten) - def infoForAll = BindingsInfo(vlist) + def get() = vlist def add(vs: Iterable[Symbol], tvar: Symbol): Bindings = { val newBindings = vs.toList map (v => Binding(v, tvar)) new Bindings(newBindings ++ vlist) } - def apply(v: Symbol): Option[Ident] = vmap(v) map (_.toIdent) override def toString() = pp(vlist) } -- cgit v1.2.3