# `CEL.Program`
[🔗](https://github.com/hansihe/pb_ex/blob/v0.2.0/cel_ex/lib/cel/program.ex#L1)

A checked CEL expression together with the `CEL.Env` it was checked
against, ready to evaluate any number of times.

    env = CEL.Env.build(vars: [name: :string])

    {:ok, program} = CEL.compile(~s|"hello, " + name|, env)
    CEL.Program.eval(program, %{name: "world"})
    #=> {:ok, {:string, "hello, world"}}

Get one from `CEL.compile/2`, or with `new/2` from a `CEL.Checked` you
already have. Literal regular expressions are compiled once, here.

# `t`

```elixir
@type t() :: %CEL.Program{
  checked: CEL.Checked.t(),
  env: CEL.Env.t(),
  regexes: %{required(CEL.Checked.expr_id()) =&gt; Regex.t()}
}
```

# `eval`

```elixir
@spec eval(t(), map() | keyword()) ::
  {:ok, CEL.Value.t()} | {:unknown, CEL.Unknown.t()} | {:error, CEL.Error.t()}
```

Evaluates a compiled program with the supplied variable bindings.

# `eval!`

```elixir
@spec eval!(t(), map() | keyword()) :: CEL.Value.t()
```

Evaluates a compiled program, raising on errors and unknown results.

# `new`

```elixir
@spec new(CEL.Checked.t(), CEL.Env.t()) :: t()
```

Bundles a previously checked expression with the environment it was checked
against, returning a `Program` ready for `eval/2`.

Most callers should use `CEL.compile/2`, which parses, checks, and
bundles in one call. Use this constructor when you already hold a
`CEL.Checked` and the matching `CEL.Env` — for example, to
cache the check phase and re-bundle programs with different runtime
bindings.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
