com.waveset.expression
Class ExValue

java.lang.Object
  extended bycom.waveset.expression.ExValue

public class ExValue
extends java.lang.Object

A class used to represent a value that is returned and manipulated by expressions.

Java purists will note that there is a LOT of seemingly unnecessary complexity in here. What is happening is that we're being absolutely militant about minimizing storage allocation and garbage collection, since manipulation of values is one of the most performance critical parts of the expression evaluator.

There are also some dreadded class comparisons in here that could be avoided with polymorphism, but I think its overkill in this situation, and I want to leave open the possibility for a value to change its type as a side effect of some mutator method.

To avoid heap churn, we keep ExValue objects in a pool. The value may be one of several types, but we try to keep primitive "int" values as int's rather than wrapping them in Integer objects which will then quickly become garbage.

Could consider representing strings as char[] arrays, and providing various string manipulation methods here, similar to the C++ implementation.


Field Summary
static java.lang.String code_id
           
static java.lang.Class INTEGER
           
static ExValue MINUSONE
          Built-in object for the representation of the number minus one.
static java.lang.Class OBJECT
           
static ExValue ONE
          Built-in object for the representation of the number one, also used for logical true.
static java.lang.Class STRING
          Constants used for types.
static ExValue ZERO
          Built-in object for the representation of the number zero, also used for logical false.
 
Constructor Summary
ExValue()
          Construct a new value.
ExValue(int n)
          Special private constructor for our static instances.
ExValue(java.lang.Object o)
          Construct a new value, initializing it to an object.
 
Method Summary
 int compare(ExValue other)
          Compare one value with another.
 int compareNocase(ExValue other)
          Compare one value to another, ignoring case.
 ExValue copy()
          Make a copy of a value.
 void free()
          Return a value to its owners pool.
 int getInt()
          Get the value as an integer.
 java.lang.Object getObject()
          Get the value as an OBJECT.
 int getReferences()
          Get the reference count of the value.
 java.lang.String getString()
          Original signature that didn't require an ExState.
 java.lang.String getString(ExState state)
          Get the value as a string, coercing if necessary.
 java.lang.Class getType()
          Returns the type of the object.
 void incReferences()
          Increment the reference count of the value.
 boolean isInt()
          Returns true if the value is represented internally as an int.
 boolean isInterned()
          Test the interned status of the value.
 boolean isNull()
          Returns true if the value is logically null.
 boolean isObject()
          Returns true if the value is represented internally an opaque object.
 boolean isString()
          Returns true if the value is represented internally as a string.
 boolean isTrue()
          Returns true if the value is logically true.
 boolean isWritable()
          Tests to see if the value is writable.
 void setInt(int ival)
          Assign a primitive integer value.
 void setInterned(boolean i)
          Set the interned status of the value.
 void setNull()
          Make the value "null".
 void setObject(java.lang.Object obj)
          Assign an object value.
 void setOwner(ExState s)
          Set the owning state object for this value.
 void setReferences(int r)
          Set the reference count of the value.
 void setString(java.lang.String s)
          Assign a string to the value.
 void setValue(ExValue src)
          Set one value from another.
 void toString(java.lang.StringBuffer b)
          Render the value into a string buffer.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

code_id

public static final java.lang.String code_id
See Also:
Constant Field Values

STRING

public static final java.lang.Class STRING
Constants used for types.


INTEGER

public static final java.lang.Class INTEGER

OBJECT

public static final java.lang.Class OBJECT

ZERO

public static final ExValue ZERO
Built-in object for the representation of the number zero, also used for logical false.


ONE

public static final ExValue ONE
Built-in object for the representation of the number one, also used for logical true.


MINUSONE

public static final ExValue MINUSONE
Built-in object for the representation of the number minus one.

Constructor Detail

ExValue

public ExValue()
Construct a new value.

Normally this is called only from the ExState value pool, but you can make an independent object for testing.


ExValue

public ExValue(java.lang.Object o)
Construct a new value, initializing it to an object.

A convenience method since setValue throws an exception.


ExValue

public ExValue(int n)
Special private constructor for our static instances.

Method Detail

setOwner

public void setOwner(ExState s)
Set the owning state object for this value.

Once an owner is set, calling free() on this value will return it to the owners value pool.


free

public void free()
Return a value to its owners pool.


copy

public ExValue copy()
             throws WavesetException
Make a copy of a value.

Throws:
WavesetException

setInterned

public void setInterned(boolean i)
Set the interned status of the value.


isInterned

public boolean isInterned()
Test the interned status of the value.


getReferences

public int getReferences()
Get the reference count of the value.


setReferences

public void setReferences(int r)
Set the reference count of the value.


incReferences

public void incReferences()
Increment the reference count of the value.


isWritable

public boolean isWritable()
Tests to see if the value is writable.

This is true if the value is not interned and has only one reference. If this is true, the expression evaluator may need to "promote" the value to a writable one by copying it.


getType

public java.lang.Class getType()
Returns the type of the object.


isNull

public boolean isNull()
Returns true if the value is logically null.


isString

public boolean isString()
Returns true if the value is represented internally as a string.


isInt

public boolean isInt()
Returns true if the value is represented internally as an int.


isObject

public boolean isObject()
Returns true if the value is represented internally an opaque object.


isTrue

public boolean isTrue()
Returns true if the value is logically true.

We define truth here as being non-null, and numerically non-zero. If the value is an object of class Boolean, we convert it to a primitive boolean type.


getString

public java.lang.String getString(ExState state)
Get the value as a string, coercing if necessary.

If the value is null, null is returned.

If the value is an int, we coerce it to a string, and save the coerced value for later use.

If the value is an object, we'll call toString() on it.

This can be used with interned values, since the semantics of the value don't change, even though we may make some minor modifications as a side effect. UPDATE: Now accepting an ExState object so we can access the Locale. Pass the whole ExState in in case there's some other coercion option we need in the future.


getString

public java.lang.String getString()
Original signature that didn't require an ExState.


getInt

public int getInt()
Get the value as an integer.

If the type isn't INTEGER, we try to coerce it to one. We won't throw exceptions if the value doesn't coerce, the integer value will be zero.

We're not saving the coerced value, under the assumption that coercing this direction happens less often than coercing to a string.


getObject

public java.lang.Object getObject()
Get the value as an OBJECT.

If type is INTEGER, we'll construct an Integer object wrapper around the primitive _int value, though expressions should try to avoid that since it will quickly become garbage.


setNull

public void setNull()
             throws WavesetException
Make the value "null".

Throws:
WavesetException

setString

public void setString(java.lang.String s)
               throws WavesetException
Assign a string to the value.

Throws:
WavesetException

setInt

public void setInt(int ival)
            throws WavesetException
Assign a primitive integer value.

Throws:
WavesetException

setObject

public void setObject(java.lang.Object obj)
               throws WavesetException
Assign an object value.

Note that if the object is of class STRING, this is the same as calling setString.

It is important that Integers be downgraded to "int" primitives so that boolean operations work.

Throws:
WavesetException

setValue

public void setValue(ExValue src)
              throws WavesetException
Set one value from another.

Throws:
WavesetException

compare

public int compare(ExValue other)
Compare one value with another.

Return value is like strcmp(), -1, 0 or 1. For comparison direction "this", should be considered to be on the left.

We try to be minimize coercion overhead.


compareNocase

public int compareNocase(ExValue other)
Compare one value to another, ignoring case.


toString

public void toString(java.lang.StringBuffer b)
Render the value into a string buffer. Used in trace messages.