pub fn compile_expr<F>(
expr: &Expr,
lookup: &OpLookup,
types: &dyn TypeResolver,
resolve: &mut F,
) -> Result<DynSegment>Expand description
Compiles retained syntax into an independently owned executable segment.
Borrows lookup and types only during compilation. resolve emits an external
identifier and returns true, or leaves the segment unchanged and returns false
to continue normal lookup. An emitted value must carry its complete runtime
descriptor, including tuple, array, record, or callable shape.
resolve must provide segment-local mutable execution owners for each compilation.
Intentionally shared host input state and immutable definitions may remain shared.
The compiler does not enforce freshness of captured execution resources.
Noncapturing closure bodies resolve only their own formals and persistent library
names; they cannot consult resolve or transient lookup scopes. Each compilation
creates fresh branch and closure execution resources. Neither syntax nor environments
need to outlive the returned segment.
§Errors
Returns a spanned error for unresolved names, duplicate/reserved parameters, incompatible operands, invalid annotations, or external emitter failures. Partially emitted resources remain safely discardable.
- Complexity: O(n) traversal time and space, plus type resolution, linear formal-name lookup and operation dispatch costs for the n syntax nodes.
§Examples
use cel_parser::{AstContext, OpLookup, Parser, builtin_type_resolver, compile_expr};
let expr = Parser::<AstContext>::new(OpLookup::new())
.parse_str_ast("false && (1i32 / 0i32 == 0i32)").unwrap();
let types = builtin_type_resolver();
let mut segment = compile_expr(&expr, &OpLookup::new(), types.as_ref(),
&mut |_, _, _| Ok(false)).unwrap();
drop(expr);
assert!(!segment.call0::<bool>().unwrap());