blob: c8218eaa6d4dd1fc17a314e02f978f9ed33b1c4e [file] [log] [blame]
/*******************************************************************************
* 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 v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* 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;
}
}