summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBurak Emir <emir@epfl.ch>2006-09-06 23:28:18 +0000
committerBurak Emir <emir@epfl.ch>2006-09-06 23:28:18 +0000
commit206233021b29aaa890f08858e46e6c7491452b19 (patch)
tree4ea69b0b577cdc9fd83a8d3f890d0c4868551c32
parentf2b8a606c1904b97a9f15a57ea395b40f6b0ec18 (diff)
downloadscala-206233021b29aaa890f08858e46e6c7491452b19.tar.gz
scala-206233021b29aaa890f08858e46e6c7491452b19.tar.bz2
scala-206233021b29aaa890f08858e46e6c7491452b19.zip
added indexOf method to Iterable, added squeeze...
added indexOf method to Iterable, added squeezeBlock code optimization to PatternMatcher
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternMatchers.scala85
-rw-r--r--src/library/scala/Iterable.scala15
-rw-r--r--src/library/scala/xml/Unparsed.scala36
-rw-r--r--test/files/jvm/xmlmore.check3
-rw-r--r--test/files/jvm/xmlmore.scala7
5 files changed, 122 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
index 7e5bfc10e8..6269e1a86f 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
@@ -58,6 +58,10 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
*/
protected var root: PatternNode = _
+ // statistics
+ var nremoved = 0
+ var nsubstituted = 0
+
/** the symbol of the result variable
*/
//protected var resultVar: Symbol = _
@@ -67,7 +71,6 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
/** init method, also needed in subclass AlgebraicMatcher
*/
def initialize(selector: Tree, owner: Symbol, handleOuter:Tree=>Tree): Unit = {
-
this.owner = owner
this.selector = selector
this.handleOuter = handleOuter
@@ -78,6 +81,8 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
Ident(root.symbol).setType(root.tpe));
//Konsole.println("resultType = "+resultType);
//this.optimize = this.optimize && (settings.target.value == "jvm");
+ if(settings.statistics.value)
+ Console.println("could remove "+(nremoved+nsubstituted)+" ValDefs, "+nremoved+" by deleting and "+nsubstituted+" by substitution")
}
// ---
@@ -237,6 +242,57 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
newVar(pos, cunit.fresh.newName("temp"), tpe).setFlag(Flags.SYNTHETIC)
// ---
+ def squeezedBlock(tree:Block) = {
+ class RefTraverser(sym:Symbol) extends Traverser {
+ var nref = 0
+ var nsafeRef = 0
+ override def traverse(tree: Tree) = tree match {
+ //case t:This => incrThis
+ case t:Ident if t.symbol == sym =>
+ nref = nref + 1
+ if(sym.owner == currentOwner) { // oldOwner should match currentOwner
+ nsafeRef = nsafeRef + 1
+ } /*else if(nref == 1) {
+ Console.println("sym owner: "+sym.owner+" but currentOwner = "+currentOwner)
+ }*/
+ case t if nref > 1 => // abort, no story to tell
+
+ case t => super . traverse (t)
+ }
+ }
+ class Subst(sym:Symbol,rhs:Tree) extends Transformer {
+ var stop = false
+ override def transform(tree: Tree) = tree match {
+ //case t:This => incrThis
+ case t:Ident if t.symbol == sym =>
+ stop = true
+ rhs
+ case t if stop =>
+ t
+ case t =>
+ super . transform (t)
+ }
+ }
+ tree match {
+ case Block((vd:ValDef):: rest, exp) =>
+ val sym = vd.symbol
+ val rt = new RefTraverser(sym)
+ val t = if(rest.isEmpty) exp else Block(rest, exp) setType tree.tpe
+ rt.atOwner(PatternMatcher.this.owner)(rt.traverse(t))
+ rt.nref match {
+ case 0 =>
+ nremoved = nremoved + 1
+ t
+ case 1 if rt.nsafeRef == 1 =>
+ nsubstituted = nsubstituted + 1
+ new Subst(sym, vd.rhs).transform(t)
+ case i =>
+ tree
+ }
+ }
+ }
+
+// ---
/** pretty printer
*/
def print(): Unit =
@@ -835,10 +891,10 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
else if (ncases == 1) {
root.and.or match {
case ConstantPat(value) =>
- return Block(List(ValDef(root.symbol, selector)),
+ return squeezedBlock(Block(List(ValDef(root.symbol, selector)),
If(Equals(Ident(root.symbol), Literal(value)),
(root.and.or.and).bodyToTree(),
- defaultBody(root.and, matchError)));
+ defaultBody(root.and, matchError))))
case _ =>
return generalSwitchToTree();
}
@@ -891,7 +947,7 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
}
return Switch(selector, tags, bodies, defaultBody1, resultType);
*/
- nCases = CaseDef(Ident(nme.WILDCARD), Block(List(ValDef(root.symbol, selector)),defaultBody1)) :: nCases;
+ nCases = CaseDef(Ident(nme.WILDCARD), squeezedBlock(Block(List(ValDef(root.symbol, selector)),defaultBody1))) :: nCases;
Match(selector, nCases)
}
@@ -900,26 +956,14 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
/** simple optimization: if the last pattern is `case _' (no guards), we won't generate the ThrowMatchError
*/
def generalSwitchToTree(): Tree = {
- this.exit = owner.newLabel(root.pos, "exit")
- .setInfo(new MethodType(List(resultType), resultType));
- //Console.println("resultType:"+resultType.toString());
+ this.exit = owner.newLabel(root.pos, "exit").setInfo(new MethodType(List(resultType), resultType));
val result = exit.newValueParameter(root.pos, "result").setInfo( resultType );
-
- //Console.println("generalSwitchToTree: "+root.or);
- /*
- val ts = List(ValDef(root.symbol, selector));
- val res = If(toTree(root.and),
- LabelDef(exit, List(result), Ident(result)),
- ThrowMatchError(selector.pos, resultType // , Ident(root.symbol)
- ));
- return Block(ts, res);
- */
- return Block(
+ return squeezedBlock(Block(
List(
ValDef(root.symbol, selector),
toTree(root.and),
ThrowMatchError(selector.pos, Ident(root.symbol))),
- LabelDef(exit, List(result), Ident(result)))
+ LabelDef(exit, List(result), Ident(result))))
}
/*protected*/ def toTree(node1: PatternNode): Tree = {
@@ -981,12 +1025,13 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
//Block(
// List(Assign(Ident(resultVar), body(i))),
// Literal(Constant(true)));
+ squeezedBlock(
Block(
List(
ValDef(temp, body(i)),
Apply(Ident(exit), List(Ident(temp)))),
Literal(Constant(true))
- ); // forward jump
+ )); // forward jump
if (guard(i) != EmptyTree)
res0 = And(guard(i), res0);
res = Or(Block(ts.toList, res0), res);
diff --git a/src/library/scala/Iterable.scala b/src/library/scala/Iterable.scala
index 9eead0db12..ad1ac9c972 100644
--- a/src/library/scala/Iterable.scala
+++ b/src/library/scala/Iterable.scala
@@ -122,6 +122,21 @@ trait Iterable[+A] {
*/
def find(p: A => Boolean): Option[A] = elements.find(p)
+ /** Returns index of the first element satisying a predicate, or -1.
+ * @param p the predicate
+ * @return the index of the first element satisfying <code>p</code>, or -1 if such an element does not exist
+ */
+ def indexOf(p: A => Boolean): Int = {
+ val it = elements
+ var i = 0
+ while(it.hasNext)
+ if(p(it.next))
+ return i
+ else
+ i = i + 1
+ return -1
+ }
+
/** Combines the elements of this list together using the binary
* operator <code>op</code>, from left to right, and starting with
* the value <code>z</code>.
diff --git a/src/library/scala/xml/Unparsed.scala b/src/library/scala/xml/Unparsed.scala
new file mode 100644
index 0000000000..d297601128
--- /dev/null
+++ b/src/library/scala/xml/Unparsed.scala
@@ -0,0 +1,36 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: Text.scala 8097 2006-07-11 17:15:02 +0200 (Tue, 11 Jul 2006) emir $
+
+
+package scala.xml
+
+import scala.runtime.compat.StringBuilder
+
+/** an XML node for unparsed content. It will be output verbatim, all bets
+ * are off regarding wellformedness etc.
+ * @author Burak Emir
+ * @param _data content in this node, may not be null.
+ */
+case class Unparsed(_data: String) extends Atom[String](_data) {
+
+ if (null == data)
+ throw new java.lang.NullPointerException("tried to construct Unparsed with null")
+
+ final override def equals(x: Any) = x match {
+ case s:String => s.equals(data)
+ case s:Text => data == s.data
+ case s:Unparsed => data == s.data
+ case _ => false
+ }
+
+ /** returns text, with some characters escaped according to XML spec */
+ override def toString(sb: StringBuilder) = sb append data
+
+}
diff --git a/test/files/jvm/xmlmore.check b/test/files/jvm/xmlmore.check
index b28255b3c2..29f144c89f 100644
--- a/test/files/jvm/xmlmore.check
+++ b/test/files/jvm/xmlmore.check
@@ -6,6 +6,5 @@ Heathen, fire worshipper or idolatrous, come!
Come even if you broke your penitence a hundred times,
Ours is the portal of hope, come as you are.&quot;
Mevlana Celaleddin Rumi
-
-
+<foo><br /></foo>
End Test
diff --git a/test/files/jvm/xmlmore.scala b/test/files/jvm/xmlmore.scala
index 15adbcc891..c6322bc1ef 100644
--- a/test/files/jvm/xmlmore.scala
+++ b/test/files/jvm/xmlmore.scala
@@ -1,3 +1,5 @@
+object myBreak extends scala.xml.Unparsed("<br />")
+
object Test extends Application {
val com = <!-- thissa comment -->
val pi = <?this is a pi foo bar = && {{ ?>
@@ -6,12 +8,13 @@ object Test extends Application {
Heathen, fire worshipper or idolatrous, come!
Come even if you broke your penitence a hundred times,
Ours is the portal of hope, come as you are."
- Mevlana Celaleddin Rumi
+ Mevlana Celaleddin Rumi]]>
-]]>
+ val nazim = <foo>{myBreak}</foo> // shows use of unparsed
Console println com
Console println pi
Console println crz // this guy will escaped, and rightly so
+ Console println nazim
Console println "End Test"
}