Skip to main content

compile_expr

Function compile_expr 

Source
pub fn compile_expr<F>(
    expr: &Expr,
    lookup: &OpLookup,
    types: &dyn TypeResolver,
    resolve: &mut F,
) -> Result<DynSegment>
where F: FnMut(&str, &mut DynSegment, SourceSpan) -> Result<bool>,
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());