### 3 unstable releases

0.2.1 | Jan 28, 2020 |
---|---|

0.2.0 | Jan 28, 2020 |

0.1.0 | Aug 12, 2019 |

#**1502** in Math

**37** downloads per month

**MIT**license

54KB

954 lines

# Cruncher

This library takes a string such as

and allows you to pass in a dictionary with values defined for each variable used and get the result.`"`x + 2 / 3 * ( z ^ 4 )`"`

Right now the tests do the best job of providing examples of how to interact with the library.

It is a work in progress but the main functionality is there. The lexer/parser needs to be improved as it is sensitive to spacing.

###
`lib.rs`

:

Cruncher, a crate for dynamic evaluation of mathematical expressions.

This crate provide run-time evaluation of mathematical expressions,
embedded in strings. The easiest way to use this crate is with the

function:`eval`

`assert_eq!``(``cruncher``::`eval`(``"`3 + 5 * 2`"``,` `None``)``,` `Ok``(``13.``0``)``)``;`

The second argument to

is a `eval`

, that
can define variables:`HashMap`

`use` `hashbrown``::`HashMap`;`
`let` `mut` context `:``HashMap``<``String`,`f64``>` `=` `HashMap``::`new`(``)``;`
context`.``insert``(``"`a`"``.``into``(``)``,` `3.``5``)``;`
`assert_eq!``(``cruncher``::`eval`(``"`2 * a`"``,` `&`context`)``,` `Ok``(``7.``0``)``)``;`

It is also possible to separate the parsing from the evaluation of an
expression with the

type. This allow to reuse
the same expression with different values for variables.`Expr`

`use` `hashbrown``::`HashMap`;`
`use` `cruncher``::``{`Expr`}``;`
`let` expr `=` `Expr``::`parse`(``"`3 + 5 * 2`"``)``.``unwrap``(``)``;`
`assert_eq!``(`expr`.``eval``(``None``)``,` `Ok``(``13.``0``)``)``;`
`let` expr `=` `Expr``::`parse`(``"`3 / c + b`"``)``.``unwrap``(``)``;`
`let` `mut` context `:``HashMap``<``String`,`f64``>` `=` `HashMap``::`new`(``)``;`
context`.``insert``(``"`c`"``.``into``(``)``,` `1.``0``)``;`
context`.``insert``(``"`b`"``.``into``(``)``,` `5.``0``)``;`
`assert_eq!``(`expr`.``eval``(``&`context`)``,` `Ok``(``8.``0``)``)``;`
context`.``insert``(``"`b`"``.``into``(``)``,` `10.``0``)``;`
`assert_eq!``(`expr`.``eval``(``&`context`)``,` `Ok``(``13.``0``)``)``;`

# Language definition

The language implemented by cruncher can contain the following elements:

- float literal values:

,`-``12.``456`

, ...;`+``0.``0045e78` - left and right parenthesis;
- mathematical operators:

for addition,`+`

for subtraction,`-`

for multiplication,`*`

for division and`/`

for exponentiation (`^`

);`std``::``f64`powf`::` - variables. Variables names are ASCII only, and can start by a letter or

, and can contain letters, digits,`_`

,`.`

,`_`

or`[`

.`]` - function call:

,`sin``(`a`)`

. The following function are accessible, with the same meaning as the corresponding`atan``(``22.``0``)`

function:`std`f64`::`

,`sqrt`

,`cbrt`

,`sin`

,`cos`

,`tan`

,`asin`

,`acos`

,`atan`

,`sinh`

,`cosh`

,`tanh`

,`asinh`

,`acosh`

,`atanh`

,`floor`

,`ceil`

,`abs`

,`exp`

,`ln`

,`log2`

.`log10`

Any other symbol is forbidden in the input.

The mathematical operators obey the usual relations of associativity and
precedence, but still carry the floating point properties: addition is not
commutative,

and infinities exist, ...`NaN`

# Technical details

cruncher is based on an AST interpreter, and uses a simple Shuntting-Yard
algorithm for parsing the expressions. It works only with

data, and
perform a simple constant propagation to optimize the expressions.`f64`

#### Dependencies

~8MB

~175K SLoC