import eclipse 3.1 M4 compiler
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / ast / DoubleLiteral.java
index 139c813..1c8a8c1 100644 (file)
@@ -14,58 +14,100 @@ import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.impl.*;
 import org.eclipse.jdt.internal.compiler.codegen.*;
 import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.FloatUtil;
 
 public class DoubleLiteral extends NumberLiteral {
        double value;
-public DoubleLiteral(char[] token, int s, int e) {
-       super(token, s,e);
-}
-public void computeConstant() {
-
-       //the source is correctly formated so the exception should never occurs
+       public DoubleLiteral(char[] token, int s, int e) {
+               super(token, s, e);
+       }
+       public void computeConstant() {
+               Double computedValue;
+               try {
+                       computedValue = Double.valueOf(String.valueOf(source));
+               } catch (NumberFormatException e) {
+                       // hex floating point literal
+                       // being rejected by 1.4 libraries where Double.valueOf(...) doesn't handle hex decimal floats
+                       try {
+                               double v = FloatUtil.valueOfHexDoubleLiteral(source);
+                               if (v == Double.POSITIVE_INFINITY) {
+                                       // error: the number is too large to represent
+                                       return;
+                               }
+                               if (Double.isNaN(v)) {
+                                       // error: the number is too small to represent
+                                       return;
+                               }
+                               value = v;
+                               constant = Constant.fromValue(v);
+                       } catch (NumberFormatException e1) {
+                               // if the computation of the constant fails
+                       }
+                       return;
+               }
 
-       Double computedValue;
-       try { computedValue = Double.valueOf(String.valueOf(source));}
-       catch(NumberFormatException e){return ;} //how can it happen ????
-
-       if (computedValue.doubleValue() > Double.MAX_VALUE) return ; //may be Infinity
-       if (computedValue.doubleValue() < Double.MIN_VALUE)
-       {       //only a true 0 can be made of zeros
-               //2.00000000000000000e-324 is illegal .... 
-               label :
-                       for (int i=0;i<source.length;i++)
-                       {       //it is welled formated so just test against '0' and potential . D d  
-                               switch (source[i]){
+               final double doubleValue = computedValue.doubleValue();
+               if (doubleValue > Double.MAX_VALUE) {
+                       // error: the number is too large to represent
+                       return;
+               }
+               if (doubleValue < Double.MIN_VALUE) {
+                       // see 1F6IGUU
+                       // a true 0 only has '0' and '.' in mantissa
+                       // 1.0e-5000d is non-zero, but underflows to 0
+                       boolean isHexaDecimal = false;
+                       label : for (int i = 0; i < source.length; i++) { //it is welled formated so just test against '0' and potential . D d  
+                               switch (source[i]) {
                                        case '0' :
                                        case '.' :
+                                               break;
+                                       case 'x' :
+                                       case 'X' :
+                                               isHexaDecimal = true;
+                                               break;
+                                       case 'e' :
+                                       case 'E' :
+                                       case 'f' :
+                                       case 'F' :
                                        case 'd' :
-                                       case 'D' : break ;
-                                       case 'e' : 
-                                       case 'E' : break label ; //exposant are valid....!
-                                       default  : return;}}} //error
-
-       constant = Constant.fromValue(value = computedValue.doubleValue());}
-/**
- * Code generation for the double literak
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- * @param valueRequired boolean
- */
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-       int pc = codeStream.position;
-       if (valueRequired)
-               if ((implicitConversion >> 4) == T_double)
-                       codeStream.generateInlinedValue(value);
-               else
+                                       case 'D' :
+                                               if (isHexaDecimal) {
+                                                       return;
+                                               }
+                                               // starting the exponent - mantissa is all zero
+                                               // no exponent - mantissa is all zero
+                                               break label;
+                                       case 'p' :
+                                       case 'P' :
+                                               break label;
+                                       default :
+                                               // error: the number is too small to represent
+                                               return;
+                               }
+                       }
+               }
+               value = doubleValue;
+               constant = Constant.fromValue(value);
+       }
+       /**
+        * Code generation for the double literak
+        *
+        * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+        * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+        * @param valueRequired boolean
+        */
+       public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+               int pc = codeStream.position;
+               if (valueRequired) {
                        codeStream.generateConstant(constant, implicitConversion);
-       codeStream.recordPositionsFrom(pc, this.sourceStart);
-}
-public TypeBinding literalType(BlockScope scope) {
-       return DoubleBinding;
-}
-public void traverse(ASTVisitor visitor, BlockScope blockScope) {
-       visitor.visit(this, blockScope);
-       visitor.endVisit(this, blockScope);
-}
+               }
+               codeStream.recordPositionsFrom(pc, this.sourceStart);
+       }
+       public TypeBinding literalType(BlockScope scope) {
+               return DoubleBinding;
+       }
+       public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+               visitor.visit(this, blockScope);
+               visitor.endVisit(this, blockScope);
+       }
 }