package net.iplantevin.ql.evaluation;
/**
* Declares default implementations for double dispatch on Value subtypes. All
* operations must return Value objects, if an operation is not valid, return
* the Undefined type (default for all operations except equal and notEqual).
*
* @author Ivan
*/
public abstract class Value {
private static final UndefinedVal UNDEFINED = new UndefinedVal();
// Every Value subtype must return a value (e.g. Integer, UndefinedVal, ...)
// so the return type of the abstract method is Object.
public abstract Object getValue();
/**
* Since |equals| cannot be used with UndefinedVal, another way is necessary
* to know whether you've got an UndefinedVal.
*
* @return whether this Value is an UndefinedVal.
*/
public boolean isUndefined() {
return false;
}
// Equality operations, the only ones that work between all Value subtypes.
public BoolVal equal(Value argument) {
return new BoolVal(this.equals(argument));
}
public BoolVal notEqual(Value argument) {
return new BoolVal(this.equals(argument));
}
// The other operations return default UndefinedVal (from field).
public Value add(Value argument) {
return UNDEFINED;
}
public Value sub(Value argument) {
return UNDEFINED;
}
public Value mul(Value argument) {
return UNDEFINED;
}
public Value div(Value argument) {
return UNDEFINED;
}
public Value and(Value argument) {
return UNDEFINED;
}
public Value or(Value argument) {
return UNDEFINED;
}
public Value not() {
return UNDEFINED;
}
public Value geq(Value argument) {
return UNDEFINED;
}
public Value gt(Value argument) {
return UNDEFINED;
}
public Value leq(Value argument) {
return UNDEFINED;
}
public Value lt(Value argument) {
return UNDEFINED;
}
public Value neg() {
return UNDEFINED;
}
public Value pos() {
return UNDEFINED;
}
// Methods for double dispatch. For each of the above operations, given a
// specific Value type, if the operation will be used, a corresponding double
// dispatch method must be defined.
// Note: crucial is the specific Value types used as arguments instead of
// generic Value type! (And double dispatch not needed for unary operators)
// Note: protected, since should only be relevant and visible to Value objects.
protected Value boolAnd(BoolVal argument) {
return UNDEFINED;
}
protected Value boolOr(BoolVal argument) {
return UNDEFINED;
}
protected Value intAdd(IntVal argument) {
return UNDEFINED;
}
protected Value intSub(IntVal argument) {
return UNDEFINED;
}
protected Value intMul(IntVal argument) {
return UNDEFINED;
}
protected Value intDiv(IntVal argument) {
return UNDEFINED;
}
protected Value intGeq(IntVal argument) {
return UNDEFINED;
}
protected Value intGt(IntVal argument) {
return UNDEFINED;
}
protected Value intLeq(IntVal argument) {
return UNDEFINED;
}
protected Value intLt(IntVal argument) {
return UNDEFINED;
}
// Default toString relies on toString of internal value of a Value object.
@Override
public String toString() {
return getValue().toString();
}
}