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