IntegerConstant.java
package org.sterling.runtime.expression;
import static java.lang.String.valueOf;
import static org.sterling.runtime.expression.BooleanConstant.FALSE;
import static org.sterling.runtime.expression.BooleanConstant.TRUE;
import static org.sterling.runtime.expression.ExpressionConversions.convertInteger;
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 IntegerConstant extends Expression {
private final int value;
public IntegerConstant(int value) {
this.value = 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 "<<": return new LeftShiftClosure(value);
case ">>": return new SignedRightShiftClosure(value);
case ">>>": return new RightShiftClosure(value);
case "&": return new BitwiseAndClosure(value);
case "|": return new BitwiseOrClosure(value);
case "^": return new BitwiseXorClosure(value);
case "<": return new LessThanClosure(value);
case "<=": return new LessThanEqualsClosure(value);
case "positive": return new IntegerConstant(Math.abs(value));
case "negative": return new IntegerConstant(-value);
case "toBoolean": return toBoolean();
case "toInteger": return this;
case "toString": return constant(valueOf(value));
case "toDouble": return new DoubleConstant(Integer.valueOf(value).doubleValue());
default: return super.access(member);
}
}
@Override
public boolean equals(Object o) {
return o == this || o instanceof IntegerConstant && value == ((IntegerConstant) o).value;
}
@Override
public int hashCode() {
return Objects.hash(value);
}
@Override
public String toString() {
return stringify(this, value);
}
private BooleanConstant toBoolean() {
return value == 1 ? TRUE : FALSE;
}
private static abstract class IntegerClosure extends Expression {
private final int value;
public IntegerClosure(int value) {
this.value = value;
}
@Override
public Expression apply(Expression argument) throws SterlingException {
return new IntegerConstant(operate(value, convertInteger(argument).value));
}
@Override
public String toString() {
return stringify(this, value);
}
protected abstract int operate(int leftValue, int rightValue);
}
private static final class AddClosure extends IntegerClosure {
public AddClosure(int value) {
super(value);
}
@Override
protected int operate(int leftValue, int rightValue) {
return leftValue + rightValue;
}
}
private static final class SubtractClosure extends IntegerClosure {
public SubtractClosure(int value) {
super(value);
}
@Override
protected int operate(int leftValue, int rightValue) {
return leftValue - rightValue;
}
}
private static final class MultiplyClosure extends IntegerClosure {
public MultiplyClosure(int value) {
super(value);
}
@Override
protected int operate(int leftValue, int rightValue) {
return leftValue * rightValue;
}
}
private static final class DivideClosure extends IntegerClosure {
public DivideClosure(int value) {
super(value);
}
@Override
protected int operate(int leftValue, int rightValue) {
return leftValue / rightValue;
}
}
private static final class ModuloClosure extends IntegerClosure {
public ModuloClosure(int value) {
super(value);
}
@Override
protected int operate(int leftValue, int rightValue) {
return leftValue % rightValue;
}
}
private static final class LeftShiftClosure extends IntegerClosure {
public LeftShiftClosure(int value) {
super(value);
}
@Override
protected int operate(int leftValue, int rightValue) {
return leftValue << rightValue;
}
}
private static final class RightShiftClosure extends IntegerClosure {
public RightShiftClosure(int value) {
super(value);
}
@Override
protected int operate(int leftValue, int rightValue) {
return leftValue >>> rightValue;
}
}
private static final class SignedRightShiftClosure extends IntegerClosure {
public SignedRightShiftClosure(int value) {
super(value);
}
@Override
protected int operate(int leftValue, int rightValue) {
return leftValue >> rightValue;
}
}
private static final class BitwiseAndClosure extends IntegerClosure {
public BitwiseAndClosure(int value) {
super(value);
}
@Override
protected int operate(int leftValue, int rightValue) {
return leftValue & rightValue;
}
}
private static final class BitwiseOrClosure extends IntegerClosure {
public BitwiseOrClosure(int value) {
super(value);
}
@Override
protected int operate(int leftValue, int rightValue) {
return leftValue | rightValue;
}
}
private static final class BitwiseXorClosure extends IntegerClosure {
public BitwiseXorClosure(int value) {
super(value);
}
@Override
protected int operate(int leftValue, int rightValue) {
return leftValue ^ rightValue;
}
}
private static final class LessThanClosure extends Expression {
private final int value;
public LessThanClosure(int value) {
this.value = value;
}
@Override
public Expression apply(Expression argument) throws SterlingException {
return value < convertInteger(argument).value ? TRUE : FALSE;
}
}
private static class LessThanEqualsClosure extends Expression {
private final int value;
public LessThanEqualsClosure(int value) {
this.value = value;
}
@Override
public Expression apply(Expression argument) throws SterlingException {
return value <= convertInteger(argument).value ? TRUE : FALSE;
}
}
}