use of org.projectnessie.cel.interpreter.Interpretable.InterpretableConst in project cel-java by projectnessie.
the class CELTest method CustomInterpreterDecorator.
@Test
void CustomInterpreterDecorator() {
AtomicReference<Interpretable> lastInstruction = new AtomicReference<>();
InterpretableDecorator optimizeArith = i -> {
lastInstruction.set(i);
// Only optimize the instruction if it is a call.
if (!(i instanceof InterpretableCall)) {
return i;
}
InterpretableCall call = (InterpretableCall) i;
// Only optimize the math functions when they have constant arguments.
switch(call.function()) {
case "_+_":
case "_-_":
case "_*_":
case "_/_":
// These are all binary operators so they should have to arguments
Interpretable[] args = call.args();
// an empty activation and the value returns as a constant.
if (!(args[0] instanceof InterpretableConst) || !(args[1] instanceof InterpretableConst)) {
return i;
}
Val val = call.eval(emptyActivation());
if (isError(val)) {
throw new RuntimeException(val.toString());
}
return newConstValue(call.id(), val);
default:
return i;
}
};
Env env = newEnv(declarations(Decls.newVar("foo", Decls.Int)));
AstIssuesTuple astIss = env.compile("foo == -1 + 2 * 3 / 3");
env.program(astIss.getAst(), evalOptions(OptPartialEval), customDecorator(optimizeArith));
assertThat(lastInstruction.get()).isInstanceOf(InterpretableCall.class);
InterpretableCall call = (InterpretableCall) lastInstruction.get();
Interpretable[] args = call.args();
Interpretable lhs = args[0];
assertThat(lhs).isInstanceOf(InterpretableAttribute.class);
InterpretableAttribute lastAttr = (InterpretableAttribute) lhs;
NamespacedAttribute absAttr = (NamespacedAttribute) lastAttr.attr();
String[] varNames = absAttr.candidateVariableNames();
assertThat(varNames).containsExactly("foo");
Interpretable rhs = args[1];
assertThat(rhs).isInstanceOf(InterpretableConst.class);
InterpretableConst lastConst = (InterpretableConst) rhs;
// This is the last number produced by the optimization.
assertThat(lastConst.value()).isSameAs(IntOne);
}
use of org.projectnessie.cel.interpreter.Interpretable.InterpretableConst in project cel-java by projectnessie.
the class AttributesTest method attributesRelativeAttr.
@Test
void attributesRelativeAttr() {
TypeRegistry reg = newRegistry();
AttributeFactory attrs = newAttributeFactory(Container.defaultContainer, reg, reg);
Map<Object, Object> data = mapOf("a", mapOf(-1, new int[] { 2, 42 }), "b", 1);
Activation vars = newActivation(data);
// The relative attribute under test is applied to a map literal:
// {
// a: {-1: [2, 42], b: 1}
// b: 1
// }
//
// The expression being evaluated is: <map-literal>.a[-1][b] -> 42
InterpretableConst op = newConstValue(1, reg.nativeToValue(data));
Attribute attr = attrs.relativeAttribute(1, op);
Qualifier qualA = attrs.newQualifier(null, 2, "a");
Qualifier qualNeg1 = attrs.newQualifier(null, 3, intOf(-1));
attr.addQualifier(qualA);
attr.addQualifier(qualNeg1);
attr.addQualifier(attrs.absoluteAttribute(4, "b"));
Object out = attr.resolve(vars);
assertThat(out).isEqualTo(intOf(42));
assertThat(estimateCost(attr)).extracting("min", "max").containsExactly(1L, 1L);
}
use of org.projectnessie.cel.interpreter.Interpretable.InterpretableConst in project cel-java by projectnessie.
the class AttributesTest method attributesRelativeAttr_OneOf.
@Test
void attributesRelativeAttr_OneOf() {
TypeRegistry reg = newRegistry();
Container cont = newContainer(Container.name("acme.ns"));
AttributeFactory attrs = newAttributeFactory(cont, reg, reg);
Map<Object, Object> data = mapOf("a", mapOf(-1, new int[] { 2, 42 }), "acme.b", 1);
Activation vars = newActivation(data);
// The relative attribute under test is applied to a map literal:
// {
// a: {-1: [2, 42], b: 1}
// b: 1
// }
//
// The expression being evaluated is: <map-literal>.a[-1][b] -> 42
//
// However, since the test is validating what happens with maybe attributes
// the attribute resolution must also consider the following variations:
// - <map-literal>.a[-1][acme.ns.b]
// - <map-literal>.a[-1][acme.b]
//
// The correct behavior should yield the value of the last alternative.
InterpretableConst op = newConstValue(1, reg.nativeToValue(data));
Attribute attr = attrs.relativeAttribute(1, op);
Qualifier qualA = attrs.newQualifier(null, 2, "a");
Qualifier qualNeg1 = attrs.newQualifier(null, 3, intOf(-1));
attr.addQualifier(qualA);
attr.addQualifier(qualNeg1);
attr.addQualifier(attrs.maybeAttribute(4, "b"));
Object out = attr.resolve(vars);
assertThat(out).isEqualTo(intOf(42));
assertThat(estimateCost(attr)).extracting("min", "max").containsExactly(1L, 1L);
}
use of org.projectnessie.cel.interpreter.Interpretable.InterpretableConst in project cel-java by projectnessie.
the class InterpretableDecorator method maybeOptimizeConstUnary.
static Interpretable maybeOptimizeConstUnary(Interpretable i, InterpretableCall call) {
Interpretable[] args = call.args();
if (args.length != 1) {
return i;
}
if (!(args[0] instanceof InterpretableConst)) {
return i;
}
Val val = call.eval(emptyActivation());
throwErrorAsIllegalStateException(val);
return newConstValue(call.id(), val);
}
use of org.projectnessie.cel.interpreter.Interpretable.InterpretableConst in project cel-java by projectnessie.
the class InterpretableDecorator method maybeOptimizeSetMembership.
/**
* maybeOptimizeSetMembership may convert an 'in' operation against a list to map key membership
* test if the following conditions are true:
*
* <ul>
* <li>the list is a constant with homogeneous element types.
* <li>the elements are all of primitive type.
* </ul>
*/
static Interpretable maybeOptimizeSetMembership(Interpretable i, InterpretableCall inlist) {
Interpretable[] args = inlist.args();
Interpretable lhs = args[0];
Interpretable rhs = args[1];
if (!(rhs instanceof InterpretableConst)) {
return i;
}
InterpretableConst l = (InterpretableConst) rhs;
// When the incoming binary call is flagged with as the InList overload, the value will
// always be convertible to a `traits.Lister` type.
Lister list = (Lister) l.value();
if (list.size() == IntZero) {
return newConstValue(inlist.id(), False);
}
IteratorT it = list.iterator();
Type typ = null;
Set<Val> valueSet = new HashSet<>();
while (it.hasNext() == True) {
Val elem = it.next();
if (!Util.isPrimitiveType(elem)) {
// Note, non-primitive type are not yet supported.
return i;
}
if (typ == null) {
typ = elem.type();
} else if (!typ.typeName().equals(elem.type().typeName())) {
return i;
}
valueSet.add(elem);
}
return new EvalSetMembership(inlist, lhs, typ.typeName(), valueSet);
}
Aggregations