mathexpr 0.1.1

A fast, safe mathematical expression parser and evaluator with bytecode compilation
Documentation
//! # mathexpr
//!
//! A fast, safe mathematical expression parser and evaluator with bytecode compilation.
//!
//! ## Features
//!
//! - **Fast**: Compiles to bytecode for efficient repeated evaluation (~15-80ns per eval)
//! - **Safe**: No unsafe code, handles errors gracefully
//! - **`no_std` compatible**: Works in embedded environments with `alloc`
//! - **Rich function library**: 27 built-in functions including trig, rounding, and more
//!
//! ## Quick Start
//!
//! ```rust
//! use mathexpr::Expression;
//!
//! // Parse and compile an expression
//! let expr = Expression::parse("sqrt(x^2 + y^2)")?
//!     .compile(&["x", "y"])?;
//!
//! // Evaluate with different values
//! assert_eq!(expr.eval(&[3.0, 4.0])?, 5.0);
//! assert_eq!(expr.eval(&[5.0, 12.0])?, 13.0);
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! ## One-liner Evaluation
//!
//! For simple cases where you don't need to reuse the expression:
//!
//! ```rust
//! use mathexpr::eval;
//!
//! let result = eval("2 * pi * r", &["r"], &[5.0])?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! ## Current Value (`_`)
//!
//! Use `_` to reference an input value, useful for transformations:
//!
//! ```rust
//! use mathexpr::Expression;
//!
//! let normalize = Expression::parse("(_ - min) / (max - min)")?
//!     .compile(&["min", "max"])?;
//!
//! // Normalize 50 to range [0, 100]
//! let result = normalize.eval_with_current(50.0, &[0.0, 100.0])?;
//! assert_eq!(result, 0.5);
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! ## Supported Operators
//!
//! | Operator | Description | Precedence |
//! |----------|-------------|------------|
//! | `+`, `-` | Addition, Subtraction | Lowest |
//! | `*`, `/`, `%` | Multiplication, Division, Modulo | Medium |
//! | `^` | Exponentiation (right-associative) | Highest |
//! | `-x` | Unary negation | Highest |
//!
//! ## Supported Functions
//!
//! ### Core Math
//! - `abs(x)`, `sqrt(x)`, `cbrt(x)` - Absolute value, roots
//! - `log(x)`/`ln(x)`, `log2(x)`, `log10(x)` - Logarithms
//! - `exp(x)`, `pow(base, exp)` - Exponentials
//! - `min(a, b)`, `max(a, b)`, `clamp(x, min, max)` - Bounds
//! - `mod(a, b)` - Modulo (same as `%`)
//!
//! ### Trigonometric
//! - `sin(x)`, `cos(x)`, `tan(x)` - Basic trig
//! - `asin(x)`, `acos(x)`, `atan(x)` - Inverse trig
//! - `sinh(x)`, `cosh(x)`, `tanh(x)` - Hyperbolic
//!
//! ### Rounding
//! - `floor(x)`, `ceil(x)`, `round(x)`, `trunc(x)`
//! - `signum(x)` - Sign of number
//!
//! ### Constants
//! - `pi` or `pi()` - π ≈ 3.14159...
//! - `e` or `e()` - Euler's number ≈ 2.71828...
//!
//! ## Performance
//!
//! Typical evaluation times (single-threaded, release build):
//!
//! | Expression Complexity | Time per Eval |
//! |-----------------------|---------------|
//! | Simple (`a + b`) | ~15 ns |
//! | Medium (`sqrt(x^2 + y^2)`) | ~35 ns |
//! | Complex (5+ functions) | ~70-80 ns |
//!
//! ## Feature Flags
//!
//! - `std` (default): Enables `std::error::Error` implementations
//! - Without `std`: Requires `alloc` crate, suitable for `no_std` environments

#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![warn(missing_docs)]
#![warn(rust_2018_idioms)]

#[cfg(not(feature = "std"))]
extern crate alloc;

pub mod ast;
pub mod builder;
pub mod compiler;
pub mod error;
pub mod parser;
pub mod vm;

// Re-export main types at crate root for convenience
pub use ast::{BinOp, BuiltinFn, Expr};
pub use builder::{eval, eval_with_current, Executable, Expression};
pub use compiler::CompiledExpr;
pub use error::{CompileError, EvalError, ParseError};
pub use parser::parse;

#[cfg(test)]
mod tests;