54 lines
1.9 KiB
Java
54 lines
1.9 KiB
Java
package cljtest;
|
|
|
|
import clojure.lang.IFn;
|
|
import common.Engine;
|
|
|
|
import java.util.Optional;
|
|
|
|
/**
|
|
* Clojure tests engine.
|
|
*
|
|
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
|
|
*/
|
|
public class ClojureEngine implements Engine<Object> {
|
|
private static final IFn HASH_MAP = ClojureScript.var("clojure.core/hash-map");
|
|
|
|
private final Optional<IFn> evaluate;
|
|
private final String evaluateString;
|
|
private final ClojureScript.F<Object> parse;
|
|
private final ClojureScript.F<String> toString;
|
|
|
|
public ClojureEngine(final String script, final Optional<String> evaluate, final String parse, final String toString) {
|
|
ClojureScript.loadScript(script);
|
|
this.parse = ClojureScript.function(parse, Object.class);
|
|
this.toString = ClojureScript.function(toString, String.class);
|
|
|
|
this.evaluate = evaluate.map(ClojureScript::var);
|
|
evaluateString = evaluate.map(s -> s + " ").orElse("");
|
|
}
|
|
|
|
@Override
|
|
public Result<Object> prepare(final String expression) {
|
|
return new Result<>(expression, ClojureScript.LOAD_STRING_IN.invoke(expression));
|
|
}
|
|
|
|
@Override
|
|
public Result<Object> parse(final String expression) {
|
|
return parse.call(new Result<>("\"" + expression + "\"", expression));
|
|
}
|
|
|
|
@Override
|
|
public Result<Number> evaluate(final Result<Object> prepared, final double[] vars) {
|
|
final Object map = HASH_MAP.invoke("x", vars[0], "y", vars[1], "z", vars[2]);
|
|
final String context = "(%sexpr %s)\nwhere expr = %s".formatted(evaluateString, map, prepared.context());
|
|
return evaluate
|
|
.map(f -> ClojureScript.call(f, Number.class, context, new Object[]{prepared.value(), map}))
|
|
.orElseGet(() -> ClojureScript.call((IFn) prepared.value(), Number.class, context, new Object[]{map}));
|
|
}
|
|
|
|
@Override
|
|
public Result<String> toString(final Result<Object> prepared) {
|
|
return toString.call(prepared);
|
|
}
|
|
}
|