[][src]Module fasteval::slab

A Slab is a pre-allocated block of memory, used during the parse/compile/eval phases to reduce memory allocation/deallocation.

A Slab enables you to perform one single, large allocation at the beginning of the parse-compile-eval process, rather than many small allocations. You can also re-use a Slab for multiple expression parse-compile-eval cycles, greatly reducing the amount of memory operations. The Slab is the main key to fasteval's excellent performance.

You use ExpressionI, ValueI, and InstructionI index types to refer to elements within the Slab. These special index types are necessary to side-step the Rust borrow checker, which is not able to understand borrow-splitting of contiguous allocations (like arrays). (In other words, these special index types allows fasteval to mutate a Slab while simultaneously holding references to its contents.)

You usually won't use any of the Slab method directly. Instead, you'll just pass a reference to other functions like parse(), compile() and eval(). We treat a Slab sort of like a Context in other programming systems.

The Slab contains two fields: ps ("Parse Slab") and cs ("Compile Slab"). It is structured like this because of Rust's borrowing rules, so that the two fields can be borrowed and mutated independently.

If you use the ez_eval() function, it allocates a Slab for you. If you are performing the parse/compile/eval process yourself, then you'll need to allocate a Slab at the beginning.


Here is an example of re-using one Slab for multiple parse/eval cycles:

use fasteval::Evaler;  // import this trait so we can call eval().
fn main() -> Result<(), fasteval::Error> {
    let parser = fasteval::Parser::new();
    let mut slab = fasteval::Slab::new();

    let val = parser.parse("1+2*3-4", &mut slab.ps)?.from(&slab.ps).eval(&slab, &mut fasteval::EmptyNamespace)?;
    assert_eq!(val, 3.0);

    // Let's re-use the same slab again to save memory operations.

    // `parse()` will clear the Slab's data.  It is important that you
    // do not use an old expression after the Slab has been cleared.
    let val = parser.parse("5+6*7-8", &mut slab.ps)?.from(&slab.ps).eval(&slab, &mut fasteval::EmptyNamespace)?;
    assert_eq!(val, 39.0);




CompileSlab is where compile() results are stored, located at Slab.cs.


ParseSlab is where parse() results are stored, located at Slab.ps.


See the slab module documentation.