Expand description
This Rust crate provides a simple math expression parsing and evaluation. Its main goal is to
be convenient to use, while allowing for some flexibility. Currently works only with f64
types. A typical use case is the configuration of numerical computations in
Rust, think initial data and boundary conditions, via config files or command line arguments.
§Documentation
§Installation
Simply add the corresponding entry to your Cargo.toml
dependency list:
[dependencies]
meval = "0.2"
and add this to your crate root:
extern crate meval;
Requires Rust 1.26.
§Simple examples
extern crate meval;
fn main() {
let r = meval::eval_str("1 + 2").unwrap();
println!("1 + 2 = {}", r);
}
Need to define a Rust function from an expression? No problem, use Expr
for this and more:
extern crate meval;
fn main() {
let expr: meval::Expr = "sin(pi * x)".parse().unwrap();
let func = expr.bind("x").unwrap();
let vs: Vec<_> = (0..100+1).map(|i| func(i as f64 / 100.)).collect();
println!("sin(pi * x), 0 <= x <= 1: {:?}", vs);
}
Custom constants and functions? Define a Context
!
use meval::{Expr, Context};
let y = 1.;
let expr: Expr = "phi(-2 * zeta + x)".parse().unwrap();
// create a context with function definitions and variables
let mut ctx = Context::new(); // built-ins
ctx.func("phi", |x| x + y)
.var("zeta", -1.);
// bind function with a custom context
let func = expr.bind_with_context(ctx, "x").unwrap();
assert_eq!(func(2.), -2. * -1. + 2. + 1.);
For functions of 2, 3, and N variables use Context::func2
, Context::func3
and
Context::funcn
,
respectively. See Context
for more options.
If you need a custom function depending on mutable parameters, you will need to use a
Cell
:
use std::cell::Cell;
use meval::{Expr, Context};
let y = Cell::new(0.);
let expr: Expr = "phi(x)".parse().unwrap();
let mut ctx = Context::empty(); // no built-ins
ctx.func("phi", |x| x + y.get());
let func = expr.bind_with_context(ctx, "x").unwrap();
assert_eq!(func(2.), 2.);
y.set(3.);
assert_eq!(func(2.), 5.);
§Supported expressions
meval
supports basic mathematical operations on floating point numbers:
- binary operators:
+
,-
,*
,/
,%
(remainder),^
(power) - unary operators:
+
,-
It supports custom variables and functions like x
, weight
, C_0
, f(1)
, etc. A variable
or function name must start with [a-zA-Z_]
and can contain only [a-zA-Z0-9_]
. Custom
functions with a variable number of arguments are also supported.
Build-ins (given by the context Context::new()
and when no context provided) currently
supported:
-
functions implemented using functions of the same name in Rust std library:
sqrt
,abs
exp
,ln
sin
,cos
,tan
,asin
,acos
,atan
,atan2
sinh
,cosh
,tanh
,asinh
,acosh
,atanh
floor
,ceil
,round
signum
-
other functions:
max(x, ...)
,min(x, ...)
: maximum and minimumum of 1 or more numbers
-
constants:
pi
e
§Deserialization
Expr
supports deserialization using the serde library to make flexible
configuration easy to set up, if the feature serde
is enabled (disable by default).
#[macro_use]
extern crate serde_derive;
extern crate toml;
extern crate meval;
use meval::{Expr, Context};
#[derive(Deserialize)]
struct Ode {
#[serde(deserialize_with = "meval::de::as_f64")]
x0: f64,
#[serde(deserialize_with = "meval::de::as_f64")]
t0: f64,
f: Expr,
g: Expr,
}
fn main() {
let config = r#"
x0 = "cos(1.)"
t0 = 2
f = "sin(x)"
g = 2.5
"#;
let ode: Ode = toml::from_str(config).unwrap();
assert_eq!(ode.x0, 1f64.cos());
assert_eq!(ode.t0, 2f64);
assert_eq!(ode.f.bind("x").unwrap()(2.), 2f64.sin());
assert_eq!(ode.g.eval().unwrap(), 2.5f64);
}
§Related projects
This is a toy project of mine for learning Rust, and to be hopefully useful when writing command line scripts. There is no plan to make this anything more than math expression -> number “converter”. For more advanced scripting, see:
- dyon – A rusty dynamically typed scripting language
- gluon – A static, type inferred programming language for application embedding
- rodolf0/tox – another shunting yard expression parser
Re-exports§
pub use shunting_yard::RPNError;
pub use tokenizer::ParseError;
Modules§
- de
- Deserialization utilities.
- shunting_
yard - Implementation of the shunting-yard algorithm for converting an infix expression to an expression in reverse Polish notation (RPN).
- tokenizer
- Tokenizer that converts a mathematical expression in a string form into a series of
Token
s.
Structs§
- Context
- A structure for storing variables/constants and functions to be used in an expression.
- Expr
- Representation of a parsed expression.
Enums§
- Error
- An error produced during parsing or evaluation.
- Func
Eval Error - Function evaluation error.
Traits§
- ArgGuard
- Trait for types that can specify the number of required arguments for a function with a variable number of arguments.
- Context
Provider - A trait of a source of variables (and constants) and functions for substitution into an evaluated expression.
Functions§
- eval_
str - Evaluates a string with built-in constants and functions.
- eval_
str_ with_ context - Evaluates a string with the given context.