import eclipse 3.1 M4 compiler
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / ast / FloatLiteral.java
index c7d53d6..0fa1908 100644 (file)
 package org.eclipse.jdt.internal.compiler.ast;
 
 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.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.util.FloatUtil;
 
 public class FloatLiteral extends NumberLiteral {
        float value;
        final static float Float_MIN_VALUE = Float.intBitsToFloat(1); // work-around VAJ problem 1F6IGUU
-public FloatLiteral(char[] token, int s, int e) {
-       super(token, s,e);
-}
-public void computeConstant() {
-
-       //the source is correctly formated so the exception should never occurs
-
-       Float computedValue;
-       try {
-               computedValue = Float.valueOf(String.valueOf(source));
-       } catch (NumberFormatException e) {
-               return;
-       } 
-
-       if (computedValue.doubleValue() > Float.MAX_VALUE){
-               return; //may be Infinity
+       public FloatLiteral(char[] token, int s, int e) {
+               super(token, s, e);
        }
-       if (computedValue.floatValue() < Float_MIN_VALUE){
-               // see 1F6IGUU
-               //only a true 0 can be made of zeros
-               //1.00000000e-46f is illegal ....
-               label : for (int i = 0; i < source.length; i++) { 
-                       switch (source[i]) {
-                               case '.' :
-                               case 'f' :
-                               case 'F' :
-                               case '0' :
-                                       break;
-                               case 'e' :
-                               case 'E' :
-                                       break label; //exposant are valid !....
-                               default :
-                                       return; //error
+       public void computeConstant() {
+               Float computedValue;
+               try {
+                       computedValue = Float.valueOf(String.valueOf(source));
+               } catch (NumberFormatException e) {
+                       // hex floating point literal
+                       // being rejected by 1.4 libraries where Float.valueOf(...) doesn't handle hex decimal floats
+                       try {
+                               float v = FloatUtil.valueOfHexFloatLiteral(source);
+                               if (v == Float.POSITIVE_INFINITY) {
+                                       // error: the number is too large to represent
+                                       return;
+                               }
+                               if (Float.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;
+               }
+
+               final float floatValue = computedValue.floatValue();
+               if (floatValue > Float.MAX_VALUE) {
+                       // error: the number is too large to represent
+                       return;
+               }
+               if (floatValue < Float.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' :
+                                               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 = floatValue;
+               constant = Constant.fromValue(value);
        }
-       constant = Constant.fromValue(value = computedValue.floatValue());
-}
-/**
- * Code generation for float literal
- *
- * @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_float)
-                       codeStream.generateInlinedValue(value);
-               else
+       /**
+        * Code generation for float literal
+        *
+        * @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 FloatBinding;
-}
-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 FloatBinding;
+       }
+       public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+               visitor.visit(this, blockScope);
+               visitor.endVisit(this, blockScope);
+       }
 }