Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions core/src/main/java/org/projectnessie/cel/extension/Guards.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import org.projectnessie.cel.common.types.StringT;
import org.projectnessie.cel.interpreter.functions.BinaryOp;
import org.projectnessie.cel.interpreter.functions.FunctionOp;
import org.projectnessie.cel.interpreter.functions.QuaternaryOp;
import org.projectnessie.cel.interpreter.functions.TernaryOp;
import org.projectnessie.cel.interpreter.functions.UnaryOp;

/** function invocation guards for common call signatures within extension functions. */
Expand Down Expand Up @@ -57,6 +59,19 @@ public static FunctionOp callInStrIntIntOutStr(
};
}

public static TernaryOp callInStrIntIntOutStrTernary(
TriFunction<String, Integer, Integer, String> func) {
return (first, second, third) -> {
try {
return StringT.stringOf(
func.apply(
(String) first.value(), getIntValue((IntT) second), getIntValue((IntT) third)));
} catch (RuntimeException e) {
return Err.newErr(e, "%s", e.getMessage());
}
};
}

public static BinaryOp callInStrStrOutInt(BiFunction<String, String, Integer> func) {
return (lhs, rhs) -> {
try {
Expand All @@ -82,6 +97,18 @@ public static FunctionOp callInStrStrIntOutInt(
};
}

public static TernaryOp callInStrStrIntOutIntTernary(
TriFunction<String, String, Integer, Integer> func) {
return (first, second, third) -> {
try {
return IntT.intOf(
func.apply((String) first.value(), (String) second.value(), getIntValue((IntT) third)));
} catch (RuntimeException e) {
return Err.newErr(e, "%s", e.getMessage());
}
};
}

public static BinaryOp callInStrStrOutStrArr(BiFunction<String, String, String[]> func) {
return (lhs, rhs) -> {
try {
Expand All @@ -107,6 +134,18 @@ public static FunctionOp callInStrStrIntOutStrArr(
};
}

public static TernaryOp callInStrStrIntOutStrArrTernary(
TriFunction<String, String, Integer, String[]> func) {
return (first, second, third) -> {
try {
return ListT.newStringArrayList(
func.apply((String) first.value(), (String) second.value(), getIntValue((IntT) third)));
} catch (RuntimeException e) {
return Err.newErr(e, "%s", e.getMessage());
}
};
}

public static FunctionOp callInStrStrStrOutStr(TriFunction<String, String, String, String> func) {
return values -> {
try {
Expand All @@ -121,6 +160,18 @@ public static FunctionOp callInStrStrStrOutStr(TriFunction<String, String, Strin
};
}

public static TernaryOp callInStrStrStrOutStrTernary(
TriFunction<String, String, String, String> func) {
return (first, second, third) -> {
try {
return StringT.stringOf(
func.apply((String) first.value(), (String) second.value(), (String) third.value()));
} catch (RuntimeException e) {
return Err.newErr(e, "%s", e.getMessage());
}
};
}

public static FunctionOp callInStrStrStrIntOutStr(
QuadFunction<String, String, String, Integer, String> func) {
return values -> {
Expand All @@ -137,6 +188,22 @@ public static FunctionOp callInStrStrStrIntOutStr(
};
}

public static QuaternaryOp callInStrStrStrIntOutStrQuaternary(
QuadFunction<String, String, String, Integer, String> func) {
return (first, second, third, fourth) -> {
try {
return StringT.stringOf(
func.apply(
(String) first.value(),
(String) second.value(),
(String) third.value(),
getIntValue((IntT) fourth)));
} catch (RuntimeException e) {
return Err.newErr(e, "%s", e.getMessage());
}
};
}

public static UnaryOp callInStrOutStr(UnaryOperator<String> func) {
return val -> {
try {
Expand Down
124 changes: 116 additions & 8 deletions core/src/main/java/org/projectnessie/cel/extension/MathLib.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@
import org.projectnessie.cel.common.types.UintT;
import org.projectnessie.cel.common.types.ref.Val;
import org.projectnessie.cel.common.types.traits.Lister;
import org.projectnessie.cel.interpreter.functions.FunctionOp;
import org.projectnessie.cel.interpreter.functions.Overload;
import org.projectnessie.cel.interpreter.functions.QuaternaryOp;
import org.projectnessie.cel.interpreter.functions.QuinaryOp;
import org.projectnessie.cel.interpreter.functions.TernaryOp;

/** MathLib provides CEL helper functions from the standard math extension library. */
public final class MathLib implements Library {
Expand Down Expand Up @@ -91,10 +95,34 @@ public List<EnvOption> getCompileOptions() {
public List<ProgramOption> getProgramOptions() {
List<Overload> overloads = new ArrayList<>();
overloads.add(
Overload.overload(GREATEST, null, MathLib::greatest, MathLib::greatest, MathLib::greatest));
overloads.add(Overload.overload(LEAST, null, MathLib::least, MathLib::least, MathLib::least));
addArityOverloads(overloads, GREATEST, MathLib::greatest);
addArityOverloads(overloads, LEAST, MathLib::least);
Overload.overload(
GREATEST,
null,
MathLib::greatest,
MathLib::greatest,
MathLib::greatest,
MathLib::greatest,
MathLib::greatest,
MathLib::greatest));
overloads.add(
Overload.overload(
LEAST,
null,
MathLib::least,
MathLib::least,
MathLib::least,
MathLib::least,
MathLib::least,
MathLib::least));
addArityOverloads(
overloads,
GREATEST,
MathLib::greatest,
MathLib::greatest,
MathLib::greatest,
MathLib::greatest);
addArityOverloads(
overloads, LEAST, MathLib::least, MathLib::least, MathLib::least, MathLib::least);
overloads.add(Overload.unary(CEIL, MathLib::ceil));
overloads.add(Overload.unary(overloadId(CEIL, 1), MathLib::ceil));
overloads.add(Overload.unary(FLOOR, MathLib::floor));
Expand Down Expand Up @@ -164,15 +192,18 @@ private static List<Type> dynArgs(int count) {
private static void addArityOverloads(
List<Overload> overloads,
String function,
org.projectnessie.cel.interpreter.functions.FunctionOp op) {
FunctionOp op,
TernaryOp ternaryOp,
QuaternaryOp quaternaryOp,
QuinaryOp quinaryOp) {
overloads.add(Overload.unary(overloadId(function, "int"), op::invoke));
overloads.add(Overload.unary(overloadId(function, "uint"), op::invoke));
overloads.add(Overload.unary(overloadId(function, "double"), op::invoke));
overloads.add(
Overload.binary(overloadId(function, 2), (left, right) -> op.invoke(left, right)));
for (int arity = 3; arity <= 5; arity++) {
overloads.add(Overload.function(overloadId(function, arity), op));
}
overloads.add(Overload.ternary(overloadId(function, 3), ternaryOp));
overloads.add(Overload.quaternary(overloadId(function, 4), quaternaryOp));
overloads.add(Overload.quinary(overloadId(function, 5), quinaryOp));
overloads.add(Overload.unary(overloadId(function, "list"), op::invoke));
}

Expand All @@ -188,10 +219,87 @@ private static Val greatest(Val... values) {
return minMax(values, true);
}

private static Val greatest(Val first, Val second, Val third) {
return minMax(first, second, third, true);
}

private static Val greatest(Val first, Val second, Val third, Val fourth) {
return minMax(first, second, third, fourth, true);
}

private static Val greatest(Val first, Val second, Val third, Val fourth, Val fifth) {
return minMax(first, second, third, fourth, fifth, true);
}

private static Val least(Val... values) {
return minMax(values, false);
}

private static Val least(Val first, Val second, Val third) {
return minMax(first, second, third, false);
}

private static Val least(Val first, Val second, Val third, Val fourth) {
return minMax(first, second, third, fourth, false);
}

private static Val least(Val first, Val second, Val third, Val fourth, Val fifth) {
return minMax(first, second, third, fourth, fifth, false);
}

private static Val minMax(
Val first, Val second, Val third, Val fourth, Val fifth, boolean greatest) {
Val result = minMax(first, second, third, fourth, greatest);
if (!isNumber(result)) {
return result;
}
if (!isNumber(fifth)) {
return noSuchOverload();
}
int cmp = compareNumbers(fifth, result);
if ((greatest && cmp > 0) || (!greatest && cmp < 0)) {
result = fifth;
}
return result;
}

private static Val minMax(Val first, Val second, Val third, Val fourth, boolean greatest) {
Val result = minMax(first, second, third, greatest);
if (!isNumber(result)) {
return result;
}
if (!isNumber(fourth)) {
return noSuchOverload();
}
int cmp = compareNumbers(fourth, result);
if ((greatest && cmp > 0) || (!greatest && cmp < 0)) {
result = fourth;
}
return result;
}

private static Val minMax(Val first, Val second, Val third, boolean greatest) {
if (!isNumber(first)) {
return noSuchOverload();
}
Val result = first;
if (!isNumber(second)) {
return noSuchOverload();
}
int cmp = compareNumbers(second, result);
if ((greatest && cmp > 0) || (!greatest && cmp < 0)) {
result = second;
}
if (!isNumber(third)) {
return noSuchOverload();
}
cmp = compareNumbers(third, result);
if ((greatest && cmp > 0) || (!greatest && cmp < 0)) {
result = third;
}
return result;
}

private static Val minMax(Val[] values, boolean greatest) {
List<Val> candidates = candidates(values);
if (candidates.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ public List<ProgramOption> getProgramOptions() {
null,
null,
Guards.callInStrStrOutInt(StringsLib::indexOf),
Guards.callInStrStrIntOutIntTernary(StringsLib::indexOfOffset),
values ->
values.length == 3
? Guards.callInStrStrIntOutInt(StringsLib::indexOfOffset).invoke(values)
Expand All @@ -398,6 +399,7 @@ public List<ProgramOption> getProgramOptions() {
null,
null,
Guards.callInStrStrOutInt(StringsLib::lastIndexOf),
Guards.callInStrStrIntOutIntTernary(StringsLib::lastIndexOfOffset),
values ->
values.length == 3
? Guards.callInStrStrIntOutInt(StringsLib::lastIndexOfOffset).invoke(values)
Expand All @@ -408,6 +410,8 @@ public List<ProgramOption> getProgramOptions() {
null,
null,
null,
Guards.callInStrStrStrOutStrTernary(StringsLib::replace),
Guards.callInStrStrStrIntOutStrQuaternary(StringsLib::replaceN),
values -> {
if (values.length == 3) {
return Guards.callInStrStrStrOutStr(StringsLib::replace).invoke(values);
Expand All @@ -423,6 +427,7 @@ public List<ProgramOption> getProgramOptions() {
null,
null,
Guards.callInStrStrOutStrArr(StringsLib::split),
Guards.callInStrStrIntOutStrArrTernary(StringsLib::splitN),
values ->
values.length == 3
? Guards.callInStrStrIntOutStrArr(StringsLib::splitN).invoke(values)
Expand All @@ -432,6 +437,7 @@ public List<ProgramOption> getProgramOptions() {
null,
null,
Guards.callInStrIntOutStr(StringsLib::substr),
Guards.callInStrIntIntOutStrTernary(StringsLib::substrRange),
values ->
values.length == 3
? Guards.callInStrIntIntOutStr(StringsLib::substrRange).invoke(values)
Expand Down
Loading
Loading