pub fn parse_scope<R>(
parser: &Tabnas,
src: &str,
use_value: impl FnOnce(Value) -> R,
) -> Result<R, TabnasError>Expand description
Parse one document and hand the unrealized value to a closure, with the expression arena held open for as long as it runs.
This is the parse-once, evaluate-many workflow: inside the closure the
expression nodes are live, so evaluation can reduce them, and
whatever the closure returns outlives them.
The arena is released when this returns, so the closure must not let an
expression HANDLE escape in what it returns. Return a reduced value, as
the example below does, or call realize on the tree and return
that; parse_with is the same parse with the realizing already done.
A handle that escapes names a node that no longer exists, and
realize and simplify then PANIC rather than report the lost
expression as an empty array. The closure return type is a type
parameter, so nothing in the signature can realize it for a caller, and
nothing in it can stop a handle from being returned.
use tabnas::Value;
use tabnas_expr::{evaluation, EvalSite, Evaluate, Op};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let parser = tabnas_expr::make();
let add: Evaluate = std::sync::Arc::new(
|_site: &mut EvalSite<'_>, _op: &Op, terms: &[Value]| match terms {
[Value::Number(left), Value::Number(right)] => Value::Number(left + right),
_ => Value::Null,
},
);
let total = tabnas_expr::parse_scope(&parser, "1+2", |value| {
evaluation(&mut EvalSite::detached(), &value, &add)
})?;
assert_eq!(total, Value::Number(3.0));
Ok(())
}