Skip to content
This repository has been archived by the owner on Oct 20, 2024. It is now read-only.

Commit

Permalink
Fold boolean and null constants, make hasContext and `structContain…
Browse files Browse the repository at this point in the history
…sKey` VarArgs.
  • Loading branch information
melontini committed May 9, 2024
1 parent 3b5efec commit ea513b4
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import me.melontini.commander.impl.expression.extensions.ReflectiveValueConverter;
import me.melontini.commander.impl.expression.functions.*;
import me.melontini.commander.impl.expression.functions.arrays.*;
import me.melontini.commander.impl.mixin.evalex.EvaluationValueAccessor;
import me.melontini.commander.impl.mixin.evalex.ExpressionAccessor;
import me.melontini.commander.impl.mixin.evalex.ExpressionConfigurationAccessor;
import me.melontini.commander.impl.mixin.evalex.MapBasedFunctionDictionaryAccessor;
Expand All @@ -35,6 +36,9 @@
public class EvalUtils {

public static final ExpressionConfiguration CONFIGURATION;
public static final EvaluationValue TRUE = EvaluationValueAccessor.commander$init(true, EvaluationValue.DataType.BOOLEAN);
public static final EvaluationValue FALSE = EvaluationValueAccessor.commander$init(false, EvaluationValue.DataType.BOOLEAN);
public static final EvaluationValue NULL = EvaluationValueAccessor.commander$init(null, EvaluationValue.DataType.NULL);

static {
var builder = ExpressionConfiguration.builder()
Expand All @@ -58,19 +62,19 @@ public class EvalUtils {
functions.put("arrayFind", new ArrayFind());
functions.put("arrayAnyMatch", new ArrayAnyMatch());
functions.put("arrayNoneMatch", new ArrayNoneMatch());
functions.put("arrayAllMatch", new ArrayNoneMatch());
functions.put("arrayAllMatch", new ArrayAllMatch());

functions.put("structContainsKey", new StructContainsKeyFunction());
functions.put("hasContext", new HasContextFunction());
builder.functionDictionary(SimpleFunctionDictionary.ofFunctions(functions));

CONFIGURATION = builder.build();
((ExpressionConfigurationAccessor) CONFIGURATION).commander$defaultConstants(ImmutableMap.of(
"true", EvaluationValue.booleanValue(true),
"false", EvaluationValue.booleanValue(false),
"true", TRUE,
"false", FALSE,
"PI", EvaluationValue.numberValue(new BigDecimal("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679")),
"E", EvaluationValue.numberValue(new BigDecimal("2.71828182845904523536028747135266249775724709369995957496696762772407663")),
"null", EvaluationValue.nullValue(),
"null", NULL,
"DT_FORMAT_ISO_DATE_TIME", EvaluationValue.stringValue("yyyy-MM-dd'T'HH:mm:ss[.SSS][XXX]['['VV']']"),
"DT_FORMAT_LOCAL_DATE_TIME", EvaluationValue.stringValue("yyyy-MM-dd'T'HH:mm:ss[.SSS]"),
"DT_FORMAT_LOCAL_DATE", EvaluationValue.stringValue("yyyy-MM-dd")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ public EvaluationValue evaluate(Expression expression, Token functionToken, Eval
BigDecimal value = par[0].getNumberValue();
BigDecimal min = par[1].getNumberValue();
BigDecimal max = par[2].getNumberValue();
return expression.convertValue(value.compareTo(min) < 0 ? min : value.min(max));
return EvaluationValue.numberValue(value.compareTo(min) < 0 ? min : value.min(max));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,22 @@
import com.ezylang.evalex.functions.AbstractFunction;
import com.ezylang.evalex.functions.FunctionParameter;
import com.ezylang.evalex.parser.Token;
import me.melontini.commander.impl.expression.EvalUtils;

@FunctionParameter(name = "key")
@FunctionParameter(name = "key", isVarArg = true)
public class HasContextFunction extends AbstractFunction {
@Override
public EvaluationValue evaluate(Expression expression, Token functionToken, EvaluationValue... par) throws EvaluationException {
return expression.convertValue(expression.getDataAccessor().getData(par[0].getStringValue()) != null);
return switch (par.length) {
case 0 -> EvalUtils.TRUE;
case 1 -> expression.getDataAccessor().getData(par[0].getStringValue()) != null ? EvalUtils.TRUE : EvalUtils.FALSE;
default -> {
var da = expression.getDataAccessor();
for (EvaluationValue value : par) {
if (da.getData(value.getStringValue()) == null) yield EvalUtils.FALSE;
}
yield EvalUtils.TRUE;
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ public EvaluationValue evaluate(Expression expression, Token functionToken, Eval
BigDecimal start = par[0].getNumberValue();
BigDecimal delta = par[1].getNumberValue();
BigDecimal end = par[2].getNumberValue();
return expression.convertValue(start.add(delta.multiply(end.subtract(start))));
return EvaluationValue.numberValue(start.add(delta.multiply(end.subtract(start))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,24 @@
import com.ezylang.evalex.functions.AbstractFunction;
import com.ezylang.evalex.functions.FunctionParameter;
import com.ezylang.evalex.parser.Token;
import me.melontini.commander.impl.expression.EvalUtils;

@FunctionParameter(name = "struct")
@FunctionParameter(name = "key")
@FunctionParameter(name = "key", isVarArg = true)
public class StructContainsKeyFunction extends AbstractFunction {
@Override
public EvaluationValue evaluate(Expression expression, Token functionToken, EvaluationValue... par) throws EvaluationException {
String key = par[1].getStringValue();
return expression.convertValue(par[0].getStructureValue().containsKey(key));
return switch (par.length) {
case 1 -> EvalUtils.TRUE;
case 2 -> par[0].getStructureValue().containsKey(par[1].getStringValue()) ? EvalUtils.TRUE : EvalUtils.FALSE;
default -> {
var struct = par[0].getStructureValue();
for (int i = 1; i < par.length; i++) {
var key = par[i].getStringValue();
if (!struct.containsKey(key)) yield EvalUtils.FALSE;
}
yield EvalUtils.TRUE;
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.ezylang.evalex.functions.FunctionParameter;
import com.ezylang.evalex.parser.ASTNode;
import com.ezylang.evalex.parser.Token;
import me.melontini.commander.impl.expression.EvalUtils;

import java.util.List;

Expand All @@ -21,6 +22,6 @@ public EvaluationValue evaluate(Expression expression, Token functionToken, Eval
List<EvaluationValue> array = par[0].getArrayValue();
ASTNode predicate = par[1].getExpressionNode();

return EvaluationValue.booleanValue(array.stream().anyMatch(value -> runLambda(expression, value, predicate).getBooleanValue()));
return array.stream().anyMatch(value -> runLambda(expression, value, predicate).getBooleanValue()) ? EvalUtils.TRUE : EvalUtils.FALSE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.ezylang.evalex.functions.FunctionParameter;
import com.ezylang.evalex.parser.ASTNode;
import com.ezylang.evalex.parser.Token;
import me.melontini.commander.impl.expression.EvalUtils;

import java.util.List;

Expand All @@ -21,6 +22,6 @@ public EvaluationValue evaluate(Expression expression, Token functionToken, Eval
List<EvaluationValue> array = par[0].getArrayValue();
ASTNode predicate = par[1].getExpressionNode();

return EvaluationValue.booleanValue(array.stream().anyMatch(value -> runLambda(expression, value, predicate).getBooleanValue()));
return array.stream().anyMatch(value -> runLambda(expression, value, predicate).getBooleanValue()) ? EvalUtils.TRUE : EvalUtils.FALSE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.ezylang.evalex.functions.FunctionParameter;
import com.ezylang.evalex.parser.ASTNode;
import com.ezylang.evalex.parser.Token;
import me.melontini.commander.impl.expression.EvalUtils;

import java.util.List;

Expand All @@ -21,6 +22,6 @@ public EvaluationValue evaluate(Expression expression, Token functionToken, Eval
List<EvaluationValue> array = par[0].getArrayValue();
ASTNode predicate = par[1].getExpressionNode();

return EvaluationValue.booleanValue(array.stream().noneMatch(value -> runLambda(expression, value, predicate).getBooleanValue()));
return array.stream().noneMatch(value -> runLambda(expression, value, predicate).getBooleanValue()) ? EvalUtils.TRUE : EvalUtils.FALSE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package me.melontini.commander.impl.mixin.evalex;

import com.ezylang.evalex.data.EvaluationValue;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;

@Mixin(value = EvaluationValue.class, remap = false)
public interface EvaluationValueAccessor {

@Invoker("<init>")
static EvaluationValue commander$init(Object value, EvaluationValue.DataType dataType) {
throw new IllegalStateException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package me.melontini.commander.impl.mixin.evalex;

import com.ezylang.evalex.data.EvaluationValue;
import me.melontini.commander.impl.expression.EvalUtils;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;

@Mixin(value = EvaluationValue.class, remap = false)
public class EvaluationValueMixin {

/**
* @author melontini
* @reason fold boolean constants
*/
@Overwrite
public static EvaluationValue booleanValue(Boolean value) {
return value ? EvalUtils.TRUE : EvalUtils.FALSE;
}

/**
* @author melontini
* @reason fold null constant
*/
@Overwrite
public static EvaluationValue nullValue() {
return EvalUtils.NULL;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package me.melontini.commander.impl.mixin.evalex;

import com.ezylang.evalex.Expression;
import com.ezylang.evalex.config.ExpressionConfiguration;
import com.ezylang.evalex.data.EvaluationValue;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;

@Mixin(value = Expression.class, remap = false)
public class ExpressionMixin {

@Shadow @Final private ExpressionConfiguration configuration;

/**
* @author melontini
* @reason avoid double object construction
*/
@Overwrite
public EvaluationValue convertValue(Object value) {
return configuration.getEvaluationValueConverter().convertObject(value, configuration);
}
}
3 changes: 3 additions & 0 deletions src/main/resources/commander.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
"compatibilityLevel": "JAVA_17",
"mixins": [
"AdvancementRewardsMixin",
"evalex.EvaluationValueAccessor",
"evalex.EvaluationValueMixin",
"evalex.ExpressionAccessor",
"evalex.ExpressionConfigurationAccessor",
"evalex.ExpressionMixin",
"evalex.MapBasedFunctionDictionaryAccessor",
"evalex.TokenizerMixin"
],
Expand Down

0 comments on commit ea513b4

Please sign in to comment.