Search in sources :

Example 1 with Macro

use of org.projectnessie.cel.parser.Macro in project cel-java by projectnessie.

the class CELTest method CustomMacro.

@Test
void CustomMacro() {
    Macro joinMacro = newReceiverMacro("join", 1, (eh, target, args) -> {
        Expr delim = args.get(0);
        Expr iterIdent = eh.ident("__iter__");
        Expr accuIdent = eh.ident("__result__");
        Expr init = eh.literalString("");
        Expr condition = eh.literalBool(true);
        Expr step = eh.globalCall(Operator.Conditional.id, eh.globalCall(Operator.Greater.id, eh.receiverCall("size", accuIdent, emptyList()), eh.literalInt(0)), eh.globalCall(Operator.Add.id, eh.globalCall(Operator.Add.id, accuIdent, delim), iterIdent), iterIdent);
        return eh.fold("__iter__", target, "__result__", init, condition, step, accuIdent);
    });
    Env e = newEnv(macros(joinMacro));
    AstIssuesTuple astIss = e.compile("['hello', 'cel', 'friend'].join(',')");
    assertThat(astIss.hasIssues()).isFalse();
    Program prg = e.program(astIss.getAst(), evalOptions(OptExhaustiveEval));
    EvalResult out = prg.eval(noVars());
    assertThat(out.getVal().equal(stringOf("hello,cel,friend"))).isSameAs(True);
}
Also used : ParsedExpr(com.google.api.expr.v1alpha1.ParsedExpr) Expr(com.google.api.expr.v1alpha1.Expr) CEL.astToCheckedExpr(org.projectnessie.cel.CEL.astToCheckedExpr) CheckedExpr(com.google.api.expr.v1alpha1.CheckedExpr) CEL.astToParsedExpr(org.projectnessie.cel.CEL.astToParsedExpr) EvalResult(org.projectnessie.cel.Program.EvalResult) Macro(org.projectnessie.cel.parser.Macro) Macro.newReceiverMacro(org.projectnessie.cel.parser.Macro.newReceiverMacro) Env.newEnv(org.projectnessie.cel.Env.newEnv) Env.newCustomEnv(org.projectnessie.cel.Env.newCustomEnv) AstIssuesTuple(org.projectnessie.cel.Env.AstIssuesTuple) Test(org.junit.jupiter.api.Test)

Example 2 with Macro

use of org.projectnessie.cel.parser.Macro in project cel-java by projectnessie.

the class CheckerEnv method addOverload.

/**
 * addOverload adds overload to function declaration f. Returns one or more errorMsg values if the
 * overload overlaps with an existing overload or macro.
 */
Decl addOverload(Decl f, Overload overload, List<String> errMsgs) {
    FunctionDecl function = f.getFunction();
    Mapping emptyMappings = newMapping();
    Type overloadFunction = Decls.newFunctionType(overload.getResultType(), overload.getParamsList());
    Type overloadErased = substitute(emptyMappings, overloadFunction, true);
    boolean hasErr = false;
    for (Overload existing : function.getOverloadsList()) {
        Type existingFunction = Decls.newFunctionType(existing.getResultType(), existing.getParamsList());
        Type existingErased = substitute(emptyMappings, existingFunction, true);
        boolean overlap = isAssignable(emptyMappings, overloadErased, existingErased) != null || isAssignable(emptyMappings, existingErased, overloadErased) != null;
        if (overlap && overload.getIsInstanceFunction() == existing.getIsInstanceFunction()) {
            errMsgs.add(overlappingOverloadError(f.getName(), overload.getOverloadId(), overloadFunction, existing.getOverloadId(), existingFunction));
            hasErr = true;
        }
    }
    for (Macro macro : Macro.AllMacros) {
        if (macro.function().equals(f.getName()) && macro.isReceiverStyle() == overload.getIsInstanceFunction() && macro.argCount() == overload.getParamsCount()) {
            errMsgs.add(overlappingMacroError(f.getName(), macro.argCount()));
            hasErr = true;
        }
    }
    if (hasErr) {
        return f;
    }
    function = function.toBuilder().addOverloads(overload).build();
    f = f.toBuilder().setFunction(function).build();
    return f;
}
Also used : Types.formatCheckedType(org.projectnessie.cel.checker.Types.formatCheckedType) Type(com.google.api.expr.v1alpha1.Type) ErrType(org.projectnessie.cel.common.types.Err.ErrType) Overload(com.google.api.expr.v1alpha1.Decl.FunctionDecl.Overload) Macro(org.projectnessie.cel.parser.Macro) Mapping.newMapping(org.projectnessie.cel.checker.Mapping.newMapping) FunctionDecl(com.google.api.expr.v1alpha1.Decl.FunctionDecl)

Example 3 with Macro

use of org.projectnessie.cel.parser.Macro in project cel-java by projectnessie.

the class Env method extend.

/**
 * Extend the current environment with additional options to produce a new Env.
 *
 * <p>Note, the extended Env value should not share memory with the original. It is possible,
 * however, that a CustomTypeAdapter or CustomTypeProvider options could provide values which are
 * mutable. To ensure separation of state between extended environments either make sure the
 * TypeAdapter and TypeProvider are immutable, or that their underlying implementations are based
 * on the ref.TypeRegistry which provides a Copy method which will be invoked by this method.
 */
public Env extend(List<EnvOption> opts) {
    if (chkErr != null) {
        throw chkErr;
    }
    // Copy slices.
    List<Decl> decsCopy = new ArrayList<>(declarations);
    List<Macro> macsCopy = new ArrayList<>(macros);
    List<ProgramOption> progOptsCopy = new ArrayList<>(progOpts);
    // Copy the adapter / provider if they appear to be mutable.
    TypeAdapter adapter = this.adapter;
    TypeProvider provider = this.provider;
    // TypeRegistry as the base implementation are captured below.
    if (this.adapter instanceof TypeRegistry && this.provider instanceof TypeRegistry) {
        TypeRegistry adapterReg = (TypeRegistry) this.adapter;
        TypeRegistry providerReg = (TypeRegistry) this.provider;
        TypeRegistry reg = providerReg.copy();
        provider = reg;
        // to the same ref.TypeRegistry as the provider.
        if (adapterReg.equals(providerReg)) {
            adapter = reg;
        } else {
            // Otherwise, make a copy of the adapter.
            adapter = adapterReg.copy();
        }
    } else if (this.provider instanceof TypeRegistry) {
        provider = ((TypeRegistry) this.provider).copy();
    } else if (this.adapter instanceof TypeRegistry) {
        adapter = ((TypeRegistry) this.adapter).copy();
    }
    Set<EnvFeature> featuresCopy = EnumSet.copyOf(this.features);
    Env ext = new Env(this.container, decsCopy, macsCopy, adapter, provider, featuresCopy, progOptsCopy);
    return ext.configure(opts);
}
Also used : Macro(org.projectnessie.cel.parser.Macro) ArrayList(java.util.ArrayList) TypeProvider(org.projectnessie.cel.common.types.ref.TypeProvider) Decl(com.google.api.expr.v1alpha1.Decl) CheckerEnv(org.projectnessie.cel.checker.CheckerEnv) TypeRegistry(org.projectnessie.cel.common.types.ref.TypeRegistry) EnvFeature(org.projectnessie.cel.EnvOption.EnvFeature) TypeAdapter(org.projectnessie.cel.common.types.ref.TypeAdapter)

Aggregations

Macro (org.projectnessie.cel.parser.Macro)3 CheckedExpr (com.google.api.expr.v1alpha1.CheckedExpr)1 Decl (com.google.api.expr.v1alpha1.Decl)1 FunctionDecl (com.google.api.expr.v1alpha1.Decl.FunctionDecl)1 Overload (com.google.api.expr.v1alpha1.Decl.FunctionDecl.Overload)1 Expr (com.google.api.expr.v1alpha1.Expr)1 ParsedExpr (com.google.api.expr.v1alpha1.ParsedExpr)1 Type (com.google.api.expr.v1alpha1.Type)1 ArrayList (java.util.ArrayList)1 Test (org.junit.jupiter.api.Test)1 CEL.astToCheckedExpr (org.projectnessie.cel.CEL.astToCheckedExpr)1 CEL.astToParsedExpr (org.projectnessie.cel.CEL.astToParsedExpr)1 AstIssuesTuple (org.projectnessie.cel.Env.AstIssuesTuple)1 Env.newCustomEnv (org.projectnessie.cel.Env.newCustomEnv)1 Env.newEnv (org.projectnessie.cel.Env.newEnv)1 EnvFeature (org.projectnessie.cel.EnvOption.EnvFeature)1 EvalResult (org.projectnessie.cel.Program.EvalResult)1 CheckerEnv (org.projectnessie.cel.checker.CheckerEnv)1 Mapping.newMapping (org.projectnessie.cel.checker.Mapping.newMapping)1 Types.formatCheckedType (org.projectnessie.cel.checker.Types.formatCheckedType)1