Struct ParseSlab

Source
pub struct ParseSlab { /* private fields */ }
Expand description

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

§Unsafe Variable Registration with add_unsafe_var()

(This is documented here because the add_unsafe_var() method and its documentation only appears if fasteval is built with the unsafe-vars feature (cargo build --features unsafe-vars). I want this documentation to appear regardless of the build mode, so I’m putting it here.)

Here is the function signature of the add_unsafe_var() method:

pub unsafe fn add_unsafe_var(&mut self, name: String, ptr: &f64)

If you are using Unsafe Variables, you need to pre-register the unsafe variable names and pointers before calling parse(). This is because Unsafe Variables are represented specially in the parse AST; therefore, parse() needs to know what variables are unsafe and which ones are normal so that it can produce the correct AST.

If you forget to pre-register an unsafe variable before parse(), the variable will be treated like a Normal Variable, and you’ll probably get an Undefined error during evaluation.

§Safety

You must guarantee that Unsafe Variable pointers remain valid for the lifetime of the resulting expression. If you continue to use an expression after the memory of an unsafe variable has been reclaimed, you will have undefined behavior.

§Examples

Here is an example of correct and incorrect use of unsafe variable pointers:

use fasteval::Evaler;    // use this trait so we can call eval().
use fasteval::Compiler;  // use this trait so we can call compile().

// Here is an example of INCORRECT registration.  DO NOT DO THIS!
fn bad_unsafe_var(slab_mut:&mut fasteval::Slab) {
    let bad : f64 = 0.0;

    // Saves a pointer to 'bad':
    unsafe { slab_mut.ps.add_unsafe_var("bad".to_string(), &bad); }  // `add_unsafe_var()` only exists if the `unsafe-vars` feature is enabled: `cargo test --features unsafe-vars`

    // 'bad' goes out-of-scope here, and the pointer we registered is no longer valid!
    // This will result in undefined behavior.
}

fn main() -> Result<(), fasteval::Error> {
    let mut slab = fasteval::Slab::new();

    // The Unsafe Variable will use a pointer to read this memory location:
    // You must make sure that this variable stays in-scope as long as the
    // expression is in-use.
    let mut deg : f64 = 0.0;

    // Unsafe Variables must be registered before 'parse()'.
    // (Normal Variables only need definitions during the 'eval' phase.)
    unsafe { slab.ps.add_unsafe_var("deg".to_string(), &deg); }  // `add_unsafe_var()` only exists if the `unsafe-vars` feature is enabled: `cargo test --features unsafe-vars`

    // bad_unsafe_var(&mut slab);  // Don't do it this way.

    let expr_str = "sin(deg/360 * 2*pi())";
    let expr_ref = fasteval::Parser::new().parse(expr_str, &mut slab.ps)?.from(&slab.ps);

    // The main reason people use Unsafe Variables is to maximize performance.
    // Compilation also helps performance, so it is usually used together with Unsafe Variables:
    let compiled = expr_ref.compile(&slab.ps, &mut slab.cs);

    let mut ns = fasteval::EmptyNamespace;  // We only define unsafe variables, not normal variables,
                                            // so EmptyNamespace is fine.

    for d in 0..360 {
        deg = d as f64;
        let val = fasteval::eval_compiled!(compiled, &slab, &mut ns);
        eprintln!("sin({}°) = {}", deg, val);
    }

    Ok(())
}
 

Implementations§

Source§

impl ParseSlab

Source

pub fn get_expr(&self, expr_i: ExpressionI) -> &Expression

Returns a reference to the Expression located at expr_i within the `ParseSlab.exprs’.

If expr_i is out-of-bounds, a reference to a default Expression is returned.

Source

pub fn get_val(&self, val_i: ValueI) -> &Value

Returns a reference to the Value located at val_i within the `ParseSlab.vals’.

If val_i is out-of-bounds, a reference to a default Value is returned.

Source

pub fn clear(&mut self)

Clears all data from ParseSlab.exprs and ParseSlab.vals.

Trait Implementations§

Source§

impl Debug for ParseSlab

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.