summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorburaq <buraq@epfl.ch>2005-05-27 12:57:24 +0000
committerburaq <buraq@epfl.ch>2005-05-27 12:57:24 +0000
commitf1c0882880b6dd967a297c15da4c99d408d6a1f0 (patch)
treed034c80f8c04734c3e7d4c688a5523e06182cca2
parentce836de569deb5443bf90ae28baf7be16c49d5ac (diff)
downloadscala-f1c0882880b6dd967a297c15da4c99d408d6a1f0.tar.gz
scala-f1c0882880b6dd967a297c15da4c99d408d6a1f0.tar.bz2
scala-f1c0882880b6dd967a297c15da4c99d408d6a1f0.zip
moved to directory matching to avoid prefix-clash
-rw-r--r--sources/scala/tools/nsc/matching/TransMatcher.scala136
-rw-r--r--sources/scala/tools/nsc/transmatch/TransMatcher.scala33
2 files changed, 136 insertions, 33 deletions
diff --git a/sources/scala/tools/nsc/matching/TransMatcher.scala b/sources/scala/tools/nsc/matching/TransMatcher.scala
new file mode 100644
index 0000000000..862e356cd3
--- /dev/null
+++ b/sources/scala/tools/nsc/matching/TransMatcher.scala
@@ -0,0 +1,136 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author buraq
+ */
+// $Id$
+package scala.tools.nsc.matching;
+
+/** Translation of pattern matching
+ */
+abstract class TransMatcher {
+
+ val global: Global;
+
+ import global._;
+ import definitions._;
+ import posAssigner.atPos;
+
+ class TransMatchPhase(prev: Phase) extends StdPhase(prev) {
+ def name = "transmatcher";
+ val global: TransMatcher.this.global.type = TransMatcher.this.global;
+ def apply(unit: CompilationUnit): unit =
+ unit.body = newTransMatcher.transform(unit.body);
+ }
+
+ def newTransMatcher = new TransMatch();
+
+ class TransMatch extends Transformer {
+
+ def isRegular(pat:Tree): Boolean = pat match {
+ case Alternative(_) => true
+ case Star(_) => true;
+
+ case Ident(_) => false
+
+ case Bind( n, pat1 ) => isRegular( pat1 )
+ case Sequence( trees ) =>
+ ( trees.length == 0 ) || isRegular( trees );
+
+ case Apply( fn, trees ) =>
+ isRegular( trees ) &&
+ !((trees.length == 1) && TreeInfo.isEmptySequence( trees( 0 )))
+
+ case Literal(_) => false;
+ case Select(_,_) => false;
+ case Typed(_,_) => false;
+ case _ => error("in TransMatch.isRegular phase: unknown node"+pat.getClass());
+ }
+
+
+ /** a casedef with sequence subpatterns like
+ *
+ * case ..x @ ().. => body
+ *
+ * should be replaced straight away with
+ *
+ * case .. () .. => val x = Nil; body
+ */
+ def removeNilVariables( cd: CaseDef ): CaseDef = {
+ var nilVars:List[Symbol] = Nil;
+ def remove(pat: Tree): Tree = pat.match {
+ case Alternative( _ ) => pat /* no bind/var allowed! */
+ case Star( _ ) => pat /* no bind/var allowed! */
+ case Bind( id, empt @ Sequence()) =>
+ nilVars = id.symbol() :: nilVars;
+ empt
+ case Bind( id, pat ) =>
+ copy.Bind( pat, id, remove(pat) );
+
+ case Sequence( trees ) =>
+ copy.Sequence( pat, trees map remove )
+
+ case Apply( fn, args ) =>
+ copy.Apply( pat, fn, args map remove )
+
+ case Ident(_) => pat
+ case Literal(_) => pat
+ case Select(_,_) => pat
+ case Typed(_,_) => pat
+
+ case _ => error("unknown node"+pat.getClass());
+ }
+
+ cd.match {
+ case CaseDef(pat, guard, body) =>
+ val npat = remove(pat);
+ val nbody = {
+ if(nilVars.isEmpty)
+ body
+ else
+ atPos(body.pos)(
+ Block(nilVars map { x => ValDef(s, gen.mkNil) }, body)
+ )
+ }
+ copy.CaseDef(cd, npat, guard, nbody)
+ }
+ }
+
+ def handle(sel:Tree, cases:List[CaseDef]): Tree = {
+
+ // 1. is there a regular pattern?
+
+ val containsReg = cases.exists { isRegular };
+
+ // @todo: remove unused variables
+
+ if(containsReg) {
+ // 2. replace nilVariables
+ //@todo: bring over AlgebraicMatcher
+ //val ncases = cases.map { removeNilVariables };
+ //val matcher = new PartialMatcher( currentOwner, root, restpe );
+ //new AlgebraicMatcher().construct( matcher, ncases );
+
+ //matcher.tree
+ null
+ } else {
+ val pm = new matching.PatternMatcher() {
+ val global = TransMatcher.this.global;
+ }
+ pm.initialize(root, currentOwner, restpe, true );
+ pm.construct( cases );
+ if (global.log()) {
+ global.log("internal pattern matching structure");
+ pm.print();
+ }
+ pm.toTree();
+ }
+ }
+
+ override def transform(tree: Tree) = tree match {
+ case Match(selector, cases) =>
+ handle(transform(selector), transform1(cases));
+ case _ =>
+ super.transform(tree);
+ }
+ }
+}
diff --git a/sources/scala/tools/nsc/transmatch/TransMatcher.scala b/sources/scala/tools/nsc/transmatch/TransMatcher.scala
deleted file mode 100644
index 1fb887b734..0000000000
--- a/sources/scala/tools/nsc/transmatch/TransMatcher.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-/* NSC -- new scala compiler
- * Copyright 2005 LAMP/EPFL
- * @author buraq
- */
-// $Id$
-package scala.tools.nsc.transmatch;
-
-/** Translation of pattern matching
- */
-abstract class TransMatcher {
-
- val global: Global;
-
- import global._;
- import definitions._;
- import posAssigner.atPos;
-
- class TransMatchPhase(prev: Phase) extends StdPhase(prev) {
- def name = "transmatcher";
- val global: TransMatcher.this.global.type = TransMatcher.this.global;
- def apply(unit: CompilationUnit): unit =
- unit.body = newTransMatcher.transform(unit.body);
- }
-
- def newTransMatcher = new TransMatch();
-
- class TransMatch extends Transformer {
- override def transform(tree: Tree) = tree match {
- case _ => super.transform(tree);
- }
- }
-
-}