package expression.common; import base.ExtendedRandom; import base.Functional; import base.Pair; import expression.ToMiniString; import java.util.List; /** * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) */ public class ExpressionKind { private final Type type; private final Class kind; private final Variables variables; private final Evaluator evaluator; public ExpressionKind( final Type type, final Class kind, final Variables variables, final Evaluator evaluator ) { this.type = type; this.kind = kind; this.variables = variables; this.evaluator = evaluator; } public ExpressionKind( final Type type, final Class kind, final List> variables, final Evaluator evaluator ) { this(type, kind, (r, c) -> variables, evaluator); } public C evaluate(final E expression, final List variables, final List values) throws Exception { return evaluator.evaluate(expression, variables, values); } public E cast(final Object expression) { return kind.cast(expression); } public String getName() { return kind.getSimpleName(); } public E constant(final C value) { return cast(type.constant(value)); } public C randomValue(final ExtendedRandom random) { return type.randomValue(random); } public List> allValues(final int length, final List values) { return Functional.allValues(fromInts(values), length); } public List fromInts(final List values) { return Functional.map(values, this::fromInt); } public C fromInt(final int value) { return type.fromInt(value); } @Override public String toString() { return kind.getName(); } public ExpressionKind withVariables(final Variables variables) { return new ExpressionKind<>(type, kind, variables, evaluator); } public Variables variables() { return variables; } @FunctionalInterface public interface Variables { List> generate(final ExtendedRandom random, final int count); } @FunctionalInterface public interface Evaluator { R evaluate(final E expression, final List vars, final List values) throws Exception; } }