mod optimize;
pub(crate) mod hooks;
mod missing;
mod operator;
mod path_segments;
pub(crate) mod scope;
mod walker;
pub(crate) use path_segments::parse_path_segments;
use datavalue::OwnedDataValue;
use crate::node::{CompileCtx, Logic};
use crate::{Engine, Result};
impl Logic {
pub(crate) fn compile_with(logic: &OwnedDataValue, engine: &Engine) -> Result<Self> {
Self::compile_in_mode(logic, engine, engine.is_templating_enabled())
}
pub(crate) fn compile_in_mode(
logic: &OwnedDataValue,
engine: &Engine,
templating: bool,
) -> Result<Self> {
let ctx = if engine.constant_folding_enabled() {
CompileCtx::new()
} else {
CompileCtx::no_fold()
};
Self::compile_inner(logic, engine, templating, ctx)
}
#[cfg(feature = "trace")]
pub(crate) fn compile_for_trace(
logic: &OwnedDataValue,
engine: &Engine,
templating: bool,
place: bool,
) -> Result<Self> {
let ctx = CompileCtx::no_fold();
let ctx = if place { ctx.recording_pointers() } else { ctx };
Self::compile_inner(logic, engine, templating, ctx)
}
#[inline]
fn compile_inner(
logic_src: &OwnedDataValue,
engine: &Engine,
templating: bool,
mut ctx: CompileCtx,
) -> Result<Self> {
let mut root = walker::compile_node(logic_src, engine, templating, &mut ctx)?;
let cse_slot_count = if ctx.skip_fold()
|| matches!(
engine.config().truthy_evaluator,
crate::TruthyEvaluator::Custom(_)
) {
0
} else {
optimize::cse::apply(&mut root)
};
let needs_ancestor_frames = scope::resolve(&mut root);
let mut logic = Self::new(root, cse_slot_count, needs_ancestor_frames);
logic.engine_id = engine.id();
logic.pointers = ctx.take_pointers();
if ctx.has_config_folds() {
logic.refold = Some(Box::new(crate::node::Refold::new(
logic_src.clone(),
templating,
engine.fold_fingerprint(),
)));
}
Ok(logic)
}
}