package prefuse.data.expression;
import prefuse.data.Schema;
import prefuse.data.Tuple;
import prefuse.util.TypeLib;
/**
* Expression supporting basic arithmetic: add, subtract, multiply,
* divide, exponentiate (pow), and modulo (%).
*
* @author <a href="http://jheer.org">jeffrey heer</a>
*/
public class ArithmeticExpression extends BinaryExpression {
/** Indicates an addition operation. */
public static final int ADD = 0;
/** Indicates a subtraction operation. */
public static final int SUB = 1;
/** Indicates a multiplication operation. */
public static final int MUL = 2;
/** Indicates a division operation. */
public static final int DIV = 3;
/** Indicates an exponentiation (pow) operation. */
public static final int POW = 4;
/** Indicates a modulo operation. */
public static final int MOD = 5;
private Class m_type;
/**
* Create a new ArithmeticExpression.
* @param operation the operation to perform
* @param left the left sub-expression
* @param right the right sub-expression
*/
public ArithmeticExpression(int operation,
Expression left, Expression right)
{
super(operation, ADD, MOD, left, right);
m_type = null;
}
/**
* @see prefuse.data.expression.Expression#getType(prefuse.data.Schema)
*/
public Class getType(Schema s) {
if ( m_type == null ) {
Class lType = m_left.getType(s);
Class rType = m_right.getType(s);
// determine this class's type
m_type = TypeLib.getNumericType(lType, rType);
}
return m_type;
}
/**
* @see prefuse.data.expression.Expression#get(prefuse.data.Tuple)
*/
public Object get(Tuple t) {
Class type = getType(t.getSchema());
if ( int.class == type || byte.class == type ) {
return new Integer(getInt(t));
} else if ( long.class == type ) {
return new Long(getInt(t));
} else if ( float.class == type ) {
return new Float(getFloat(t));
} else if ( double.class == type ) {
return new Double(getDouble(t));
} else {
throw new IllegalStateException();
}
}
/**
* @see prefuse.data.expression.Expression#getInt(prefuse.data.Tuple)
*/
public int getInt(Tuple t) {
int x = m_left.getInt(t);
int y = m_right.getInt(t);
// compute return value
switch ( m_op ) {
case ADD:
return x+y;
case SUB:
return x-y;
case MUL:
return x*y;
case DIV:
return x/y;
case POW:
return (int)Math.pow(x,y);
case MOD:
return x%y;
}
throw new IllegalStateException("Unknown operation type.");
}
/**
* @see prefuse.data.expression.Expression#getLong(prefuse.data.Tuple)
*/
public long getLong(Tuple t) {
long x = m_left.getLong(t);
long y = m_right.getLong(t);
// compute return value
switch ( m_op ) {
case ADD:
return x+y;
case SUB:
return x-y;
case MUL:
return x*y;
case DIV:
return x/y;
case POW:
return (long)Math.pow(x,y);
case MOD:
return x%y;
}
throw new IllegalStateException("Unknown operation type.");
}
/**
* @see prefuse.data.expression.Expression#getFloat(prefuse.data.Tuple)
*/
public float getFloat(Tuple t) {
float x = m_left.getFloat(t);
float y = m_right.getFloat(t);
// compute return value
switch ( m_op ) {
case ADD:
return x+y;
case SUB:
return x-y;
case MUL:
return x*y;
case DIV:
return x/y;
case POW:
return (float)Math.pow(x,y);
case MOD:
return (float)Math.IEEEremainder(x,y);
}
throw new IllegalStateException("Unknown operation type.");
}
/**
* @see prefuse.data.expression.Expression#getDouble(prefuse.data.Tuple)
*/
public double getDouble(Tuple t) {
double x = m_left.getDouble(t);
double y = m_right.getDouble(t);
// compute return value
switch ( m_op ) {
case ADD:
return x+y;
case SUB:
return x-y;
case MUL:
return x*y;
case DIV:
return x/y;
case POW:
return Math.pow(x,y);
case MOD:
return Math.IEEEremainder(x,y);
}
throw new IllegalStateException("Unknown operation type.");
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
char op = '?';
switch ( m_op ) {
case ADD:
op = '+';
break;
case SUB:
op = '-';
break;
case MUL:
op = '*';
break;
case DIV:
op = '/';
break;
case POW:
op = '^';
break;
case MOD:
op = '%';
break;
}
return '('+m_left.toString()+' '+op+' '+m_right.toString()+')';
}
} // end of class ArithmeticExpression