package expression.common; import base.Functional; import base.Pair; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; /** * @author Georgiy Korneev (kgeorgiy@kgeorgiy.info) */ public interface Renderer { static Builder builder(final Node.Const constant) { return new Builder<>(constant); } R render(final Expr expr, final S settings); @FunctionalInterface interface UnaryOperator { R apply(S settings, R arg); } @FunctionalInterface interface BinaryOperator { R apply(S settings, R arg1, R arg2); } final class Builder { private final Node.Const constant; private final Map> unary = new HashMap<>(); private final Map> binary = new HashMap<>(); private Builder(final Node.Const constant) { this.constant = constant; } public void unary(final String name, final UnaryOperator op) { unary.put(name, op); } public void binary(final String name, final BinaryOperator op) { binary.put(name, op); } public Renderer build() { return (expr, settings) -> { final Map vars = expr.variables().stream() .collect(Collectors.toMap(Pair::first, Pair::second)); return expr.node().cata( constant, name -> Functional.get(vars, name), (name, p, arg) -> Functional.get(unary, name).apply(settings, arg), (name, arg1, arg2) -> Functional.get(binary, name).apply(settings, arg1, arg2) ); }; } } }