ArgumentBinder.java
package org.sterling.runtime.expression;
import static org.sterling.runtime.expression.ExpressionFactory.access;
import static org.sterling.runtime.expression.ExpressionFactory.apply;
import static org.sterling.runtime.expression.ExpressionFactory.declaration;
import static org.sterling.runtime.expression.ExpressionFactory.lambda;
import java.util.HashSet;
import java.util.Set;
import org.sterling.SterlingException;
public class ArgumentBinder implements ExpressionVisitor<Expression, Argument> {
private static final ArgumentBinder INSTANCE = new ArgumentBinder();
public static Expression bindArgument(Expression expression, Argument argument) throws SterlingException {
return INSTANCE.visit(expression, argument);
}
private ArgumentBinder() {
// intentionally empty
}
@Override
public Expression visit(Expression expression, Argument argument) throws SterlingException {
return expression.accept(this, argument);
}
@Override
public Expression visitAccessExpression(AccessedExpression expression, Argument argument) throws SterlingException {
return access(visit(expression.getExpression(), argument), visit(expression.getMember(), argument));
}
@Override
public Expression visitApplyExpression(AppliedExpression expression, Argument argument) throws SterlingException {
return apply(visit(expression.getExpression(), argument), visit(expression.getArgument(), argument));
}
@Override
public Expression visitArgumentExpression(Argument expression, Argument argument) throws SterlingException {
throw new UnsupportedOperationException();
}
@Override
public Expression visitBindExpression(BoundExpression expression, Argument argument) throws SterlingException {
throw new UnsupportedOperationException();
}
@Override
public Expression visitLambda(Lambda lambda, Argument argument) throws SterlingException {
if (argument.isApplicableTo(lambda)) {
return lambda(lambda.getVariable(), visit(lambda.getExpression(), argument));
} else {
return lambda;
}
}
@Override
public Expression visitObjectExpression(ObjectExpression object, Argument argument) throws SterlingException {
Set<DeclaredExpression> declarations = new HashSet<>();
for (DeclaredExpression declaration : object.getMembers()) {
declarations.add(declaration(declaration.getSymbol(), visit(declaration.getExpression(), argument)));
}
return new ObjectExpression(declarations);
}
@Override
public Expression visitPrimaryExpression(Expression expression, Argument argument) throws SterlingException {
if (argument.replaces(expression)) {
return argument.getExpression();
} else {
return expression;
}
}
@Override
public Expression visitReference(Reference reference, Argument data) throws SterlingException {
return visit(reference.reduce(), data);
}
}