Expression.java
package org.sterling.runtime.expression;
import static org.sterling.runtime.expression.BooleanConstant.FALSE;
import static org.sterling.runtime.expression.ExpressionConversions.convertSymbol;
import static org.sterling.runtime.expression.ExpressionFactory.constant;
import org.sterling.SterlingException;
import org.sterling.runtime.exception.AppliedExpressionException;
import org.sterling.runtime.exception.UndefinedMemberException;
public abstract class Expression {
public <R, D> R accept(ExpressionVisitor<R, D> visitor, D data) throws SterlingException {
return visitor.visitPrimaryExpression(this, data);
}
public Expression access(Expression member) throws SterlingException {
Symbol symbol = convertSymbol(member);
switch (symbol.getValue()) {
case "isNothing": return FALSE;
case "toString": return constant(toString());
default: throw new UndefinedMemberException(
"Expression '" + getName() + "' does not define member '" + symbol.getValue() + "'"
);
}
}
public Expression apply(Expression argument) throws SterlingException {
throw new AppliedExpressionException("Cannot apply arguments to '" + getName() + "' expression");
}
public Expression evaluate() throws SterlingException {
Expression expression = reduce();
while (expression.isReducible()) {
expression = expression.reduce();
}
return expression;
}
public Expression reduce() throws SterlingException {
return this;
}
protected boolean isReducible() {
return false;
}
private String getName() {
return getClass().getSimpleName();
}
}