DoubleConstant.java
package org.sterling.runtime.expression;
import static org.sterling.runtime.expression.BooleanConstant.FALSE;
import static org.sterling.runtime.expression.BooleanConstant.TRUE;
import static org.sterling.runtime.expression.ExpressionConversions.convertDouble;
import static org.sterling.runtime.expression.ExpressionConversions.convertSymbol;
import static org.sterling.runtime.expression.ExpressionFactory.constant;
import static org.sterling.util.StringUtil.stringify;
import java.util.Objects;
import org.sterling.SterlingException;
public class DoubleConstant extends Expression {
private final double value;
public DoubleConstant(double value) {
this.value = value;
}
@Override
public boolean equals(Object o) {
return o == this || o instanceof DoubleConstant && value == ((DoubleConstant) o).value;
}
@Override
public Expression access(Expression member) throws SterlingException {
switch (convertSymbol(member).getValue()) {
case "+": return new AddClosure(value);
case "-": return new SubtractClosure(value);
case "*": return new MultiplyClosure(value);
case "/": return new DivideClosure(value);
case "%": return new ModuloClosure(value);
case "positive": return new DoubleConstant(Math.abs(value));
case "negative": return new DoubleConstant(-value);
case "toBoolean": return toBoolean();
case "toInteger": return new IntegerConstant(Double.valueOf(value).intValue());
case "toDouble": return this;
case "toString": return constant(Double.valueOf(value).toString());
default: return super.access(member);
}
}
@Override
public int hashCode() {
return Objects.hash(value);
}
@Override
public String toString() {
return stringify(this, value);
}
private BooleanConstant toBoolean() {
return value == 1D ? TRUE : FALSE;
}
private static abstract class DoubleClosure extends Expression {
private final double value;
public DoubleClosure(double value) {
this.value = value;
}
@Override
public Expression apply(Expression argument) throws SterlingException {
return new DoubleConstant(operate(value, convertDouble(argument).value));
}
@Override
public String toString() {
return stringify(this, value);
}
protected abstract double operate(double leftValue, double rightValue);
}
private static final class AddClosure extends DoubleClosure {
public AddClosure(double value) {
super(value);
}
@Override
protected double operate(double leftValue, double rightValue) {
return leftValue + rightValue;
}
}
private static final class SubtractClosure extends DoubleClosure {
public SubtractClosure(double value) {
super(value);
}
@Override
protected double operate(double leftValue, double rightValue) {
return leftValue - rightValue;
}
}
private static final class MultiplyClosure extends DoubleClosure {
public MultiplyClosure(double value) {
super(value);
}
@Override
protected double operate(double leftValue, double rightValue) {
return leftValue * rightValue;
}
}
private static final class DivideClosure extends DoubleClosure {
public DivideClosure(double value) {
super(value);
}
@Override
protected double operate(double leftValue, double rightValue) {
return leftValue / rightValue;
}
}
private static final class ModuloClosure extends DoubleClosure {
public ModuloClosure(double value) {
super(value);
}
@Override
protected double operate(double leftValue, double rightValue) {
return leftValue % rightValue;
}
}
}