summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorburaq <buraq@epfl.ch>2004-07-08 17:09:22 +0000
committerburaq <buraq@epfl.ch>2004-07-08 17:09:22 +0000
commitde1938de8fdb9cdf2dd6b5666bee1fdd08f2a163 (patch)
tree450ad8ab87d288ac675cdb4e818af245e847fdec
parente0e30084fb8149203ade32f687b869a748519de0 (diff)
downloadscala-de1938de8fdb9cdf2dd6b5666bee1fdd08f2a163.tar.gz
scala-de1938de8fdb9cdf2dd6b5666bee1fdd08f2a163.tar.bz2
scala-de1938de8fdb9cdf2dd6b5666bee1fdd08f2a163.zip
regular expressions
-rw-r--r--sources/scala/tools/scalac/transformer/matching/PatternExp.scala81
1 files changed, 81 insertions, 0 deletions
diff --git a/sources/scala/tools/scalac/transformer/matching/PatternExp.scala b/sources/scala/tools/scalac/transformer/matching/PatternExp.scala
new file mode 100644
index 0000000000..a1d0bce8a4
--- /dev/null
+++ b/sources/scala/tools/scalac/transformer/matching/PatternExp.scala
@@ -0,0 +1,81 @@
+import scalac.ast._ ;
+import scalac.atree.AConstant ;
+import scalac.symtab.{ Definitions, Modifiers, Symbol, Type} ;
+import scalac.util.Name ;
+
+package scala.tools.scalac.transformer.matching {
+
+ import scala.util.regexp.PointedHedgeExp;
+
+ class PatternExp(defs: Definitions) extends PointedHedgeExp[PatternTest] {
+ type regexp = RegExp ;
+
+ case class Binding(vble:Symbol, re:regexp) extends Meta( re ) ;
+ case object WildcardNode extends RegExp {
+ final val isNullable = false;
+ }
+
+ def fromTrees( ts:Array[Tree] ):Seq[RegExp] = {
+ var nts: List[RegExp] = Nil;
+ val it = Iterator.fromArray( ts );
+ while( it.hasNext )
+ nts = fromTree( it.next ) :: nts;
+ nts.reverse
+ }
+
+ def fromTree( t:Tree ):RegExp = {
+ import Tree._ ;
+ t match {
+ case Alternative(choices:Array[Tree] ) =>
+ Alt( fromTrees(choices):_* )
+
+ case x @ Apply(_, args) =>
+ if(isSeqApply( x )) // List(1,2,3)
+ Node(TypeTest( x.getType() ), Sequ(fromTrees( args ):_*))
+
+ else if( isObjectRef( x ) ) // uncurry: foo.bar => foo.bar()
+ Node(EqualsValue( t ), Eps);
+
+ else // case class constructor
+ Node(Constructor( t.getType() ), Sequ(fromTrees( args ):_*));
+
+ case Bind(n: Name, t:Tree) =>
+ if( TreeInfo.isNameOfStarPattern( n ) )
+ Star(fromTree( t ))
+ else
+ Binding( t.symbol(), fromTree( t ))
+
+ case Ident( n:Name ) =>
+ if( t.symbol() == defs.PATTERN_WILDCARD )
+ WildcardNode
+ else if( TreeInfo.isNameOfStarPattern( n ) )
+ Eps;
+ else Node(EqualsValue( t ), Eps)
+
+ case Select(_,_) =>
+ Node(EqualsValue( t ), Eps)
+
+ case Sequence( trees ) =>
+ Sequ(fromTrees( trees ):_*);
+
+ case Typed(_,_) =>
+ Node(TypeTest( t.getType() ), Eps)
+ }
+ }
+
+ /** these are treated like constant value */
+ final def isObjectRef( t:Tree.Apply ):Boolean = {
+ val sym = t.fun.symbol();
+ (sym != null)
+ && sym.isStable()
+ && !(sym.isModule()
+ && ((sym.flags & Modifiers.CASE) != 0));
+ }
+
+ final def isSeqApply( tree:Tree.Apply ):Boolean = {
+ ((tree.getType().symbol().flags & Modifiers.CASE) == 0)
+ && ( tree.args.length == 1 )
+ && tree.args(0).isInstanceOf[Tree.Sequence]
+ }
+ }
+}