ripin/
lib.rs

1//! This library provide a way to evaluate [`Reverse Polish Notated`] expressions for
2//! numbers and basic evaluators.
3//!
4//! [`Floats`] and [`signed integers`] has already been implemented with basic evaluators
5//! (cf. `+`, `-`, `*`, `/`, `neg`, `pow`...).
6//!
7//! Of course you can build your own Evaluators by implementing the [`Evaluate`] Trait,
8//! the only constraint is the compatibility with the [`Operand`] type,
9//! that can be everything you want (cf. `letters`, `Enums`, `chinese symbols`...).
10//!
11//! # Expression Usage
12//!
13//! Let's define an expression:
14//!
15//! ```rust
16//! let expr = "3 4 + 2 *"; // (3 + 4) * 2
17//! ```
18//!
19//! Tokenize it:
20//!
21//! ```rust
22//! # let expr = "3 4 + 2 *";
23//! let tokens = expr.split_whitespace();
24//! ```
25//!
26//! Ripin can evaluate `floating-point` expressions:
27//!
28//! ```rust
29//! # let expr = "3 4 + 2 *";
30//! # let tokens = expr.split_whitespace();
31//! use ripin::evaluate::FloatExpr;
32//!
33//! let expr = FloatExpr::<f32>::from_iter(tokens).unwrap();
34//! assert_eq!(expr.evaluate(), Ok(14.0));
35//! ```
36//!
37//! like `integers` ones:
38//!
39//! ```rust
40//! # let expr = "3 4 + 2 *";
41//! # let tokens = expr.split_whitespace();
42//! use ripin::evaluate::IntExpr;
43//!
44//! let expr = IntExpr::<i32>::from_iter(tokens).unwrap();
45//! assert_eq!(expr.evaluate(), Ok(14));
46//! ```
47//!
48//! # Variable Expression Usage
49//!
50//! You need variable expressions ?
51//! No problem Ripin can do this too !
52//!
53//! Declare some variables:
54//!
55//! ```rust
56//! let variables = vec![3.0, 500.0];
57//! ```
58//!
59//! Once variables as been set, do the same as before:
60//!
61//! ```rust
62//! # let variables = vec![3.0, 500.0];
63//! use ripin::evaluate::VariableFloatExpr;
64//! use ripin::variable::IndexVar;
65//!
66//! let expr = "3 4 + 2 * $0 -"; // (3 + 4) * 2 - $0
67//!
68//! let tokens = expr.split_whitespace();
69//! let expr = VariableFloatExpr::<f32, IndexVar>::from_iter(tokens).unwrap();
70//! ```
71//!
72//! Evaluate the expression with informations about the way of indexation (`usize`):
73//!
74//! ```rust
75//! # let variables = vec![3.0, 500.0];
76//! # use ripin::evaluate::VariableFloatExpr;
77//! # use ripin::variable::IndexVar;
78//! # let expr = "3 4 + 2 * $0 -"; // (3 + 4) * 2 - $0
79//! # let tokens = expr.split_whitespace();
80//! # let expr = VariableFloatExpr::<f32, IndexVar>::from_iter(tokens).unwrap();
81//! assert_eq!(expr.evaluate_with_variables(&variables), Ok(11.0));
82//! ```
83//!
84//! [`Reverse Polish Notated`]: https://en.wikipedia.org/wiki/Reverse_Polish_notation
85//! [`str`]: https://doc.rust-lang.org/std/str/index.html
86//! [`Floats`]: evaluate/enum.FloatEvaluator.html
87//! [`signed integers`]: evaluate/enum.IntEvaluator.html
88//! [`Evaluate`]: evaluate/trait.Evaluate.html
89//! [`Operand`]: expression/enum.Arithm.html
90
91extern crate num;
92
93mod stack;
94
95/// TryFrom/Into_ref conversion module
96pub mod convert_ref;
97
98/// Operation on expressions and `Expression` construction methods.
99pub mod expression;
100
101/// Useful structs to use variables with expressions
102pub mod variable;
103
104/// `Evaluate Trait` and default `Evaluators`.
105pub mod evaluate;
106
107pub use stack::Stack;
108
109/// Removes the last two elements from a stack and return them,
110/// or `None` if there is not enough element.
111pub fn pop_two_operands<T>(stack: &mut Stack<T>) -> Option<(T, T)> {
112    if stack.len() >= 2 {
113        let (a, b) = (stack.pop().unwrap(), stack.pop().unwrap());
114        Some((b, a))
115    } else {
116        None
117    }
118}