diff options
author | buraq <buraq@epfl.ch> | 2005-05-27 12:57:24 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2005-05-27 12:57:24 +0000 |
commit | f1c0882880b6dd967a297c15da4c99d408d6a1f0 (patch) | |
tree | d034c80f8c04734c3e7d4c688a5523e06182cca2 | |
parent | ce836de569deb5443bf90ae28baf7be16c49d5ac (diff) | |
download | scala-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.scala | 136 | ||||
-rw-r--r-- | sources/scala/tools/nsc/transmatch/TransMatcher.scala | 33 |
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); - } - } - -} |