From eb79135b976114e75526a0d5b37401f110d47136 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 14 Aug 2006 16:40:46 +0000 Subject: Fixed bug 697 --- src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 4 ++-- src/compiler/scala/tools/nsc/symtab/Constants.scala | 3 +++ .../scala/tools/nsc/typechecker/ConstantFolder.scala | 15 +++++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 6fe085a54e..b942f73b22 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -273,8 +273,8 @@ trait Parsers requires SyntaxAnalyzer { case '|' => 2 case '^' => 3 case '&' => 4 - case '<' | '>' => 5 - case '=' | '!' => 6 + case '=' | '!' => 5 + case '<' | '>' => 6 case ':' => 7 case '+' | '-' => 8 case '*' | '/' | '%' => 9 diff --git a/src/compiler/scala/tools/nsc/symtab/Constants.scala b/src/compiler/scala/tools/nsc/symtab/Constants.scala index 38fc822b18..181ab56ef1 100644 --- a/src/compiler/scala/tools/nsc/symtab/Constants.scala +++ b/src/compiler/scala/tools/nsc/symtab/Constants.scala @@ -12,6 +12,7 @@ trait Constants requires SymbolTable { import definitions._; + final val NoTag = LITERAL - LITERAL final val UnitTag = LITERALunit - LITERAL; final val BooleanTag = LITERALboolean - LITERAL; final val ByteTag = LITERALbyte - LITERAL; @@ -27,6 +28,8 @@ trait Constants requires SymbolTable { final val EnumTag = ClassTag + 1; final val ArrayTag = EnumTag + 1; + def isNumeric(tag: int) = ByteTag <= tag && tag <= DoubleTag + case class Constant(value: Any) { val tag: int = diff --git a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala index 32d7fcd800..a19c5799d4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala @@ -16,21 +16,21 @@ abstract class ConstantFolder { case Apply(Select(Literal(x), op), List(Literal(y))) => foldBinop(op, x, y) case Select(Literal(x), op) => foldUnop(op, x) case _ => null - }); + }) /** If tree is a constant value that can be converted to type `pt', perform the conversion */ def apply(tree: Tree, pt: Type): Tree = fold(tree, tree.tpe match { case ConstantType(x) => x convertTo pt case _ => null - }); + }) - private def fold(tree: Tree, compX: =>Constant): Tree = + private def fold(tree: Tree, compX: => Constant): Tree = try { val x = compX if (x != null && x.tag != UnitTag) tree setType ConstantType(x) - else tree; + else tree } catch { - case _:ArithmeticException => tree // the code will crash at runtime, + case _: ArithmeticException => tree // the code will crash at runtime, // but that is better than the // compiler itself crashing } @@ -55,7 +55,10 @@ abstract class ConstantFolder { } private def foldBinop(op: Name, x: Constant, y: Constant): Constant = try { - val optag = if (x.tag > y.tag) x.tag else y.tag; + val optag = if (x.tag == y.tag) x.tag + else if (isNumeric(x.tag) && isNumeric(y.tag)) + if (x.tag > y.tag) x.tag else y.tag + else NoTag optag match { case BooleanTag => op match { -- cgit v1.2.3