/******************************************************************************* * Copyright (c) 2001, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jem.internal.proxy.initParser; /* */ public class NumberLiteral extends Expression { protected String numberString = ""; //$NON-NLS-1$ protected boolean isComplete = false; protected Class numberClass = Integer.TYPE; protected int exponentFlag = NO_EXPONENT; protected static final int NO_EXPONENT = 0, HAS_EXPONENT = 1, HAS_EXPONENT_MINUS = 2; /** * evaluate method comment. */ public NumberLiteral(){ } /** * evaluate method comment. */ public Object evaluate() throws Exception { try { // Return a number of the correct instance if (numberClass == Float.TYPE){ return new Float(Float.parseFloat(numberString)); } else if (numberClass == Long.TYPE ) { return Long.decode(numberString); } else if (numberClass == Double.TYPE ){ return new Double(Double.parseDouble(numberString)); } else return Integer.decode(numberString); } catch (Exception e) { throw new EvaluationException(e); } } public boolean isComplete(){ return isComplete; } /** * Return the type of number that we are. */ public Class getTypeClass(){ return numberClass; } protected String getTypeClassName() { return numberClass != null ? numberClass.getName() : ""; //$NON-NLS-1$ } /** * If the delimiter is an operation such as a +,-,/,* then we can consume it * If the delimiter is period and we don't already have one then it is the decimal portion of us */ public Expression push(char[] token , char delimiter){ // Close brackets complete use if(delimiter == DelimiterCloseParen || delimiter == DelimiterComma || delimiter == DelimiterCloseElipse){ isComplete = true; } if (delimiter == OperMinus && numberString.length() == 0) numberString+=OperMinus; // No digits yet, but we have a minus sign, so add to accumulating number. numberString += processNumberToken(token); // If we have part of a number and are asked to do some arithmetic throw an // error that this has not been coded yet, except minus could be part of an exponent. if(numberString.length() > 0 && token.length > 1) { switch(delimiter){ case OperMinus: if (exponentFlag == HAS_EXPONENT) { exponentFlag = HAS_EXPONENT_MINUS; numberString += OperMinus; break; } case OperPlus: case OperMultiply: case OperDivide: { throw new RuntimeException("Can't do arithmetic yet"); //$NON-NLS-1$ } } } if (delimiter == DelimiterPeriod){ numberClass = Double.TYPE; // A decimal makes it double. numberString += DelimiterPeriod; } if(delimiter == BitOR || delimiter == BitAND){ Expression result = new PrimitiveOperation(this,delimiter); isComplete = true; return result; } return this; } protected String processNumberToken(char[] token){ for (int i=0; i<token.length; i++) if (token[i] == 'E' || token[i] == 'e') { numberClass = Double.TYPE; // Definitely a floating because of this. exponentFlag = HAS_EXPONENT; break; } // The token could be a number, e.g. 10 or 5 or could be qualified with a primitive // suffix, e.g. 10l or 5f char[] numberToken = token; if ( token.length > 0 ) { switch(token[token.length - 1]){ case 'F': case 'f': numberClass = Float.TYPE; numberToken = new char[token.length - 1]; System.arraycopy(token,0,numberToken,0,numberToken.length); isComplete = true; break; case 'L': case 'l': numberClass = Long.TYPE; numberToken = new char[token.length - 1]; System.arraycopy(token,0,numberToken,0,numberToken.length); isComplete = true; break; case 'D': case 'd': numberClass = Double.TYPE; numberToken = new char[token.length - 1]; System.arraycopy(token,0,numberToken,0,numberToken.length); isComplete = true; break; } } return new String(numberToken); } public String toString(){ java.io.StringWriter writer = new java.io.StringWriter(); writer.write("Number \""); //$NON-NLS-1$ writer.write(numberString); writer.write("\""); //$NON-NLS-1$ return writer.toString(); } /** * Number literals are primitive */ public boolean isPrimitive() { return true; } }