001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.compiler.ast;
011:
012: import org.eclipse.jdt.internal.compiler.ASTVisitor;
013: import org.eclipse.jdt.internal.compiler.impl.*;
014: import org.eclipse.jdt.internal.compiler.codegen.*;
015: import org.eclipse.jdt.internal.compiler.lookup.*;
016: import org.eclipse.jdt.internal.compiler.util.FloatUtil;
017:
018: public class DoubleLiteral extends NumberLiteral {
019: double value;
020:
021: public DoubleLiteral(char[] token, int s, int e) {
022: super (token, s, e);
023: }
024:
025: public void computeConstant() {
026: Double computedValue;
027: try {
028: computedValue = Double.valueOf(String.valueOf(source));
029: } catch (NumberFormatException e) {
030: // hex floating point literal
031: // being rejected by 1.4 libraries where Double.valueOf(...) doesn't handle hex decimal floats
032: try {
033: double v = FloatUtil.valueOfHexDoubleLiteral(source);
034: if (v == Double.POSITIVE_INFINITY) {
035: // error: the number is too large to represent
036: return;
037: }
038: if (Double.isNaN(v)) {
039: // error: the number is too small to represent
040: return;
041: }
042: value = v;
043: constant = DoubleConstant.fromValue(v);
044: } catch (NumberFormatException e1) {
045: // if the computation of the constant fails
046: }
047: return;
048: }
049:
050: final double doubleValue = computedValue.doubleValue();
051: if (doubleValue > Double.MAX_VALUE) {
052: // error: the number is too large to represent
053: return;
054: }
055: if (doubleValue < Double.MIN_VALUE) {
056: // see 1F6IGUU
057: // a true 0 only has '0' and '.' in mantissa
058: // 1.0e-5000d is non-zero, but underflows to 0
059: boolean isHexaDecimal = false;
060: label: for (int i = 0; i < source.length; i++) { //it is welled formated so just test against '0' and potential . D d
061: switch (source[i]) {
062: case '0':
063: case '.':
064: break;
065: case 'x':
066: case 'X':
067: isHexaDecimal = true;
068: break;
069: case 'e':
070: case 'E':
071: case 'f':
072: case 'F':
073: case 'd':
074: case 'D':
075: if (isHexaDecimal) {
076: return;
077: }
078: // starting the exponent - mantissa is all zero
079: // no exponent - mantissa is all zero
080: break label;
081: case 'p':
082: case 'P':
083: break label;
084: default:
085: // error: the number is too small to represent
086: return;
087: }
088: }
089: }
090: value = doubleValue;
091: constant = DoubleConstant.fromValue(value);
092: }
093:
094: /**
095: * Code generation for the double literak
096: *
097: * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
098: * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
099: * @param valueRequired boolean
100: */
101: public void generateCode(BlockScope currentScope,
102: CodeStream codeStream, boolean valueRequired) {
103: int pc = codeStream.position;
104: if (valueRequired) {
105: codeStream.generateConstant(constant, implicitConversion);
106: }
107: codeStream.recordPositionsFrom(pc, this .sourceStart);
108: }
109:
110: public TypeBinding literalType(BlockScope scope) {
111: return TypeBinding.DOUBLE;
112: }
113:
114: public void traverse(ASTVisitor visitor, BlockScope scope) {
115: visitor.visit(this, scope);
116: visitor.endVisit(this, scope);
117: }
118: }
|