Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
main.io.github.moonlightsuite.moonlight.script.BiParametricExpressionEvaluator Maven / Gradle / Ivy
package io.github.moonlightsuite.moonlight.script;
import io.github.moonlightsuite.moonlight.core.base.MoonLightRecord;
import io.github.moonlightsuite.moonlight.offline.signal.RecordHandler;
import org.antlr.v4.runtime.ParserRuleContext;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
public class BiParametricExpressionEvaluator extends MoonLightScriptBaseVisitor> {
private static final Map> binaryFunctionMap = new HashMap<>();
static {
binaryFunctionMap.put("atan2", Math::atan2);
binaryFunctionMap.put("hypot", Math::hypot);
binaryFunctionMap.put("max", Math::max);
binaryFunctionMap.put("min", Math::min);
binaryFunctionMap.put("pow", Math::pow);
}
private static final Map> unaryFunctionMap = new HashMap<>();
static {
unaryFunctionMap.put("abs", Math::abs);
unaryFunctionMap.put("acos", Math::acos);
unaryFunctionMap.put("asin", Math::asin);
unaryFunctionMap.put("atan", Math::atan);
unaryFunctionMap.put("cbrt", Math::cbrt);
unaryFunctionMap.put("ceil", Math::ceil);
unaryFunctionMap.put("cos", Math::cos);
unaryFunctionMap.put("cosh", Math::cosh);
unaryFunctionMap.put("exp", Math::exp);
unaryFunctionMap.put("expm1", Math::expm1);
unaryFunctionMap.put("floor", Math::floor);
unaryFunctionMap.put("log", Math::log);
unaryFunctionMap.put("log10", Math::log10);
unaryFunctionMap.put("log1p", Math::log1p);
unaryFunctionMap.put("signum", Math::signum);
unaryFunctionMap.put("sin", Math::sin);
unaryFunctionMap.put("sqrt", Math::sqrt);
unaryFunctionMap.put("sinh", Math::sinh);
unaryFunctionMap.put("tan", Math::tan);
}
private final List errors;
private final NameResolver resolver;
private final RecordHandler firstGroupHandler; //Record handler for formula parameters;
private final RecordHandler secondGroupHandler; //Record handler for signal expressions;
private BiParametricBooleanExpressionEvaluator signalPredicateEvaluator ;
public BiParametricExpressionEvaluator(
List errors,
NameResolver resolver,
RecordHandler firstGroupHandler,
RecordHandler secondGroupHandler) {
this.errors = errors;
this.resolver = resolver;
this.firstGroupHandler = firstGroupHandler;
this.secondGroupHandler = secondGroupHandler;
}
public BiParametricExpressionEvaluator(
NameResolver resolver,
RecordHandler firstGroupHandler,
RecordHandler secondGroupHandler) {
this(new LinkedList<>(),resolver, firstGroupHandler, secondGroupHandler);
}
@Override
protected BiFunction defaultResult() {
return (r,s) -> Double.NaN;
}
@Override
public BiFunction visitBinaryMathCallExpression(MoonLightScriptParser.BinaryMathCallExpressionContext ctx) {
BiFunction opFunction = getBinaryFunction(ctx.binaryMathFunction());
return doApply(ctx,opFunction,ctx.left.accept(this),ctx.right.accept(this));
}
private BiFunction getBinaryFunction(MoonLightScriptParser.BinaryMathFunctionContext binaryMathFunction) {
String funName = binaryMathFunction.getText();
BiFunction fun = binaryFunctionMap.get(funName);
if (fun == null) {
errors.add(MoonLightParseError.illegalFunctionName(funName,binaryMathFunction.start));
return (x,y) -> Double.NaN;
}
return fun;
}
private BiFunction doApply(ParserRuleContext ctx, BiFunction fun, BiFunction arg1, BiFunction arg2) {
return (r,s) -> fun.apply(arg1.apply(r,s), arg2.apply(r,s));
}
@Override
public BiFunction visitBracketExpression(MoonLightScriptParser.BracketExpressionContext ctx) {
return ctx.expression().accept(this);
}
@Override
public BiFunction visitUnaryMathCallExpression(MoonLightScriptParser.UnaryMathCallExpressionContext ctx) {
Function fun = getUnaryFunction(ctx.fun);
return doApply(ctx,fun,ctx.argument.accept(this));
}
private BiFunction doApply(ParserRuleContext ctx, Function fun, BiFunction arg) {
return (r,s) -> fun.apply(arg.apply(r,s));
}
private Function getUnaryFunction(MoonLightScriptParser.UnaryMathFunctionContext unaryMathFunction) {
String funName = unaryMathFunction.getText();
Function fun = unaryFunctionMap.get(funName);
if (fun == null) {
errors.add(MoonLightParseError.illegalFunctionName(funName,unaryMathFunction.start));
return x -> Double.NaN;
}
return fun;
}
@Override
public BiFunction visitRealExpression(MoonLightScriptParser.RealExpressionContext ctx) {
return (r,s) -> Double.parseDouble(ctx.getText());
}
@Override
public BiFunction visitUnaryExpression(MoonLightScriptParser.UnaryExpressionContext ctx) {
Function fun;
if (ctx.op.getText().equals("-")) {
fun = x -> -x;
return doApply(ctx,fun,ctx.arg.accept(this));
} else {
return ctx.arg.accept(this);
}
}
@Override
public BiFunction visitReferenceExpression(MoonLightScriptParser.ReferenceExpressionContext ctx) {
String name = ctx.name.getText();
double value = resolver.get(name);
if (!Double.isNaN(value)) {
return (r,s) -> value;
}
if (firstGroupHandler.isAVariable(name)) {
int idx = firstGroupHandler.getVariableIndex(name);
return (r,s) -> r.getDoubleOf(idx);
}
if (secondGroupHandler.isAVariable(name)) {
int vIndex = secondGroupHandler.getVariableIndex(name);
return (r,s) -> s.getDoubleOf(vIndex);
}
errors.add(MoonLightParseError.useOfAnUnknownName(name,ctx));
return (r,s) -> Double.NaN;
}
@Override
public BiFunction visitIntExpression(MoonLightScriptParser.IntExpressionContext ctx) {
double i = (double) Integer.parseInt(ctx.getText());
return (r,s) -> i;
}
@Override
public BiFunction visitIfThenElseExpression(MoonLightScriptParser.IfThenElseExpressionContext ctx) {
BiParametricBooleanExpressionEvaluator signalPredicateEvaluator = getSignalPredicateEvaluator();
BiFunction guard = ctx.guard.accept(signalPredicateEvaluator);
BiFunction thenBranch = ctx.thenExpression.accept(this);
BiFunction elseBranch = ctx.elseExpression.accept( this);
return (r,s) -> (guard.apply(r,s)?thenBranch.apply(r,s):elseBranch.apply(r,s));
}
private synchronized BiParametricBooleanExpressionEvaluator getSignalPredicateEvaluator() {
if (signalPredicateEvaluator == null) {
signalPredicateEvaluator = new BiParametricBooleanExpressionEvaluator(this);
}
return signalPredicateEvaluator;
}
@Override
public BiFunction visitMulDivExpression(MoonLightScriptParser.MulDivExpressionContext ctx) {
BiFunction fun;
if (ctx.op.getText().equals("*")) {
fun = (x,y) -> x*y;
} else {
fun = (x,y) -> x/y;
}
return doApply(ctx,fun,ctx.left.accept(this),ctx.right.accept(this));
}
@Override
public BiFunction visitSumDifExpression(MoonLightScriptParser.SumDifExpressionContext ctx) {
BiFunction fun;
if (ctx.op.getText().equals("+")) {
fun = Double::sum;
} else {
if (ctx.op.getText().equals("-")) {
fun = (x,y) -> x-y;
} else {
fun = (x,y) -> x%y;
}
}
return doApply(ctx,fun,ctx.left.accept(this),ctx.right.accept(this));
}
@Override
public BiFunction visitInfinityExpression(MoonLightScriptParser.InfinityExpressionContext ctx) {
return (r,s) -> Double.POSITIVE_INFINITY;
}
public BiFunction eval(MoonLightScriptParser.ExpressionContext value) {
return value.accept(this);
}
}