summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-08-14 08:27:13 -0700
committerAdriaan Moors <adriaan.moors@epfl.ch>2012-08-14 08:27:13 -0700
commitaf1d0a83a55b1dca300f455d60e85b815fc7b06b (patch)
tree7f2068c61fbcc00093ad19594e116d9c62abefe7 /src
parent1c5526ed81a27550cc4f376d6debe89216470c51 (diff)
parent9285bdbd40233f05093c0acdeed4aa1b701b11d6 (diff)
downloadscala-af1d0a83a55b1dca300f455d60e85b815fc7b06b.tar.gz
scala-af1d0a83a55b1dca300f455d60e85b815fc7b06b.tar.bz2
scala-af1d0a83a55b1dca300f455d60e85b815fc7b06b.zip
Merge pull request #1134 from adriaanm/patmat-misc
patmat tweaks: compiler performance, better error on unsupported pattern
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/ast/Printers.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala49
2 files changed, 25 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Printers.scala b/src/compiler/scala/tools/nsc/ast/Printers.scala
index 8b92f0acd6..885fc3f518 100644
--- a/src/compiler/scala/tools/nsc/ast/Printers.scala
+++ b/src/compiler/scala/tools/nsc/ast/Printers.scala
@@ -278,6 +278,7 @@ trait Printers extends reflect.internal.Printers { this: Global =>
def asString(t: Tree): String = render(t, newStandardTreePrinter, settings.printtypes.value, settings.uniqid.value, settings.Yshowsymkinds.value)
def asCompactString(t: Tree): String = render(t, newCompactTreePrinter, settings.printtypes.value, settings.uniqid.value, settings.Yshowsymkinds.value)
+ def asCompactDebugString(t: Tree): String = render(t, newCompactTreePrinter, true, true, true)
def newStandardTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer)
def newStandardTreePrinter(stream: OutputStream): TreePrinter = newStandardTreePrinter(new PrintWriter(stream))
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index 662de79e24..a1a596456f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -67,10 +67,6 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
object exceeded extends Exception {
val advice = s"(The analysis required more space than allowed. Please try with scalac -Dscalac.patmat.analysisBudget=${AnalysisBudget.max*2} or -Dscalac.patmat.analysisBudget=off.)"
}
-
- object stackOverflow extends Exception {
- val advice = "(There was a stack overflow. Please try increasing the stack available to the compiler using e.g., -Xss2m.)"
- }
}
def newTransformer(unit: CompilationUnit): Transformer =
@@ -521,7 +517,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// case Star(_) | ArrayValue => error("stone age pattern relics encountered!")
case _ =>
- error("unsupported pattern: "+ patTree +"(a "+ patTree.getClass +")")
+ typer.context.unit.error(patTree.pos, s"unsupported pattern: $patTree (a ${patTree.getClass}).\n This is a scalac bug. Tree diagnostics: ${asCompactDebugString(patTree)}.")
noFurtherSubPats()
}
@@ -2056,21 +2052,29 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
def Lit(sym: Sym, pos: Boolean = true): Lit
// throws an AnalysisBudget.Exception when the prop results in a CNF that's too big
+ // TODO: be smarter/more efficient about this (http://lara.epfl.ch/w/sav09:tseitin_s_encoding)
def eqFreePropToSolvable(p: Prop): Formula = {
- // TODO: for now, reusing the normalization from DPLL
- def negationNormalForm(p: Prop): Prop = p match {
- case And(a, b) => And(negationNormalForm(a), negationNormalForm(b))
- case Or(a, b) => Or(negationNormalForm(a), negationNormalForm(b))
- case Not(And(a, b)) => negationNormalForm(Or(Not(a), Not(b)))
- case Not(Or(a, b)) => negationNormalForm(And(Not(a), Not(b)))
- case Not(Not(p)) => negationNormalForm(p)
- case Not(True) => False
- case Not(False) => True
- case True
- | False
- | (_ : Sym)
- | Not(_ : Sym) => p
- }
+ def negationNormalFormNot(p: Prop, budget: Int = AnalysisBudget.max): Prop =
+ if (budget <= 0) throw AnalysisBudget.exceeded
+ else p match {
+ case And(a, b) => Or(negationNormalFormNot(a, budget - 1), negationNormalFormNot(b, budget - 1))
+ case Or(a, b) => And(negationNormalFormNot(a, budget - 1), negationNormalFormNot(b, budget - 1))
+ case Not(p) => negationNormalForm(p, budget - 1)
+ case True => False
+ case False => True
+ case s: Sym => Not(s)
+ }
+
+ def negationNormalForm(p: Prop, budget: Int = AnalysisBudget.max): Prop =
+ if (budget <= 0) throw AnalysisBudget.exceeded
+ else p match {
+ case And(a, b) => And(negationNormalForm(a, budget - 1), negationNormalForm(b, budget - 1))
+ case Or(a, b) => Or(negationNormalForm(a, budget - 1), negationNormalForm(b, budget - 1))
+ case Not(negated) => negationNormalFormNot(negated, budget - 1)
+ case True
+ | False
+ | (_ : Sym) => p
+ }
val TrueF = formula()
val FalseF = formula(clause())
@@ -2113,12 +2117,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
}
val start = Statistics.startTimer(patmatCNF)
- val res =
- try {
- conjunctiveNormalForm(negationNormalForm(p))
- } catch { case ex : StackOverflowError =>
- throw AnalysisBudget.stackOverflow
- }
+ val res = conjunctiveNormalForm(negationNormalForm(p))
Statistics.stopTimer(patmatCNF, start)