67 lines
2.0 KiB
Java
67 lines
2.0 KiB
Java
package jstest;
|
|
|
|
import common.Engine;
|
|
|
|
import java.nio.file.Path;
|
|
import java.util.Arrays;
|
|
import java.util.stream.Collectors;
|
|
|
|
/**
|
|
* Expression-aware JavaScript engine.
|
|
*
|
|
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
|
|
*/
|
|
public class JSExpressionEngine implements Engine<Object> {
|
|
private final JSEngine engine;
|
|
private final String evaluate;
|
|
private final String parse;
|
|
private final String toString;
|
|
|
|
public JSExpressionEngine(final Path script, final String evaluate, final String parse, final String toString) {
|
|
engine = new JSEngine(script);
|
|
this.evaluate = evaluate;
|
|
this.parse = parse;
|
|
this.toString = toString;
|
|
}
|
|
|
|
@Override
|
|
public Result<Object> prepare(final String expression) {
|
|
return parse("eval", expression);
|
|
}
|
|
|
|
@Override
|
|
public Result<Object> parse(final String expression) {
|
|
return parse(parse, expression);
|
|
}
|
|
|
|
private Result<Object> parse(final String parse, final String expression) {
|
|
return engine.eval(expression, "%s(\"%s\")".formatted(parse, expression), Object.class);
|
|
}
|
|
|
|
@Override
|
|
public Result<Number> evaluate(final Result<Object> prepared, final double[] vars) {
|
|
final String code = "expr%s(%s);".formatted(
|
|
evaluate,
|
|
Arrays.stream(vars).mapToObj("%.20f"::formatted).collect(Collectors.joining(","))
|
|
);
|
|
return evaluate(prepared, code, Number.class);
|
|
}
|
|
|
|
public Result<String> toString(final Result<Object> prepared) {
|
|
return evaluate(prepared, "expr." + toString + "()", String.class);
|
|
}
|
|
|
|
protected <T> Engine.Result<T> evaluate(
|
|
final Engine.Result<Object> prepared,
|
|
final String code,
|
|
final Class<T> result
|
|
) {
|
|
engine.set("expr", prepared);
|
|
return engine.eval(
|
|
"%n in %s%n where expr = %s%n".formatted(code, prepared.context()),
|
|
code,
|
|
result
|
|
);
|
|
}
|
|
}
|