calc_rational

CLI calculator for rational numbers.
git clone https://git.philomathiclife.com/repos/calc_rational
Log | Files | Refs | README

lib.rs (128984B)


      1 //! # `calc_lib`  
      2 //!   
      3 //! `calc_lib` is a library for performing basic rational number arithmetic using standard operator precedence
      4 //! and associativity. Internally, it is based on
      5 //! [`Ratio<T>`] and [`BigInt`].
      6 //!   
      7 //! ## Expressions  
      8 //!   
      9 //! The following are the list of expressions in descending order of precedence:  
     10 //!   1. number literals, `@`, `()`, `||`, `round()`, `rand()`  
     11 //!   2. `!`  
     12 //!   3. `^`  
     13 //!   4. `-` (unary negation operator)  
     14 //!   5. `*`, `/`, `mod`  
     15 //!   6. `+`, `-`  
     16 //!   
     17 //! All binary operators are left-associative sans `^` which is right-associative.  
     18 //!   
     19 //! Any expression is allowed to be enclosed in `()`. Note that parentheses are purely for grouping expressions;
     20 //! in particular, you cannot use them to represent multiplication (e.g., `4(2)` is grammatically incorrect and
     21 //! will result in an error message).  
     22 //!   
     23 //! Any expression is allowed to be enclosed in `||`. This unary operator represents absolute value.  
     24 //!   
     25 //! `!` is the factorial operator. Due to its high precedence, something like *-i!^j!* for *i, j ∈ ℕ* is
     26 //! the same thing as *-((i!)^(j!))*. If the expression preceding it does not evaluate to a non-negative integer,
     27 //! then an error will be displayed. Spaces  and tabs are *not* ignored; so `1 !` is grammatically incorrect and
     28 //! will result in an error message.  
     29 //!   
     30 //! `^` is the exponentiation operator. The expression left of the operator can evaluate to any rational number;
     31 //! however the expression right of the operator must evaluate to an integer or ±1/2 unless the expression on
     32 //! the left evaluates to `0` or `1`. In the event of the former, the expression right of the operator must evaluate
     33 //! to a non-negative rational number. In the event of the latter, the expression right of the operator can evaluate to
     34 //! any rational number. Note that `0^0` is defined to be 1. When the operand right of `^` evaluates to ±1/2, then
     35 //! the left operand must be the square of a rational number.  
     36 //!   
     37 //! The unary operator `-` represents negation.  
     38 //!   
     39 //! The operators `*` and `/` represent multiplication and division respectively. Expressions right of `/`
     40 //! must evaluate to any non-zero rational number; otherwise an error will be displayed.  
     41 //!   
     42 //! The binary operator `mod` represents modulo such that *n mod m = r = n - m\*q* for *n,q ∈ ℤ, m ∈ ℤ\\{0}, and r ∈ ℕ*
     43 //! where *r* is the minimum non-negative solution.  
     44 //!   
     45 //! The binary operators `+` and `-` represent addition and subtraction respectively.  
     46 //!   
     47 //! With the aforementioned exception of `!`, all spaces and tabs before and after operators are ignored.  
     48 //!   
     49 //! ## Round expression  
     50 //!   
     51 //! `round(expression, digit)` rounds `expression` to `digit`-number of fractional digits. An error will
     52 //! be displayed if called incorrectly.  
     53 //!   
     54 //! ## Rand expression  
     55 //!   
     56 //! `rand(expression, expression)` generates a random 64-bit integer inclusively between the passed expressions.
     57 //! An error will be displayed if called incorrectly. `rand()` generates a random 64-bit integer.  
     58 //!   
     59 //! ## Numbers  
     60 //!   
     61 //! A number literal is a non-empty sequence of digits or a non-empty sequence of digits immediately followed by `.`
     62 //! which is immediately followed by a non-empty sequence of digits (e.g., `134.901`). This means that number
     63 //! literals represent precisely all rational numbers that are equivalent to a ratio of a non-negative integer
     64 //! to a positive integer whose sole prime factors are 2 or 5. To represent all other rational numbers, the unary
     65 //! operator `-` and binary operator `/` must be used.  
     66 //!   
     67 //! ## Empty expression  
     68 //!   
     69 //! The empty expression (i.e., expression that at most only consists of spaces and tabs) will return
     70 //! the result from the previous non-(empty/store) expression in *decimal* form using the minimum number of digits.
     71 //! In the event an infinite number of digits is required, it will be rounded to 9 fractional digits using normal rounding
     72 //! rules first.  
     73 //!   
     74 //! ## Store expression  
     75 //!   
     76 //! To store the result of the previous non-(empty/store) expression, one simply passes `s`. In addition to storing the
     77 //! result which will subsequently be available via `@`, it displays the result. At most 8 results can be stored at once;
     78 //! at which point, results that are stored overwrite the oldest result.  
     79 //!   
     80 //! ## Recall expression  
     81 //!   
     82 //! `@` is used to recall previously stored results. It can be followed by any *digit* from `1` to `8`.
     83 //! If such a digit does not immediately follow it, then it will be interpreted as if there were a `1`.
     84 //! `@i` returns the *i*-th most-previous stored result where *i ∈ {1, 2, 3, 4, 5, 6, 7, 8}*.
     85 //! Note that spaces and tabs are *not* ignored so `@ 2` is grammatically incorrect and will result in an error message.
     86 //! As emphasized, it does not work on expressions; so both `@@` and `@(1)` are grammatically incorrect.  
     87 //!   
     88 //! ## Character encoding  
     89 //!   
     90 //! All inputs must only contain the ASCII encoding of the following Unicode scalar values: `0`-`9`, `.`, `+`, `-`,
     91 //! `*`, `/`, `^`, `!`, `mod`, `|`, `(`, `)`, `round`, `rand`, `,`, `@`, `s`, &lt;space&gt;, &lt;tab&gt;,
     92 //! &lt;line feed&gt;, &lt;carriage return&gt;, and `q`. Any other byte sequences are grammatically incorrect and will
     93 //! lead to an error message.  
     94 //!   
     95 //! ## Errors  
     96 //!   
     97 //! Errors due to a language violation (e.g., dividing by `0`) manifest into an error message. `panic!`s
     98 //! and [`io::Error`](https://doc.rust-lang.org/std/io/struct.Error.html)s caused by writing to the global
     99 //! standard output stream lead to program abortion.  
    100 //!   
    101 //! ## Exiting  
    102 //!   
    103 //! `q` with any number of spaces and tabs before and after will cause the program to terminate.  
    104 //!   
    105 //! ### Formal language specification  
    106 //!   
    107 //! For a more precise specification of the “calc language”, one can read the
    108 //! [calc language specification](https://git.philomathiclife.com/calc_rational/lang.pdf).
    109 #![no_std]
    110 #![cfg_attr(all(doc, channel_nightly), feature(doc_auto_cfg))]
    111 #![deny(
    112     unknown_lints,
    113     future_incompatible,
    114     let_underscore,
    115     missing_docs,
    116     nonstandard_style,
    117     refining_impl_trait,
    118     rust_2018_compatibility,
    119     rust_2018_idioms,
    120     rust_2021_compatibility,
    121     rust_2024_compatibility,
    122     unsafe_code,
    123     unused,
    124     unused_crate_dependencies,
    125     warnings,
    126     clippy::all,
    127     clippy::cargo,
    128     clippy::complexity,
    129     clippy::correctness,
    130     clippy::nursery,
    131     clippy::pedantic,
    132     clippy::perf,
    133     clippy::restriction,
    134     clippy::style,
    135     clippy::suspicious
    136 )]
    137 #![expect(
    138     clippy::arithmetic_side_effects,
    139     reason = "this is a calculator, so this is unavoidable"
    140 )]
    141 #![expect(
    142     clippy::blanket_clippy_restriction_lints,
    143     clippy::indexing_slicing,
    144     clippy::exhaustive_enums,
    145     clippy::implicit_return,
    146     clippy::min_ident_chars,
    147     clippy::missing_trait_methods,
    148     clippy::question_mark_used,
    149     clippy::ref_patterns,
    150     clippy::single_char_lifetime_names,
    151     clippy::unseparated_literal_suffix,
    152     reason = "noisy, opinionated, and likely doesn't prevent bugs or improve APIs"
    153 )]
    154 extern crate alloc;
    155 use alloc::{
    156     string::{String, ToString},
    157     vec,
    158     vec::Vec,
    159 };
    160 use cache::Cache;
    161 #[cfg(not(feature = "rand"))]
    162 use core::marker::PhantomData;
    163 use core::{
    164     convert,
    165     fmt::{self, Display, Formatter},
    166     ops::Index,
    167 };
    168 pub use num_bigint;
    169 use num_bigint::{BigInt, BigUint, Sign};
    170 use num_integer::Integer;
    171 pub use num_rational;
    172 use num_rational::Ratio;
    173 #[cfg(feature = "rand")]
    174 use num_traits::ToPrimitive;
    175 use num_traits::{Inv, Pow};
    176 #[cfg(feature = "rand")]
    177 pub use rand;
    178 #[cfg(feature = "rand")]
    179 use rand::{rngs::ThreadRng, RngCore};
    180 use LangErr::{
    181     DivByZero, ExpDivByZero, ExpIsNotIntOrOneHalf, InvalidAbs, InvalidDec, InvalidPar, InvalidQuit,
    182     InvalidRound, InvalidStore, MissingTerm, ModIsNotInt, ModZero, NotEnoughPrevResults,
    183     NotNonNegIntFact, SqrtDoesNotExist, TrailingSyms,
    184 };
    185 use O::{Empty, Eval, Exit, Store};
    186 /// Fixed-sized cache that automatically overwrites the oldest data
    187 /// when a new item is added and the cache is full. One can think of
    188 /// [`Cache`] as a very limited but more performant [`VecDeque`][alloc::collections::VecDeque] that only
    189 /// adds new data or reads old data.
    190 pub mod cache;
    191 /// Generalizes [`Iterator`] by using
    192 /// generic associated types.
    193 pub mod lending_iterator;
    194 /// Error due to a language violation.
    195 #[non_exhaustive]
    196 #[derive(Debug)]
    197 pub enum LangErr {
    198     /// The input began with a `q` but had non-whitespace
    199     /// that followed it.
    200     InvalidQuit,
    201     /// The input began with an `s` but had non-whitespace
    202     /// that followed it.
    203     InvalidStore,
    204     /// A sub-expression in the input would have led
    205     /// to a division by zero.
    206     DivByZero(usize),
    207     /// A sub-expression in the input would have led
    208     /// to a rational number that was not 0 or 1 to be
    209     /// raised to a non-integer power that is not (+/-) 1/2.
    210     ExpIsNotIntOrOneHalf(usize),
    211     /// A sub-expression in the input would have led
    212     /// to 0 being raised to a negative power which itself
    213     /// would have led to a division by zero.
    214     ExpDivByZero(usize),
    215     /// A sub-expression in the input would have led
    216     /// to a number modulo 0.
    217     ModZero(usize),
    218     /// A sub-expression in the input would have led
    219     /// to the mod of two expressions with at least one
    220     /// not being an integer.
    221     ModIsNotInt(usize),
    222     /// A sub-expression in the input would have led
    223     /// to a non-integer factorial or a negative integer factorial.
    224     NotNonNegIntFact(usize),
    225     /// The input contained a non-empty sequence of digits followed
    226     /// by `.` which was not followed by a non-empty sequence of digits.
    227     InvalidDec(usize),
    228     /// A recall expression was used to recall the *i*-th most-recent stored result,
    229     /// but there are fewer than *i* stored where
    230     /// *i ∈ {1, 2, 3, 4, 5, 6, 7, 8}*.
    231     NotEnoughPrevResults(usize),
    232     /// The input did not contain a closing `|`.
    233     InvalidAbs(usize),
    234     /// The input did not contain a closing `)`.
    235     InvalidPar(usize),
    236     /// The input contained an invalid round expression.
    237     InvalidRound(usize),
    238     /// A sub-expression in the input had a missing terminal expression
    239     /// where a terminal expression is a decimal literal expression,
    240     /// recall expression, absolute value expression, parenthetical
    241     /// expression, or round expression.
    242     MissingTerm(usize),
    243     /// The expression that was passed to the square root does not have a solution
    244     /// in the field of rational numbers.
    245     SqrtDoesNotExist(usize),
    246     /// The input started with a valid expression but was immediately followed
    247     /// by symbols that could not be chained with the preceding expression.
    248     TrailingSyms(usize),
    249     /// The input contained an invalid random expression.
    250     #[cfg(feature = "rand")]
    251     InvalidRand(usize),
    252     /// Error when the second argument is less than first in the rand function.
    253     #[cfg(feature = "rand")]
    254     RandInvalidArgs(usize),
    255     /// Error when there are no 64-bit integers in the interval passed to the random function.
    256     #[cfg(feature = "rand")]
    257     RandNoInts(usize),
    258 }
    259 impl Display for LangErr {
    260     #[inline]
    261     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    262         match *self {
    263             InvalidStore => f.write_str("Invalid store expression. A store expression must be of the extended regex form: ^[ \\t]*s[ \\t]*$."),
    264             InvalidQuit => f.write_str("Invalid quit expression. A quit expression must be of the extended regex form: ^[ \\t]*q[ \\t]*$."),
    265             DivByZero(u) => write!(f, "Division by zero ending at position {u}."),
    266             ExpIsNotIntOrOneHalf(u) => write!(f, "Non-integer exponent that is not (+/-) 1/2 with a base that was not 0 or 1 ending at position {u}."),
    267             ExpDivByZero(u) => write!(f, "Non-negative exponent with a base of 0 ending at position {u}."),
    268             ModZero(u) => write!(f, "A number modulo 0 ending at position {u}."),
    269             ModIsNotInt(u) => write!(f, "The modulo expression was applied to at least one non-integer ending at position {u}."),
    270             NotNonNegIntFact(u) => write!(f, "Factorial of a rational number that was not a non-negative integer ending at position {u}."),
    271             InvalidDec(u) => write!(f, "Invalid decimal literal expression ending at position {u}. A decimal literal expression must be of the extended regex form: [0-9]+(\\.[0-9]+)?."),
    272             NotEnoughPrevResults(len) => write!(f, "There are only {len} previous results."),
    273             InvalidAbs(u) => write!(f, "Invalid absolute value expression ending at position {u}. An absolute value expression is an addition expression enclosed in '||'."),
    274             InvalidPar(u) => write!(f, "Invalid parenthetical expression ending at position {u}. A parenthetical expression is an addition expression enclosed in '()'."),
    275             InvalidRound(u) => write!(f, "Invalid round expression ending at position {u}. A round expression is of the form 'round(<mod expression>, digit)'"),
    276             SqrtDoesNotExist(u) => write!(f, "The square root of the passed expression does not have a solution in the field of rational numbers ending at position {u}."),
    277             #[cfg(not(feature = "rand"))]
    278             MissingTerm(u) => write!(f, "Missing terminal expression at position {u}. A terminal expression is a decimal literal expression, recall expression, absolute value expression, parenthetical expression, or round expression."),
    279             #[cfg(feature = "rand")]
    280             MissingTerm(u) => write!(f, "Missing terminal expression at position {u}. A terminal expression is a decimal literal expression, recall expression, absolute value expression, parenthetical expression, round expression, or rand expression."),
    281             TrailingSyms(u) => write!(f, "Trailing symbols starting at position {u}."),
    282             #[cfg(feature = "rand")]
    283             Self::InvalidRand(u) => write!(f, "Invalid rand expression ending at position {u}. A rand expression is of the form 'rand()' or 'rand(<mod expression>, <mod expression>)'."),
    284             #[cfg(feature = "rand")]
    285             Self::RandInvalidArgs(u) => write!(f, "The second expression passed to the random function evaluated to rational number less than the first ending at position {u}."),
    286             #[cfg(feature = "rand")]
    287             Self::RandNoInts(u) => write!(f, "There are no 64-bit integers within the interval passed to the random function ending at position {u}."),
    288         }
    289     }
    290 }
    291 /// A successful evaluation of an input.
    292 #[derive(Debug)]
    293 pub enum O<'a> {
    294     /// The input only contained whitespace.
    295     /// This returns the previous `Eval`.
    296     /// It is `None` iff there have been no
    297     /// previous `Eval` results.
    298     Empty(&'a Option<Ratio<BigInt>>),
    299     /// The quit expression was issued to terminate the program.
    300     Exit,
    301     /// Result of a "normal" expression.
    302     Eval(&'a Ratio<BigInt>),
    303     /// The store expression stores and returns the previous `Eval`.
    304     /// It is `None` iff there have been no previous `Eval` results.
    305     Store(&'a Option<Ratio<BigInt>>),
    306 }
    307 impl<'a> Display for O<'a> {
    308     #[expect(
    309         unsafe_code,
    310         reason = "manually construct guaranteed UTF-8; thus avoid the needless check"
    311     )]
    312     #[inline]
    313     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    314         match *self {
    315             Empty(o) => {
    316                 o.as_ref().map_or(Ok(()), |val| {
    317                     if val.is_integer() {
    318                         write!(f, "> {val}")
    319                     } else {
    320                         // If the prime factors of the denominator are only 2 and 5,
    321                         // then the number requires a finite number of digits and thus
    322                         // will be represented perfectly using the fewest number of digits.
    323                         // Any other situation will be rounded to 9 fractional digits.
    324                         // max{twos, fives} represents the minimum number of fractional
    325                         // digits necessary to represent val.
    326                         let mut twos = 0;
    327                         let mut fives = 0;
    328                         let zero = BigInt::from_biguint(Sign::NoSign, BigUint::new(Vec::new()));
    329                         let one = BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1]));
    330                         let two = BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2]));
    331                         let five = BigInt::from_biguint(Sign::Plus, BigUint::new(vec![5]));
    332                         let mut denom = val.denom().clone();
    333                         let mut div_rem;
    334                         while denom > one {
    335                             div_rem = denom.div_rem(&two);
    336                             if div_rem.1 == zero {
    337                                 twos += 1;
    338                                 denom = div_rem.0;
    339                             } else {
    340                                 break;
    341                             }
    342                         }
    343                         while denom > one {
    344                             div_rem = denom.div_rem(&five);
    345                             if div_rem.1 == zero {
    346                                 fives += 1;
    347                                 denom = div_rem.0;
    348                             } else {
    349                                 break;
    350                             }
    351                         }
    352                         // int < 0 iff val <= -1. frac < 0 iff val is a negative non-integer.
    353                         let (int, frac, digits) = if denom == one {
    354                             let (int, mut frac) = val.numer().div_rem(val.denom());
    355                             while twos > fives {
    356                                 frac *= &five;
    357                                 fives += 1;
    358                             }
    359                             while fives > twos {
    360                                 frac *= &two;
    361                                 twos += 1;
    362                             }
    363                             (int, frac, twos)
    364                         } else {
    365                             // Requires an infinite number of decimal digits to represent, so we display
    366                             // 9 digits after rounding.
    367                             let mult =
    368                                 BigInt::from_biguint(Sign::Plus, BigUint::new(vec![10])).pow(9u8);
    369                             let (int, frac) = (val * &mult).round().numer().div_rem(&mult);
    370                             (int, frac, 9)
    371                         };
    372                         let int_str = int.to_string().into_bytes();
    373                         let (mut v, frac_str) = if val.numer().sign() == Sign::Minus {
    374                             if int_str[0] == b'-' {
    375                                 (
    376                                     Vec::with_capacity(int_str.len() + 1 + digits),
    377                                     (-frac).to_string().into_bytes(),
    378                                 )
    379                             } else {
    380                                 let mut tmp = Vec::with_capacity(int_str.len() + 2 + digits);
    381                                 tmp.push(b'-');
    382                                 (tmp, (-frac).to_string().into_bytes())
    383                             }
    384                         } else {
    385                             (
    386                                 Vec::with_capacity(int_str.len() + 1 + digits),
    387                                 frac.to_string().into_bytes(),
    388                             )
    389                         };
    390                         v.extend_from_slice(int_str.as_slice());
    391                         v.push(b'.');
    392                         // digits >= frac_str.len().
    393                         v.resize(v.len() + (digits - frac_str.len()), b'0');
    394                         v.extend_from_slice(frac_str.as_slice());
    395                         // SAFETY:
    396                         // v contains precisely the UTF-8 code units returned from Strings
    397                         // returned from the to_string function on the integer and fraction part of
    398                         // val plus optionally the single byte encodings of ".", "-", and "0".
    399                         write!(f, "> {}", unsafe { String::from_utf8_unchecked(v) })
    400                     }
    401                 })
    402             }
    403             Eval(r) => write!(f, "> {r}"),
    404             Exit => Ok(()),
    405             Store(o) => o.as_ref().map_or(Ok(()), |val| write!(f, "> {val}")),
    406         }
    407     }
    408 }
    409 /// Size of [`Evaluator::cache`].
    410 const CACHE_SIZE: usize = 8;
    411 /// Evaluates the supplied input.
    412 pub struct Evaluator<'input, 'cache, 'prev, 'scratch, 'rand> {
    413     /// The input to be evaluated.
    414     utf8: &'input [u8],
    415     /// The index within `utf8` that evaluation needs to continue.
    416     /// We use this instead of slicing from `utf8` since we want
    417     /// to be able to report the position within the input
    418     /// that an error occurs.
    419     i: usize,
    420     /// The cache of previously stored results.
    421     cache: &'cache mut Cache<Ratio<BigInt>, CACHE_SIZE>,
    422     /// The last result.
    423     prev: &'prev mut Option<Ratio<BigInt>>,
    424     /// Buffer used to evaluate right-associative sub-expressions.
    425     scratch: &'scratch mut Vec<Ratio<BigInt>>,
    426     /// Random number generator.
    427     #[cfg(feature = "rand")]
    428     rng: &'rand mut ThreadRng,
    429     #[cfg(not(feature = "rand"))]
    430     _rng: PhantomData<fn() -> &'rand ()>,
    431 }
    432 impl<'input, 'cache, 'prev, 'scratch, 'rand> Evaluator<'input, 'cache, 'prev, 'scratch, 'rand> {
    433     /// Creates an `Evaluator<'input, 'cache, 'prev, 'scratch, 'rand>` based on the supplied arguments.
    434     #[cfg(not(feature = "rand"))]
    435     #[inline]
    436     pub fn new(
    437         utf8: &'input [u8],
    438         cache: &'cache mut Cache<Ratio<BigInt>, 8>,
    439         prev: &'prev mut Option<Ratio<BigInt>>,
    440         scratch: &'scratch mut Vec<Ratio<BigInt>>,
    441     ) -> Self {
    442         Self {
    443             utf8,
    444             i: 0,
    445             cache,
    446             prev,
    447             scratch,
    448             _rng: PhantomData,
    449         }
    450     }
    451     /// Creates an `Evaluator<'input, 'cache, 'prev, 'scratch, 'rand>` based on the supplied arguments.
    452     #[cfg(feature = "rand")]
    453     #[inline]
    454     pub fn new(
    455         utf8: &'input [u8],
    456         cache: &'cache mut Cache<Ratio<BigInt>, 8>,
    457         prev: &'prev mut Option<Ratio<BigInt>>,
    458         scratch: &'scratch mut Vec<Ratio<BigInt>>,
    459         rng: &'rand mut ThreadRng,
    460     ) -> Self {
    461         Self {
    462             utf8,
    463             i: 0,
    464             cache,
    465             prev,
    466             scratch,
    467             rng,
    468         }
    469     }
    470     /// Evaluates the input consuming the `Evaluator<'input, 'cache, 'exp>`.
    471     /// Requires the input to contain one expression (i.e., if there are
    472     /// multiple newlines, it will error).
    473 
    474     /// # Errors
    475     ///
    476     /// Returns a [`LangErr`] iff the input violates the calc language.
    477     #[inline]
    478     pub fn evaluate(mut self) -> Result<O<'prev>, LangErr> {
    479         self.utf8 = if self.utf8.last().map_or(true, |b| *b != b'\n') {
    480             self.utf8
    481         } else {
    482             &self.utf8[..self.utf8.len()
    483                 - self
    484                     .utf8
    485                     .get(self.utf8.len().wrapping_sub(2))
    486                     .map_or(1, |b| if *b == b'\r' { 2 } else { 1 })]
    487         };
    488         self.consume_ws();
    489         let Some(b) = self.utf8.get(self.i) else {
    490             return Ok(Empty(self.prev));
    491         };
    492         if *b == b'q' {
    493             self.i += 1;
    494             self.consume_ws();
    495             if self.i == self.utf8.len() {
    496                 Ok(Exit)
    497             } else {
    498                 Err(InvalidQuit)
    499             }
    500         } else if *b == b's' {
    501             self.i += 1;
    502             self.consume_ws();
    503             if self.i == self.utf8.len() {
    504                 if let Some(ref val) = *self.prev {
    505                     self.cache.push(val.clone());
    506                 }
    507                 Ok(Store(self.prev))
    508             } else {
    509                 Err(InvalidStore)
    510             }
    511         } else {
    512             self.get_adds().and_then(move |val| {
    513                 self.consume_ws();
    514                 if self.i == self.utf8.len() {
    515                     Ok(Eval(self.prev.insert(val)))
    516                 } else {
    517                     Err(TrailingSyms(self.i))
    518                 }
    519             })
    520         }
    521     }
    522     /// Reads from the input until the next non-{space/tab} byte value.
    523     fn consume_ws(&mut self) {
    524         // ControlFlow makes more sense to use in try_fold; however due to a lack
    525         // of a map_or_else function, it is easier to simply return a Result with
    526         // Err taking the role of ControlFlow::Break.
    527         self.i += self.utf8[self.i..]
    528             .iter()
    529             .try_fold(0, |val, b| match *b {
    530                 b' ' | b'\t' => Ok(val + 1),
    531                 _ => Err(val),
    532             })
    533             .map_or_else(convert::identity, convert::identity);
    534     }
    535     /// Evaluates addition expressions as defined in the calc language.
    536     /// This function is used for both addition and subtraction operations which
    537     /// themselves are based on multiplication expressions.
    538     fn get_adds(&mut self) -> Result<Ratio<BigInt>, LangErr> {
    539         let mut left = self.get_mults()?;
    540         let mut j;
    541         self.consume_ws();
    542         while let Some(i) = self.utf8.get(self.i) {
    543             j = *i;
    544             self.consume_ws();
    545             if j == b'+' {
    546                 self.i += 1;
    547                 self.consume_ws();
    548                 left += self.get_mults()?;
    549             } else if j == b'-' {
    550                 self.i += 1;
    551                 self.consume_ws();
    552                 left -= self.get_mults()?;
    553             } else {
    554                 break;
    555             }
    556         }
    557         Ok(left)
    558     }
    559     /// Evaluates multiplication expressions as defined in the calc language.
    560     /// This function is used for both multiplication and division operations which
    561     /// themselves are based on negation expressions.
    562     fn get_mults(&mut self) -> Result<Ratio<BigInt>, LangErr> {
    563         let mut left = self.get_neg()?;
    564         let mut right;
    565         let mut j;
    566         let mut mod_val;
    567         let mut numer;
    568         self.consume_ws();
    569         while let Some(i) = self.utf8.get(self.i) {
    570             j = *i;
    571             self.consume_ws();
    572             if j == b'*' {
    573                 self.i += 1;
    574                 self.consume_ws();
    575                 left *= self.get_neg()?;
    576             } else if j == b'/' {
    577                 self.i += 1;
    578                 self.consume_ws();
    579                 right = self.get_neg()?;
    580                 if right.numer().sign() == Sign::NoSign {
    581                     return Err(DivByZero(self.i));
    582                 }
    583                 left /= right;
    584             } else if let Some(k) = self.utf8.get(self.i..self.i.saturating_add(3)) {
    585                 if k == b"mod" {
    586                     if !left.is_integer() {
    587                         return Err(ModIsNotInt(self.i));
    588                     }
    589                     self.i += 3;
    590                     self.consume_ws();
    591                     right = self.get_neg()?;
    592                     if !right.is_integer() {
    593                         return Err(ModIsNotInt(self.i));
    594                     }
    595                     numer = right.numer();
    596                     if numer.sign() == Sign::NoSign {
    597                         return Err(ModZero(self.i));
    598                     }
    599                     mod_val = left.numer() % numer;
    600                     left = Ratio::from_integer(if mod_val.sign() == Sign::Minus {
    601                         if numer.sign() == Sign::Minus {
    602                             mod_val - numer
    603                         } else {
    604                             mod_val + numer
    605                         }
    606                     } else {
    607                         mod_val
    608                     });
    609                 } else {
    610                     break;
    611                 }
    612             } else {
    613                 break;
    614             }
    615         }
    616         Ok(left)
    617     }
    618     /// Evaluates negation expressions as defined in the calc language.
    619     /// This function is based on exponentiation expressions.
    620     fn get_neg(&mut self) -> Result<Ratio<BigInt>, LangErr> {
    621         let mut count = 0usize;
    622         while let Some(b) = self.utf8.get(self.i) {
    623             if *b == b'-' {
    624                 self.i += 1;
    625                 self.consume_ws();
    626                 count += 1;
    627             } else {
    628                 break;
    629             }
    630         }
    631         self.get_exps()
    632             .map(|val| if count & 1 == 0 { val } else { -val })
    633     }
    634     /// Gets the square root of value so long as a solution exists.
    635     #[expect(
    636         clippy::unreachable,
    637         reason = "code that shouldn't happen did, so we want to crash"
    638     )]
    639     fn sqrt(val: Ratio<BigInt>) -> Option<Ratio<BigInt>> {
    640         /// Returns the square root of `n` if one exists; otherwise
    641         /// returns `None`.
    642         /// MUST NOT pass 0.
    643         #[expect(clippy::suspicious_operation_groupings, reason = "false positive")]
    644         fn calc(n: &BigUint) -> Option<BigUint> {
    645             let mut shift = n.bits();
    646             shift += shift & 1;
    647             let mut result = BigUint::new(Vec::new());
    648             let one = BigUint::new(vec![1]);
    649             let zero = BigUint::new(Vec::new());
    650             loop {
    651                 shift -= 2;
    652                 result <<= 1u32;
    653                 result |= &one;
    654                 result ^= if &result * &result > (n >> shift) {
    655                     &one
    656                 } else {
    657                     &zero
    658                 };
    659                 if shift == 0 {
    660                     break (&result * &result == *n).then_some(result);
    661                 }
    662             }
    663         }
    664         let numer = val.numer();
    665         if numer.sign() == Sign::NoSign {
    666             Some(val)
    667         } else {
    668             numer.try_into().map_or_else(
    669                 |_| None,
    670                 |num| {
    671                     calc(&num).and_then(|n| {
    672                         calc(&val.denom().try_into().unwrap_or_else(|_| {
    673                             unreachable!("Ratio must never have a negative denominator")
    674                         }))
    675                         .map(|d| Ratio::new(n.into(), d.into()))
    676                     })
    677                 },
    678             )
    679         }
    680     }
    681     /// Evaluates exponentiation expressions as defined in the calc language.
    682     /// This function is based on negation expressions.
    683     fn get_exps(&mut self) -> Result<Ratio<BigInt>, LangErr> {
    684         let mut t = self.get_fact()?;
    685         let ix = self.scratch.len();
    686         let mut prev;
    687         let mut numer;
    688         self.scratch.push(t);
    689         self.consume_ws();
    690         let mut j;
    691         let one = BigInt::new(Sign::Plus, vec![1]);
    692         let min_one = BigInt::new(Sign::Minus, vec![1]);
    693         let two = BigInt::new(Sign::Plus, vec![2]);
    694         while let Some(i) = self.utf8.get(self.i) {
    695             j = *i;
    696             self.consume_ws();
    697             if j == b'^' {
    698                 self.i += 1;
    699                 self.consume_ws();
    700                 t = self.get_neg()?;
    701                 // Safe since we always push at least one value, and we always
    702                 // return immediately once we encounter an error.
    703                 prev = self.scratch.index(self.scratch.len() - 1);
    704                 numer = prev.numer();
    705                 // Equiv to checking if prev is 0.
    706                 if numer.sign() == Sign::NoSign {
    707                     if t.numer().sign() == Sign::Minus {
    708                         self.scratch.clear();
    709                         return Err(ExpDivByZero(self.i));
    710                     }
    711                     self.scratch.push(t);
    712                 } else if prev.is_integer() {
    713                     let t_numer = t.numer();
    714                     // 1 raised to anything is 1, so we don't bother
    715                     // storing the exponent.
    716                     if *numer == one {
    717                     } else if t.is_integer()
    718                         || ((*t_numer == one || *t_numer == min_one) && *t.denom() == two)
    719                     {
    720                         self.scratch.push(t);
    721                     } else {
    722                         self.scratch.clear();
    723                         return Err(ExpIsNotIntOrOneHalf(self.i));
    724                     }
    725                 } else if t.is_integer()
    726                     || ((*t.numer() == one || *t.numer() == min_one) && *t.denom() == two)
    727                 {
    728                     self.scratch.push(t);
    729                 } else {
    730                     self.scratch.clear();
    731                     return Err(ExpIsNotIntOrOneHalf(self.i));
    732                 }
    733             } else {
    734                 break;
    735             }
    736         }
    737         self.scratch
    738             .drain(ix..)
    739             .try_rfold(Ratio::from_integer(one.clone()), |exp, base| {
    740                 if exp.is_integer() {
    741                     Ok(base.pow(exp.numer()))
    742                 } else if base.numer().sign() == Sign::NoSign {
    743                     Ok(base)
    744                 } else if *exp.denom() == two {
    745                     if *exp.numer() == one {
    746                         Self::sqrt(base).map_or_else(|| Err(SqrtDoesNotExist(self.i)), Ok)
    747                     } else if *exp.numer() == min_one {
    748                         Self::sqrt(base)
    749                             .map_or_else(|| Err(SqrtDoesNotExist(self.i)), |v| Ok(v.inv()))
    750                     } else {
    751                         Err(ExpIsNotIntOrOneHalf(self.i))
    752                     }
    753                 } else {
    754                     Err(ExpIsNotIntOrOneHalf(self.i))
    755                 }
    756             })
    757     }
    758     /// Evaluates factorial expressions as defined in the calc language.
    759     /// This function is based on terminal expressions.
    760     fn get_fact(&mut self) -> Result<Ratio<BigInt>, LangErr> {
    761         /// Calculates the factorial of `val`.
    762         fn fact(mut val: BigUint) -> BigUint {
    763             let zero = BigUint::new(Vec::new());
    764             let one = BigUint::new(vec![1]);
    765             let mut calc = BigUint::new(vec![1]);
    766             while val > zero {
    767                 calc *= &val;
    768                 val -= &one;
    769             }
    770             calc
    771         }
    772         let t = self.get_term()?;
    773         let Some(b) = self.utf8.get(self.i) else {
    774             return Ok(t);
    775         };
    776         if *b == b'!' {
    777             self.i += 1;
    778             if t.is_integer() {
    779                 // We can make a copy of self.i here, or call map_or instead
    780                 // of map_or_else.
    781                 let i = self.i;
    782                 t.numer().try_into().map_or_else(
    783                     |_| Err(NotNonNegIntFact(i)),
    784                     |val| {
    785                         let mut factorial = fact(val);
    786                         while let Some(b2) = self.utf8.get(self.i) {
    787                             if *b2 == b'!' {
    788                                 self.i += 1;
    789                                 factorial = fact(factorial);
    790                             } else {
    791                                 break;
    792                             }
    793                         }
    794                         Ok(Ratio::from_integer(BigInt::from_biguint(
    795                             Sign::Plus,
    796                             factorial,
    797                         )))
    798                     },
    799                 )
    800             } else {
    801                 Err(NotNonNegIntFact(self.i))
    802             }
    803         } else {
    804             Ok(t)
    805         }
    806     }
    807     /// Evaluates terminal expressions as defined in the calc language.
    808     /// This function is based on number literal expressions, parenthetical expressions,
    809     /// recall expressions, absolute value expressions, round expressions, and possibly
    810     /// rand expressions if that feature is enabled.
    811     fn get_term(&mut self) -> Result<Ratio<BigInt>, LangErr> {
    812         self.get_rational().map_or_else(Err, |o| {
    813             o.map_or_else(
    814                 || {
    815                     self.get_par().map_or_else(Err, |o2| {
    816                         o2.map_or_else(
    817                             || {
    818                                 self.get_recall().map_or_else(Err, |o3| {
    819                                     o3.map_or_else(
    820                                         || {
    821                                             self.get_abs().map_or_else(Err, |o4| {
    822                                                 o4.map_or_else(
    823                                                     || {
    824                                                         self.get_round().and_then(|o5| {
    825                                                             o5.map_or_else(
    826                                                                 #[cfg(not(feature = "rand"))]
    827                                                                 || Err(MissingTerm(self.i)),
    828                                                                 #[cfg(feature = "rand")]
    829                                                                 || self.get_rand(),
    830                                                                 Ok,
    831                                                             )
    832                                                         })
    833                                                     },
    834                                                     Ok,
    835                                                 )
    836                                             })
    837                                         },
    838                                         Ok,
    839                                     )
    840                                 })
    841                             },
    842                             Ok,
    843                         )
    844                     })
    845                 },
    846                 Ok,
    847             )
    848         })
    849     }
    850     /// Generates a random 64-bit integer. This function is based on add expressions. This is the last terminal
    851     /// expression attempted when needing a terminal expression; as a result, it is the only terminal expression
    852     /// that does not return an `Option`.
    853     #[cfg(feature = "rand")]
    854     fn get_rand(&mut self) -> Result<Ratio<BigInt>, LangErr> {
    855         /// Generates a random 64-bit integer.
    856         #[expect(clippy::host_endian_bytes, reason = "must keep platform endianness")]
    857         fn rand(rng: &mut ThreadRng) -> i64 {
    858             let mut bytes = [0; 8];
    859             // `ThreadRng::try_fill_bytes` is infallible, so easier to call `fill_bytes`.
    860             rng.fill_bytes(&mut bytes);
    861             i64::from_ne_bytes(bytes)
    862         }
    863         /// Generates a random 64-bit integer inclusively between the passed arguments.
    864         #[expect(clippy::single_call_fn, reason = "easier to reason about")]
    865         #[expect(
    866             clippy::integer_division_remainder_used,
    867             reason = "need for uniform randomness"
    868         )]
    869         #[expect(
    870             clippy::as_conversions,
    871             clippy::cast_possible_truncation,
    872             clippy::cast_possible_wrap,
    873             clippy::cast_sign_loss,
    874             reason = "lossless conversions between signed integers"
    875         )]
    876         fn rand_range(
    877             rng: &mut ThreadRng,
    878             lower: &Ratio<BigInt>,
    879             upper: &Ratio<BigInt>,
    880             i: usize,
    881         ) -> Result<i64, LangErr> {
    882             if lower > upper {
    883                 return Err(LangErr::RandInvalidArgs(i));
    884             }
    885             let lo = lower.ceil();
    886             let up = upper.floor();
    887             let lo_int = lo.numer();
    888             let up_int = up.numer();
    889             if lo_int > &BigInt::from(i64::MAX) || up_int < &BigInt::from(i64::MIN) {
    890                 return Err(LangErr::RandNoInts(i));
    891             }
    892             let lo_min = lo_int.to_i64().unwrap_or(i64::MIN);
    893             let up_max = up_int.to_i64().unwrap_or(i64::MAX);
    894             if up_max > lo_min || upper.is_integer() || lower.is_integer() {
    895                 let low = i128::from(lo_min);
    896                 // `i64::MAX >= up_max >= low`; so underflow and overflow cannot happen.
    897                 // range is [1, 2^64] so casting to a u128 is fine.
    898                 let modulus = (i128::from(up_max) - low + 1) as u128;
    899                 // range is [0, i64::MAX] so converting to a `u64` is fine.
    900                 // rem represents how many values need to be removed
    901                 // when generating a random i64 in order for uniformity.
    902                 let rem = (0x0001_0000_0000_0000_0000 % modulus) as u64;
    903                 let mut low_adj;
    904                 loop {
    905                     low_adj = rand(rng) as u64;
    906                     // Since rem is in [0, i64::MAX], this is the same as low_adj < 0 || low_adj >= rem.
    907                     if low_adj >= rem {
    908                         return Ok(
    909                             // range is [i64::MIN, i64::MAX]; thus casts are safe.
    910                             // modulus is up_max - low + 1; so as low grows,
    911                             // % shrinks by the same factor. i64::MAX happens
    912                             // when low = up_max = i64::MAX or when low = 0,
    913                             // up_max = i64::MAX and low_adj is i64::MAX.
    914                             ((u128::from(low_adj) % modulus) as i128 + low) as i64,
    915                         );
    916                     }
    917                 }
    918             } else {
    919                 Err(LangErr::RandNoInts(i))
    920             }
    921         }
    922         // This is the last kind of terminal expression that is attempted.
    923         // If there is no more data, then we have a missing terminal expression.
    924         let Some(b) = self.utf8.get(self.i..self.i.saturating_add(5)) else {
    925             return Err(MissingTerm(self.i));
    926         };
    927         if b == b"rand(" {
    928             self.i += 5;
    929             self.consume_ws();
    930             let i = self.i;
    931             self.utf8.get(self.i).map_or_else(
    932                 || Err(LangErr::InvalidRand(i)),
    933                 |p| {
    934                     if *p == b')' {
    935                         self.i += 1;
    936                         Ok(Ratio::from_integer(BigInt::from(rand(self.rng))))
    937                     } else {
    938                         let add = self.get_adds()?;
    939                         let Some(b2) = self.utf8.get(self.i) else {
    940                             return Err(LangErr::InvalidRand(self.i));
    941                         };
    942                         if *b2 == b',' {
    943                             self.i += 1;
    944                             self.consume_ws();
    945                             let add2 = self.get_adds()?;
    946                             self.consume_ws();
    947                             let Some(b3) = self.utf8.get(self.i) else {
    948                                 return Err(LangErr::InvalidRand(self.i));
    949                             };
    950                             if *b3 == b')' {
    951                                 self.i += 1;
    952                                 rand_range(self.rng, &add, &add2, self.i)
    953                                     .map(|v| Ratio::from_integer(BigInt::from(v)))
    954                             } else {
    955                                 Err(LangErr::InvalidRand(self.i))
    956                             }
    957                         } else {
    958                             Err(LangErr::InvalidRand(self.i))
    959                         }
    960                     }
    961                 },
    962             )
    963         } else {
    964             Err(MissingTerm(self.i))
    965         }
    966     }
    967     /// Rounds a value to the specified number of fractional digits.
    968     /// This function is based on add expressions.
    969     fn get_round(&mut self) -> Result<Option<Ratio<BigInt>>, LangErr> {
    970         let Some(b) = self.utf8.get(self.i..self.i.saturating_add(6)) else {
    971             return Ok(None);
    972         };
    973         if b == b"round(" {
    974             self.i += 6;
    975             self.consume_ws();
    976             let val = self.get_adds()?;
    977             self.consume_ws();
    978             let Some(b2) = self.utf8.get(self.i) else {
    979                 return Err(InvalidRound(self.i));
    980             };
    981             let b3 = *b2;
    982             if b3 == b',' {
    983                 self.i += 1;
    984                 self.consume_ws();
    985                 let Some(b4) = self.utf8.get(self.i) else {
    986                     return Err(InvalidRound(self.i));
    987                 };
    988                 let r = if b4.is_ascii_digit() {
    989                     self.i += 1;
    990                     *b4 - b'0'
    991                 } else {
    992                     return Err(InvalidRound(self.i));
    993                 };
    994                 self.consume_ws();
    995                 let i = self.i;
    996                 self.utf8.get(self.i).map_or_else(
    997                     || Err(InvalidRound(i)),
    998                     |p| {
    999                         if *p == b')' {
   1000                             self.i += 1;
   1001                             let mult =
   1002                                 BigInt::from_biguint(Sign::Plus, BigUint::new(vec![10])).pow(r);
   1003                             Ok(Some((val * &mult).round() / &mult))
   1004                         } else {
   1005                             Err(InvalidRound(self.i))
   1006                         }
   1007                     },
   1008                 )
   1009             } else {
   1010                 Err(InvalidRound(self.i))
   1011             }
   1012         } else {
   1013             Ok(None)
   1014         }
   1015     }
   1016     /// Evaluates absolute value expressions as defined in the calc language.
   1017     /// This function is based on add expressions.
   1018     fn get_abs(&mut self) -> Result<Option<Ratio<BigInt>>, LangErr> {
   1019         let Some(b) = self.utf8.get(self.i) else {
   1020             return Ok(None);
   1021         };
   1022         if *b == b'|' {
   1023             self.i += 1;
   1024             self.consume_ws();
   1025             let r = self.get_adds()?;
   1026             self.consume_ws();
   1027             let Some(b2) = self.utf8.get(self.i) else {
   1028                 return Err(InvalidAbs(self.i));
   1029             };
   1030             let b3 = *b2;
   1031             if b3 == b'|' {
   1032                 self.i += 1;
   1033                 Ok(Some(if r.numer().sign() == Sign::Minus {
   1034                     -r
   1035                 } else {
   1036                     r
   1037                 }))
   1038             } else {
   1039                 Err(InvalidAbs(self.i))
   1040             }
   1041         } else {
   1042             Ok(None)
   1043         }
   1044     }
   1045     /// Evaluates recall expressions as defined in the calc language.
   1046     // This does not return a Result<Option<&Ratio<BigInt>>, LangErr>
   1047     // since the only place this function is called is in get_term which
   1048     // would end up needing to clone the Ratio anyway. By not forcing
   1049     // get_term to clone, it can rely on map_or_else over match expressions.
   1050     fn get_recall(&mut self) -> Result<Option<Ratio<BigInt>>, LangErr> {
   1051         let Some(b) = self.utf8.get(self.i) else {
   1052             return Ok(None);
   1053         };
   1054         if *b == b'@' {
   1055             self.i += 1;
   1056             self.cache
   1057                 .get(self.utf8.get(self.i).map_or(0, |b2| {
   1058                     if (b'1'..b'9').contains(b2) {
   1059                         self.i += 1;
   1060                         usize::from(*b2 - b'1')
   1061                     } else {
   1062                         0
   1063                     }
   1064                 }))
   1065                 .map_or_else(
   1066                     || Err(NotEnoughPrevResults(self.cache.len())),
   1067                     |p| Ok(Some(p.clone())),
   1068                 )
   1069         } else {
   1070             Ok(None)
   1071         }
   1072     }
   1073     /// Evaluates parenthetical expressions as defined in the calc language.
   1074     /// This function is based on add expressions.
   1075     fn get_par(&mut self) -> Result<Option<Ratio<BigInt>>, LangErr> {
   1076         let Some(b) = self.utf8.get(self.i) else {
   1077             return Ok(None);
   1078         };
   1079         if *b == b'(' {
   1080             self.i += 1;
   1081             self.consume_ws();
   1082             let r = self.get_adds()?;
   1083             self.consume_ws();
   1084             let Some(b2) = self.utf8.get(self.i) else {
   1085                 return Err(InvalidPar(self.i));
   1086             };
   1087             let b3 = *b2;
   1088             if b3 == b')' {
   1089                 self.i += 1;
   1090                 Ok(Some(r))
   1091             } else {
   1092                 Err(InvalidPar(self.i))
   1093             }
   1094         } else {
   1095             Ok(None)
   1096         }
   1097     }
   1098     /// Evaluates number literal expressions as defined in the calc language.
   1099     fn get_rational(&mut self) -> Result<Option<Ratio<BigInt>>, LangErr> {
   1100         // ControlFlow makes more sense to use in try_fold; however due to a lack
   1101         // of a map_or_else function, it is easier to simply return a Result with
   1102         // Err taking the role of ControlFlow::Break.
   1103         /// Used to parse a sequence of digits into an unsigned integer.
   1104         fn to_biguint(v: &[u8]) -> (BigUint, usize) {
   1105             v.iter()
   1106                 .try_fold((BigUint::new(Vec::new()), 0), |mut prev, d| {
   1107                     if d.is_ascii_digit() {
   1108                         prev.1 += 1;
   1109                         // `*d - b'0'` is guaranteed to return a integer between 0 and 9.
   1110                         prev.0 = prev.0 * 10u8 + (*d - b'0');
   1111                         Ok(prev)
   1112                     } else {
   1113                         Err(prev)
   1114                     }
   1115                 })
   1116                 .map_or_else(convert::identity, convert::identity)
   1117         }
   1118         let (int, len) = to_biguint(&self.utf8[self.i..]);
   1119         if len == 0 {
   1120             return Ok(None);
   1121         }
   1122         self.i += len;
   1123         if let Some(b) = self.utf8.get(self.i) {
   1124             if *b == b'.' {
   1125                 self.i += 1;
   1126                 let (numer, len2) = to_biguint(&self.utf8[self.i..]);
   1127                 if len2 == 0 {
   1128                     Err(InvalidDec(self.i))
   1129                 } else {
   1130                     self.i += len2;
   1131                     Ok(Some(
   1132                         Ratio::from_integer(BigInt::from_biguint(Sign::Plus, int))
   1133                             + Ratio::new(
   1134                                 BigInt::from_biguint(Sign::Plus, numer),
   1135                                 BigInt::from_biguint(Sign::Plus, BigUint::new(vec![10]).pow(len2)),
   1136                             ),
   1137                     ))
   1138                 }
   1139             } else {
   1140                 Ok(Some(Ratio::from_integer(BigInt::from_biguint(
   1141                     Sign::Plus,
   1142                     int,
   1143                 ))))
   1144             }
   1145         } else {
   1146             Ok(Some(Ratio::from_integer(BigInt::from_biguint(
   1147                 Sign::Plus,
   1148                 int,
   1149             ))))
   1150         }
   1151     }
   1152 }
   1153 /// Reads data from `R` passing each line to an [`Evaluator`] to be evaluated.
   1154 #[cfg(feature = "std")]
   1155 pub struct EvalIter<R> {
   1156     /// Reader that contains input data.
   1157     reader: R,
   1158     /// Buffer that is used by `reader` to read
   1159     /// data into.
   1160     input_buffer: Vec<u8>,
   1161     /// Cache of stored results.
   1162     cache: Cache<Ratio<BigInt>, 8>,
   1163     /// Result of the previous expression.
   1164     prev: Option<Ratio<BigInt>>,
   1165     /// Buffer used by [`Evaluator`] to process
   1166     /// sub-expressions.
   1167     exp_buffer: Vec<Ratio<BigInt>>,
   1168     /// Random number generator.
   1169     #[cfg(feature = "rand")]
   1170     rng: ThreadRng,
   1171 }
   1172 #[cfg(feature = "std")]
   1173 impl<R> EvalIter<R> {
   1174     /// Creates a new `EvalIter`.
   1175     #[inline]
   1176     #[cfg(feature = "rand")]
   1177     pub fn new(reader: R) -> Self {
   1178         Self {
   1179             reader,
   1180             input_buffer: Vec::new(),
   1181             cache: Cache::new(),
   1182             prev: None,
   1183             exp_buffer: Vec::new(),
   1184             rng: rand::thread_rng(),
   1185         }
   1186     }
   1187     /// Creates a new `EvalIter`.
   1188     #[inline]
   1189     #[cfg(any(doc, not(feature = "rand")))]
   1190     pub fn new(reader: R) -> Self {
   1191         Self {
   1192             reader,
   1193             input_buffer: Vec::new(),
   1194             cache: Cache::new(),
   1195             prev: None,
   1196             exp_buffer: Vec::new(),
   1197         }
   1198     }
   1199 }
   1200 #[cfg(feature = "std")]
   1201 extern crate std;
   1202 #[cfg(feature = "std")]
   1203 use std::io::{BufRead, Error};
   1204 #[cfg(feature = "std")]
   1205 /// Error returned from [`EvalIter`] when an expression has an error.
   1206 #[derive(Debug)]
   1207 pub enum E {
   1208     /// Error containing [`Error`] which is returned
   1209     /// from [`EvalIter`] when reading from the supplied
   1210     /// [`BufRead`]er.
   1211     Error(Error),
   1212     /// Error containing [`LangErr`] which is returned
   1213     /// from [`EvalIter`] when evaluating a single expression.
   1214     LangErr(LangErr),
   1215 }
   1216 #[cfg(feature = "std")]
   1217 impl Display for E {
   1218     #[inline]
   1219     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
   1220         match *self {
   1221             Self::Error(ref e) => e.fmt(f),
   1222             Self::LangErr(ref e) => e.fmt(f),
   1223         }
   1224     }
   1225 }
   1226 #[cfg(feature = "std")]
   1227 use crate::lending_iterator::LendingIterator;
   1228 #[cfg(feature = "std")]
   1229 impl<R> LendingIterator for EvalIter<R>
   1230 where
   1231     R: BufRead,
   1232 {
   1233     type Item<'a> = Result<O<'a>, E> where Self: 'a;
   1234     #[inline]
   1235     fn lend_next(&mut self) -> Option<Result<O<'_>, E>> {
   1236         self.input_buffer.clear();
   1237         self.exp_buffer.clear();
   1238         self.reader
   1239             .read_until(b'\n', &mut self.input_buffer)
   1240             .map_or_else(
   1241                 |e| Some(Err(E::Error(e))),
   1242                 |c| {
   1243                     if c == 0 {
   1244                         None
   1245                     } else {
   1246                         Evaluator::new(
   1247                             self.input_buffer.as_slice(),
   1248                             &mut self.cache,
   1249                             &mut self.prev,
   1250                             &mut self.exp_buffer,
   1251                             #[cfg(feature = "rand")]
   1252                             &mut self.rng,
   1253                         )
   1254                         .evaluate()
   1255                         .map_or_else(
   1256                             |e| Some(Err(E::LangErr(e))),
   1257                             |o| match o {
   1258                                 O::Empty(_) | O::Eval(_) | O::Store(_) => Some(Ok(o)),
   1259                                 O::Exit => None,
   1260                             },
   1261                         )
   1262                     }
   1263                 },
   1264             )
   1265     }
   1266 }
   1267 #[cfg(test)]
   1268 mod tests {
   1269     use super::*;
   1270     #[cfg(not(feature = "rand"))]
   1271     #[test]
   1272     fn empty() {
   1273         // Empty expressions without a previous result return nothing.
   1274         assert!(
   1275             match Evaluator::new(b"\n", &mut Cache::new(), &mut None, &mut Vec::new())
   1276                 .evaluate()
   1277                 .unwrap()
   1278             {
   1279                 O::Empty(o) => o.is_none(),
   1280                 _ => false,
   1281             }
   1282         );
   1283         assert!(
   1284             Evaluator::new(
   1285                 b"  \t  \t \n",
   1286                 &mut Cache::new(),
   1287                 &mut Some(Ratio::from_integer(BigInt::from_biguint(
   1288                     Sign::Minus,
   1289                     BigUint::new(vec![12])
   1290                 ))),
   1291                 &mut Vec::new()
   1292             )
   1293             .evaluate()
   1294             .unwrap()
   1295             .to_string()
   1296                 == "> -12"
   1297         );
   1298         assert!(
   1299             Evaluator::new(
   1300                 b"\t\n",
   1301                 &mut Cache::new(),
   1302                 &mut Some(Ratio::new(
   1303                     BigInt::from_biguint(Sign::Minus, BigUint::new(vec![4])),
   1304                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![6]))
   1305                 )),
   1306                 &mut Vec::new()
   1307             )
   1308             .evaluate()
   1309             .unwrap()
   1310             .to_string()
   1311                 == "> -0.666666667"
   1312         );
   1313         assert!(
   1314             Evaluator::new(
   1315                 b"\t\n",
   1316                 &mut Cache::new(),
   1317                 &mut Some(Ratio::new(
   1318                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])),
   1319                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![4230196224, 6]))
   1320                 )),
   1321                 &mut Vec::new()
   1322             )
   1323             .evaluate()
   1324             .unwrap()
   1325             .to_string()
   1326                 == "> 0.000000000"
   1327         );
   1328         assert!(
   1329             Evaluator::new(
   1330                 b"\t\n",
   1331                 &mut Cache::new(),
   1332                 &mut Some(Ratio::new(
   1333                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![17])),
   1334                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![4230196224, 6]))
   1335                 )),
   1336                 &mut Vec::new()
   1337             )
   1338             .evaluate()
   1339             .unwrap()
   1340             .to_string()
   1341                 == "> 0.000000001"
   1342         );
   1343         assert!(
   1344             Evaluator::new(
   1345                 b"\t\n",
   1346                 &mut Cache::new(),
   1347                 &mut Some(Ratio::new(
   1348                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![3])),
   1349                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![10]))
   1350                 )),
   1351                 &mut Vec::new()
   1352             )
   1353             .evaluate()
   1354             .unwrap()
   1355             .to_string()
   1356                 == "> 0.3"
   1357         );
   1358         assert!(
   1359             Evaluator::new(
   1360                 b"\t\n",
   1361                 &mut Cache::new(),
   1362                 &mut Some(Ratio::new(
   1363                     BigInt::from_biguint(Sign::Minus, BigUint::new(vec![203])),
   1364                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![10]))
   1365                 )),
   1366                 &mut Vec::new()
   1367             )
   1368             .evaluate()
   1369             .unwrap()
   1370             .to_string()
   1371                 == "> -20.3"
   1372         );
   1373         assert!(
   1374             Evaluator::new(
   1375                 &[0u8; 0],
   1376                 &mut Cache::new(),
   1377                 &mut Some(Ratio::new(
   1378                     BigInt::from_biguint(Sign::Minus, BigUint::new(vec![203])),
   1379                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![10]))
   1380                 )),
   1381                 &mut Vec::new()
   1382             )
   1383             .evaluate()
   1384             .unwrap()
   1385             .to_string()
   1386                 == "> -20.3"
   1387         );
   1388     }
   1389     #[cfg(not(feature = "rand"))]
   1390     #[test]
   1391     fn number_literal() {
   1392         // Normal 0 is fine.
   1393         assert!(
   1394             Evaluator::new(b"0", &mut Cache::new(), &mut None, &mut Vec::new())
   1395                 .get_rational()
   1396                 .unwrap()
   1397                 .unwrap()
   1398                 == Ratio::from_integer(BigInt::from_biguint(
   1399                     Sign::NoSign,
   1400                     BigUint::new(Vec::new())
   1401                 ))
   1402         );
   1403         // Leading 0s and trailing 0s are fine.
   1404         assert!(
   1405             Evaluator::new(b"0000.00000", &mut Cache::new(), &mut None, &mut Vec::new())
   1406                 .get_rational()
   1407                 .unwrap()
   1408                 .unwrap()
   1409                 == Ratio::from_integer(BigInt::from_biguint(
   1410                     Sign::NoSign,
   1411                     BigUint::new(Vec::new())
   1412                 ))
   1413         );
   1414         // Parsing stops at first non-(digit/period).
   1415         assert!(
   1416             Evaluator::new(b"1 0", &mut Cache::new(), &mut None, &mut Vec::new())
   1417                 .get_rational()
   1418                 .unwrap()
   1419                 .unwrap()
   1420                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   1421         );
   1422         let int = b"3397450981271938475135134759823759835414";
   1423         let frac = b"913759810573549872354897210539127530981570";
   1424         let left = Ratio::from_integer(BigInt::parse_bytes(int, 10).unwrap());
   1425         let right = Ratio::new(
   1426             BigInt::parse_bytes(frac, 10).unwrap(),
   1427             BigInt::from_biguint(Sign::Plus, BigUint::new(vec![10]).pow(frac.len() + 1)),
   1428         );
   1429         let mut vec = Vec::new();
   1430         vec.extend_from_slice(int);
   1431         vec.push(b'.');
   1432         vec.push(b'0');
   1433         vec.extend_from_slice(frac);
   1434         // Test a number whose integer and fraction portions are larger than u128::MAX.
   1435         assert!(
   1436             Evaluator::new(
   1437                 vec.as_slice(),
   1438                 &mut Cache::new(),
   1439                 &mut None,
   1440                 &mut Vec::new()
   1441             )
   1442             .get_rational()
   1443             .unwrap()
   1444             .unwrap()
   1445                 == left + right
   1446         );
   1447         // Leading 0s and trailing 0s for a non-zero value are fine.
   1448         assert!(
   1449             Evaluator::new(
   1450                 b"000000014.0000000000000",
   1451                 &mut Cache::new(),
   1452                 &mut None,
   1453                 &mut Vec::new()
   1454             )
   1455             .get_rational()
   1456             .unwrap()
   1457             .unwrap()
   1458                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![14])))
   1459         );
   1460         // A sequence of digits followed immediately by a decimal point but no digits after is invalid.
   1461         assert!(
   1462             match Evaluator::new(b"1.", &mut Cache::new(), &mut None, &mut Vec::new())
   1463                 .get_rational()
   1464                 .unwrap_err()
   1465             {
   1466                 InvalidDec(i) => i == 2,
   1467                 _ => false,
   1468             }
   1469         );
   1470         // A sequence of digits followed immediately by a decimal point but no digits after is invalid.
   1471         // This just shows that spaces are not ignored in number literals.
   1472         assert!(
   1473             match Evaluator::new(b"1. 2", &mut Cache::new(), &mut None, &mut Vec::new())
   1474                 .get_rational()
   1475                 .unwrap_err()
   1476             {
   1477                 InvalidDec(i) => i == 2,
   1478                 _ => false,
   1479             }
   1480         );
   1481         // Non-whitespace starting the input is valid but produces no value.
   1482         // This also shows that an invalid byte sequence does not produce an error here.
   1483         assert!(
   1484             Evaluator::new(b"a1", &mut Cache::new(), &mut None, &mut Vec::new())
   1485                 .get_rational()
   1486                 .unwrap()
   1487                 .is_none()
   1488         );
   1489         // A space starting the input is valid but produces no value.
   1490         assert!(
   1491             Evaluator::new(b" 1", &mut Cache::new(), &mut None, &mut Vec::new())
   1492                 .get_rational()
   1493                 .unwrap()
   1494                 .is_none()
   1495         );
   1496         // A tab starting the input is valid but produces no value.
   1497         assert!(
   1498             Evaluator::new(b"\t1", &mut Cache::new(), &mut None, &mut Vec::new())
   1499                 .get_rational()
   1500                 .unwrap()
   1501                 .is_none()
   1502         );
   1503         // Negative literals don't exist, so this should succeed but produce nothing.
   1504         assert!(
   1505             Evaluator::new(b"-1", &mut Cache::new(), &mut None, &mut Vec::new())
   1506                 .get_rational()
   1507                 .unwrap()
   1508                 .is_none()
   1509         );
   1510         // '/' is division and not part of a number literal so only the "numerator" is parsed.
   1511         assert!(
   1512             Evaluator::new(b"1/2", &mut Cache::new(), &mut None, &mut Vec::new())
   1513                 .get_rational()
   1514                 .unwrap()
   1515                 .unwrap()
   1516                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   1517         );
   1518         // A sequence of digits followed by invalid bytes is valid and produces a number equal to the digits before the invalid bytes.
   1519         assert!(
   1520             Evaluator::new(b"130alj", &mut Cache::new(), &mut None, &mut Vec::new())
   1521                 .get_rational()
   1522                 .unwrap()
   1523                 .unwrap()
   1524                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![130])))
   1525         );
   1526     }
   1527     #[cfg(not(feature = "rand"))]
   1528     #[test]
   1529     fn par() {
   1530         // Missing closing ')'
   1531         assert!(
   1532             match Evaluator::new(b"(1", &mut Cache::new(), &mut None, &mut Vec::new())
   1533                 .get_par()
   1534                 .unwrap_err()
   1535             {
   1536                 InvalidPar(i) => i == 2,
   1537                 _ => false,
   1538             }
   1539         );
   1540         assert!(
   1541             match Evaluator::new(b"((1\t + 2)", &mut Cache::new(), &mut None, &mut Vec::new())
   1542                 .get_par()
   1543                 .unwrap_err()
   1544             {
   1545                 InvalidPar(i) => i == 9,
   1546                 _ => false,
   1547             }
   1548         );
   1549         assert!(
   1550             Evaluator::new(b"(  0 \t )", &mut Cache::new(), &mut None, &mut Vec::new())
   1551                 .get_par()
   1552                 .unwrap()
   1553                 .unwrap()
   1554                 == Ratio::from_integer(BigInt::from_biguint(
   1555                     Sign::NoSign,
   1556                     BigUint::new(Vec::new())
   1557                 ))
   1558         );
   1559         assert!(
   1560             Evaluator::new(b"( - \t 5 )", &mut Cache::new(), &mut None, &mut Vec::new())
   1561                 .get_par()
   1562                 .unwrap()
   1563                 .unwrap()
   1564                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![5])))
   1565         );
   1566         assert!(
   1567             Evaluator::new(
   1568                 b"( ( 2 -\t  5) * 9 )",
   1569                 &mut Cache::new(),
   1570                 &mut None,
   1571                 &mut Vec::new()
   1572             )
   1573             .get_par()
   1574             .unwrap()
   1575             .unwrap()
   1576                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![27])))
   1577         );
   1578     }
   1579     #[cfg(not(feature = "rand"))]
   1580     #[test]
   1581     fn recall_expression() {
   1582         // If the input does not start with '@', then it's valid but produces nothing.
   1583         assert!(
   1584             Evaluator::new(b"1", &mut Cache::new(), &mut None, &mut Vec::new())
   1585                 .get_recall()
   1586                 .unwrap()
   1587                 .is_none()
   1588         );
   1589         assert!(
   1590             Evaluator::new(b"a", &mut Cache::new(), &mut None, &mut Vec::new())
   1591                 .get_recall()
   1592                 .unwrap()
   1593                 .is_none()
   1594         );
   1595         assert!(
   1596             Evaluator::new(b" @", &mut Cache::new(), &mut None, &mut Vec::new())
   1597                 .get_recall()
   1598                 .unwrap()
   1599                 .is_none()
   1600         );
   1601         assert!(
   1602             Evaluator::new(b"\t@", &mut Cache::new(), &mut None, &mut Vec::new())
   1603                 .get_recall()
   1604                 .unwrap()
   1605                 .is_none()
   1606         );
   1607         // Invalid recall expression since there are no previous results.
   1608         assert!(
   1609             match Evaluator::new(b"@", &mut Cache::new(), &mut None, &mut Vec::new())
   1610                 .get_recall()
   1611                 .unwrap_err()
   1612             {
   1613                 NotEnoughPrevResults(count) => count == 0,
   1614                 _ => false,
   1615             }
   1616         );
   1617         // Invalid recall expression since there are no previous results.
   1618         assert!(
   1619             match Evaluator::new(b"@4", &mut Cache::new(), &mut None, &mut Vec::new())
   1620                 .get_recall()
   1621                 .unwrap_err()
   1622             {
   1623                 NotEnoughPrevResults(count) => count == 0,
   1624                 _ => false,
   1625             }
   1626         );
   1627         // Invalid recall expression since there are no previous results.
   1628         // The input violates our grammar, but this error happens before that.
   1629         assert!(
   1630             match Evaluator::new(b"@0", &mut Cache::new(), &mut None, &mut Vec::new())
   1631                 .get_recall()
   1632                 .unwrap_err()
   1633             {
   1634                 NotEnoughPrevResults(count) => count == 0,
   1635                 _ => false,
   1636             }
   1637         );
   1638         // Successfully extract previous expression.
   1639         let mut prev = None;
   1640         let mut cache = Cache::new();
   1641         Evaluator::new(b"1\n", &mut cache, &mut prev, &mut Vec::new())
   1642             .evaluate()
   1643             .unwrap();
   1644         Evaluator::new(b"   s   \r\n", &mut cache, &mut prev, &mut Vec::new())
   1645             .evaluate()
   1646             .unwrap();
   1647         assert!(
   1648             Evaluator::new(b"@", &mut cache, &mut prev, &mut Vec::new())
   1649                 .get_recall()
   1650                 .unwrap()
   1651                 .unwrap()
   1652                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   1653         );
   1654         // Invalid characters are ignored at this stage.
   1655         assert!(
   1656             Evaluator::new(b"@&", &mut cache, &mut prev, &mut Vec::new())
   1657                 .get_recall()
   1658                 .unwrap()
   1659                 .unwrap()
   1660                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   1661         );
   1662         // 0 is not a valid stored value only 1-8 are.
   1663         assert!(
   1664             Evaluator::new(b"@0", &mut cache, &mut prev, &mut Vec::new())
   1665                 .get_recall()
   1666                 .unwrap()
   1667                 .unwrap()
   1668                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   1669         );
   1670         // 9 is not a valid stored value only 1-8 are.
   1671         assert!(
   1672             Evaluator::new(b"@9", &mut cache, &mut prev, &mut Vec::new())
   1673                 .get_recall()
   1674                 .unwrap()
   1675                 .unwrap()
   1676                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   1677         );
   1678         // Spaces are not cleaned; otherwise this would error since we only have 1 stored value.
   1679         assert!(
   1680             Evaluator::new(b"@ 2", &mut cache, &mut prev, &mut Vec::new())
   1681                 .get_recall()
   1682                 .unwrap()
   1683                 .unwrap()
   1684                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   1685         );
   1686         // Tabs are not cleaned; otherwise this would error since we only have 1 stored value.
   1687         assert!(
   1688             Evaluator::new(b"@\t2", &mut cache, &mut prev, &mut Vec::new())
   1689                 .get_recall()
   1690                 .unwrap()
   1691                 .unwrap()
   1692                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   1693         );
   1694         // One digits are looked at so this is not @<ten>.
   1695         assert!(
   1696             Evaluator::new(b"@10", &mut cache, &mut prev, &mut Vec::new())
   1697                 .get_recall()
   1698                 .unwrap()
   1699                 .unwrap()
   1700                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   1701         );
   1702         // Invalid recall expression since there is only one stored result.
   1703         assert!(
   1704             match Evaluator::new(b"@2", &mut cache, &mut prev, &mut Vec::new())
   1705                 .get_recall()
   1706                 .unwrap_err()
   1707             {
   1708                 NotEnoughPrevResults(count) => count == 1,
   1709                 _ => false,
   1710             }
   1711         );
   1712         Evaluator::new(b"2\r\n", &mut cache, &mut prev, &mut Vec::new())
   1713             .evaluate()
   1714             .unwrap();
   1715         Evaluator::new(b"s\n", &mut cache, &mut prev, &mut Vec::new())
   1716             .evaluate()
   1717             .unwrap();
   1718         // Stored values correct.
   1719         assert!(
   1720             Evaluator::new(b"@", &mut cache, &mut prev, &mut Vec::new())
   1721                 .get_recall()
   1722                 .unwrap()
   1723                 .unwrap()
   1724                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2])))
   1725         );
   1726         assert!(
   1727             Evaluator::new(b"@2", &mut cache, &mut prev, &mut Vec::new())
   1728                 .get_recall()
   1729                 .unwrap()
   1730                 .unwrap()
   1731                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   1732         );
   1733         // Invalid recall expression since there are only three stored results.
   1734         assert!(
   1735             match Evaluator::new(b"@3", &mut cache, &mut prev, &mut Vec::new())
   1736                 .get_recall()
   1737                 .unwrap_err()
   1738             {
   1739                 NotEnoughPrevResults(count) => count == 2,
   1740                 _ => false,
   1741             }
   1742         );
   1743         let mut v = vec![0, b'\n'];
   1744         for i in b'3'..=b'8' {
   1745             v[0] = i;
   1746             Evaluator::new(v.as_slice(), &mut cache, &mut prev, &mut Vec::new())
   1747                 .evaluate()
   1748                 .unwrap();
   1749             Evaluator::new(b"s\n", &mut cache, &mut prev, &mut Vec::new())
   1750                 .evaluate()
   1751                 .unwrap();
   1752         }
   1753         v[0] = b'@';
   1754         for i in b'1'..=b'8' {
   1755             v[1] = i;
   1756             // Cache is filled up correctly storing all previous values.
   1757             assert!(
   1758                 Evaluator::new(v.as_slice(), &mut cache, &mut prev, &mut Vec::new())
   1759                     .get_recall()
   1760                     .unwrap()
   1761                     .unwrap()
   1762                     == Ratio::from_integer(BigInt::from_biguint(
   1763                         Sign::Plus,
   1764                         BigUint::new(vec![(b'9' - i) as u32])
   1765                     ))
   1766             );
   1767         }
   1768         // Only parses the first @ since the second @ is not a digit between 1 and 8.
   1769         assert!(
   1770             Evaluator::new(b"@@", &mut cache, &mut prev, &mut Vec::new())
   1771                 .get_recall()
   1772                 .unwrap()
   1773                 .unwrap()
   1774                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![8])))
   1775         );
   1776         Evaluator::new(b"9\r\n", &mut cache, &mut prev, &mut Vec::new())
   1777             .evaluate()
   1778             .unwrap();
   1779         Evaluator::new(b"s\n", &mut cache, &mut prev, &mut Vec::new())
   1780             .evaluate()
   1781             .unwrap();
   1782         // Oldest value is overwritten; all others remain.
   1783         for i in b'1'..=b'8' {
   1784             v[1] = i;
   1785             assert!(
   1786                 Evaluator::new(v.as_slice(), &mut cache, &mut prev, &mut Vec::new())
   1787                     .get_recall()
   1788                     .unwrap()
   1789                     .unwrap()
   1790                     == Ratio::from_integer(BigInt::from_biguint(
   1791                         Sign::Plus,
   1792                         BigUint::new(vec![((b'9' + 1) - i) as u32])
   1793                     ))
   1794             );
   1795         }
   1796     }
   1797     #[cfg(not(feature = "rand"))]
   1798     #[test]
   1799     fn abs() {
   1800         // Missing closing '|'
   1801         assert!(
   1802             match Evaluator::new(b"|1", &mut Cache::new(), &mut None, &mut Vec::new())
   1803                 .get_abs()
   1804                 .unwrap_err()
   1805             {
   1806                 InvalidAbs(i) => i == 2,
   1807                 _ => false,
   1808             }
   1809         );
   1810         assert!(
   1811             match Evaluator::new(b"||1 + 2|", &mut Cache::new(), &mut None, &mut Vec::new())
   1812                 .get_abs()
   1813                 .unwrap_err()
   1814             {
   1815                 InvalidAbs(i) => i == 8,
   1816                 _ => false,
   1817             }
   1818         );
   1819         assert!(
   1820             Evaluator::new(
   1821                 b"|  0\t \t |",
   1822                 &mut Cache::new(),
   1823                 &mut None,
   1824                 &mut Vec::new()
   1825             )
   1826             .get_abs()
   1827             .unwrap()
   1828             .unwrap()
   1829                 == Ratio::from_integer(BigInt::from_biguint(
   1830                     Sign::NoSign,
   1831                     BigUint::new(Vec::new())
   1832                 ))
   1833         );
   1834         assert!(
   1835             Evaluator::new(b"| -  5 |", &mut Cache::new(), &mut None, &mut Vec::new())
   1836                 .get_abs()
   1837                 .unwrap()
   1838                 .unwrap()
   1839                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![5])))
   1840         );
   1841         assert!(
   1842             Evaluator::new(
   1843                 b"| \t| 2 -  5| * 9 |",
   1844                 &mut Cache::new(),
   1845                 &mut None,
   1846                 &mut Vec::new()
   1847             )
   1848             .get_abs()
   1849             .unwrap()
   1850             .unwrap()
   1851                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![27])))
   1852         );
   1853         // If the input does not start with '|', then it's valid but produces nothing.
   1854         assert!(
   1855             Evaluator::new(b" \t|9|", &mut Cache::new(), &mut None, &mut Vec::new())
   1856                 .get_abs()
   1857                 .unwrap()
   1858                 .is_none()
   1859         );
   1860     }
   1861     #[cfg(not(feature = "rand"))]
   1862     #[test]
   1863     fn round() {
   1864         // Missing ',<digit>)'
   1865         assert!(
   1866             match Evaluator::new(b"round(1", &mut Cache::new(), &mut None, &mut Vec::new())
   1867                 .get_round()
   1868                 .unwrap_err()
   1869             {
   1870                 InvalidRound(i) => i == 7,
   1871                 _ => false,
   1872             }
   1873         );
   1874         assert!(
   1875             match Evaluator::new(b"round(1,", &mut Cache::new(), &mut None, &mut Vec::new())
   1876                 .get_round()
   1877                 .unwrap_err()
   1878             {
   1879                 InvalidRound(i) => i == 8,
   1880                 _ => false,
   1881             }
   1882         );
   1883         assert!(
   1884             match Evaluator::new(b"round(1,2", &mut Cache::new(), &mut None, &mut Vec::new())
   1885                 .get_round()
   1886                 .unwrap_err()
   1887             {
   1888                 InvalidRound(i) => i == 9,
   1889                 _ => false,
   1890             }
   1891         );
   1892         assert!(match Evaluator::new(
   1893             b"round(1,10)",
   1894             &mut Cache::new(),
   1895             &mut None,
   1896             &mut Vec::new()
   1897         )
   1898         .get_round()
   1899         .unwrap_err()
   1900         {
   1901             InvalidRound(i) => i == 9,
   1902             _ => false,
   1903         });
   1904         assert!(
   1905             match Evaluator::new(b"round(1,a)", &mut Cache::new(), &mut None, &mut Vec::new())
   1906                 .get_round()
   1907                 .unwrap_err()
   1908             {
   1909                 InvalidRound(i) => i == 8,
   1910                 _ => false,
   1911             }
   1912         );
   1913         assert!(
   1914             Evaluator::new(
   1915                 b"round(2, 7)",
   1916                 &mut Cache::new(),
   1917                 &mut None,
   1918                 &mut Vec::new()
   1919             )
   1920             .get_round()
   1921             .unwrap()
   1922                 == Some(Ratio::from_integer(BigInt::from_biguint(
   1923                     Sign::Plus,
   1924                     BigUint::new(vec![2])
   1925                 )))
   1926         );
   1927         assert!(
   1928             Evaluator::new(
   1929                 b"round(2.677, 1)",
   1930                 &mut Cache::new(),
   1931                 &mut None,
   1932                 &mut Vec::new()
   1933             )
   1934             .get_round()
   1935             .unwrap()
   1936                 == Some(Ratio::new(
   1937                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![27])),
   1938                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![10]))
   1939                 ))
   1940         );
   1941     }
   1942     #[cfg(feature = "rand")]
   1943     #[test]
   1944     fn rand() {
   1945         assert!(match Evaluator::new(
   1946             b"rand(1",
   1947             &mut Cache::new(),
   1948             &mut None,
   1949             &mut Vec::new(),
   1950             &mut rand::thread_rng()
   1951         )
   1952         .get_rand()
   1953         .unwrap_err()
   1954         {
   1955             LangErr::InvalidRand(i) => i == 6,
   1956             _ => false,
   1957         });
   1958         assert!(match Evaluator::new(
   1959             b"rand(1,2",
   1960             &mut Cache::new(),
   1961             &mut None,
   1962             &mut Vec::new(),
   1963             &mut rand::thread_rng()
   1964         )
   1965         .get_rand()
   1966         .unwrap_err()
   1967         {
   1968             LangErr::InvalidRand(i) => i == 8,
   1969             _ => false,
   1970         });
   1971         assert!(match Evaluator::new(
   1972             b"rand(1/2,3/4)",
   1973             &mut Cache::new(),
   1974             &mut None,
   1975             &mut Vec::new(),
   1976             &mut rand::thread_rng(),
   1977         )
   1978         .get_rand()
   1979         .unwrap_err()
   1980         {
   1981             LangErr::RandNoInts(i) => i == 13,
   1982             _ => false,
   1983         });
   1984         assert!(match Evaluator::new(
   1985             b"rand(-100000000000000000000000,-1000000000000000000000)",
   1986             &mut Cache::new(),
   1987             &mut None,
   1988             &mut Vec::new(),
   1989             &mut rand::thread_rng(),
   1990         )
   1991         .get_rand()
   1992         .unwrap_err()
   1993         {
   1994             LangErr::RandNoInts(i) => i == 55,
   1995             _ => false,
   1996         });
   1997         assert!(match Evaluator::new(
   1998             b"rand(2/3,1/3)",
   1999             &mut Cache::new(),
   2000             &mut None,
   2001             &mut Vec::new(),
   2002             &mut rand::thread_rng(),
   2003         )
   2004         .get_rand()
   2005         .unwrap_err()
   2006         {
   2007             LangErr::RandInvalidArgs(i) => i == 13,
   2008             _ => false,
   2009         });
   2010         // If the input does not start with 'rand(', then it's invalid since get_rand must only be called as the last terminal expression which means whitespace must be consumed already.
   2011         assert!(match Evaluator::new(
   2012             b" rand(2/3,2)",
   2013             &mut Cache::new(),
   2014             &mut None,
   2015             &mut Vec::new(),
   2016             &mut rand::thread_rng(),
   2017         )
   2018         .get_rand()
   2019         .unwrap_err()
   2020         {
   2021             MissingTerm(i) => i == 0,
   2022             _ => false,
   2023         });
   2024         assert!(Evaluator::new(
   2025             b"rand(2, 7)",
   2026             &mut Cache::new(),
   2027             &mut None,
   2028             &mut Vec::new(),
   2029             &mut rand::thread_rng()
   2030         )
   2031         .get_rand()
   2032         .map(|r| {
   2033             let int = r.numer();
   2034             int >= &BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2]))
   2035                 && *int <= BigInt::from_biguint(Sign::Plus, BigUint::new(vec![7]))
   2036         })
   2037         .unwrap());
   2038         assert!(Evaluator::new(
   2039             b"rand()",
   2040             &mut Cache::new(),
   2041             &mut None,
   2042             &mut Vec::new(),
   2043             &mut rand::thread_rng()
   2044         )
   2045         .get_rand()
   2046         .map(|r| {
   2047             let int = r.numer();
   2048             int >= &BigInt::from(i64::MIN) && *int <= BigInt::from(i64::MAX)
   2049         })
   2050         .unwrap());
   2051         for _ in 0..100 {
   2052             assert!(Evaluator::new(
   2053                 b"rand(2, 2)",
   2054                 &mut Cache::new(),
   2055                 &mut None,
   2056                 &mut Vec::new(),
   2057                 &mut rand::thread_rng()
   2058             )
   2059             .get_rand()
   2060             .map(|r| *r.numer() == BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2])))
   2061             .unwrap());
   2062         }
   2063     }
   2064     #[cfg(feature = "rand")]
   2065     #[test]
   2066     #[ignore]
   2067     fn rand_uni() {
   2068         // Test rand on an interval that is not a power of 2 in size.
   2069         // This causes rand to adjust the interval to enforce uniformity.
   2070         let mut vals = [0u32; 3];
   2071         let mut vec = Vec::new();
   2072         let mut cache = Cache::new();
   2073         let mut none = None;
   2074         const COUNT: u32 = 999999;
   2075         for _ in 1..COUNT {
   2076             vals[(Evaluator::new(
   2077                 b"rand(-1, 1)",
   2078                 &mut cache,
   2079                 &mut none,
   2080                 &mut vec,
   2081                 &mut rand::thread_rng(),
   2082             )
   2083             .get_rand()
   2084             .unwrap()
   2085             .numer()
   2086             .to_i32()
   2087             .unwrap()
   2088                 + 1) as usize] += 1;
   2089         }
   2090         // Test that the distribution is within 1% of what is expected.
   2091         assert!(vals
   2092             .into_iter()
   2093             .try_fold(false, |_, r| {
   2094                 if r < COUNT * 33 / 100 || r > COUNT * 101 / 300 {
   2095                     Err(false)
   2096                 } else {
   2097                     Ok(true)
   2098                 }
   2099             })
   2100             .unwrap());
   2101     }
   2102     #[test]
   2103     fn term() {
   2104         #[cfg(not(feature = "rand"))]
   2105         assert!(
   2106             Evaluator::new(b"0000.00000", &mut Cache::new(), &mut None, &mut Vec::new())
   2107                 .get_term()
   2108                 .unwrap()
   2109                 == Ratio::from_integer(BigInt::from_biguint(
   2110                     Sign::NoSign,
   2111                     BigUint::new(Vec::new())
   2112                 ))
   2113         );
   2114         #[cfg(not(feature = "rand"))]
   2115         assert!(
   2116             Evaluator::new(b"(4)", &mut Cache::new(), &mut None, &mut Vec::new())
   2117                 .get_term()
   2118                 .unwrap()
   2119                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![4])))
   2120         );
   2121         #[cfg(not(feature = "rand"))]
   2122         assert!(
   2123             Evaluator::new(
   2124                 b"round(-2/3,2)",
   2125                 &mut Cache::new(),
   2126                 &mut None,
   2127                 &mut Vec::new()
   2128             )
   2129             .get_term()
   2130             .unwrap()
   2131                 == Ratio::new(
   2132                     BigInt::from_biguint(Sign::Minus, BigUint::new(vec![67])),
   2133                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![100]))
   2134                 )
   2135         );
   2136         #[cfg(feature = "rand")]
   2137         assert!(Evaluator::new(
   2138             b"rand()",
   2139             &mut Cache::new(),
   2140             &mut None,
   2141             &mut Vec::new(),
   2142             &mut rand::thread_rng()
   2143         )
   2144         .get_term()
   2145         .is_ok());
   2146         #[cfg(feature = "rand")]
   2147         assert!(Evaluator::new(
   2148             b"rand(-13/93, 833)",
   2149             &mut Cache::new(),
   2150             &mut None,
   2151             &mut Vec::new(),
   2152             &mut rand::thread_rng(),
   2153         )
   2154         .get_term()
   2155         .is_ok());
   2156         #[cfg(not(feature = "rand"))]
   2157         assert!(
   2158             match Evaluator::new(b"rand()", &mut Cache::new(), &mut None, &mut Vec::new())
   2159                 .get_term()
   2160                 .unwrap_err()
   2161             {
   2162                 MissingTerm(i) => i == 0,
   2163                 _ => false,
   2164             }
   2165         );
   2166         #[cfg(not(feature = "rand"))]
   2167         assert!(
   2168             Evaluator::new(b"|4|", &mut Cache::new(), &mut None, &mut Vec::new())
   2169                 .get_term()
   2170                 .unwrap()
   2171                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![4])))
   2172         );
   2173         // Terminal expressions do no clean up before or after.
   2174         #[cfg(not(feature = "rand"))]
   2175         assert!(
   2176             match Evaluator::new(b" 2", &mut Cache::new(), &mut None, &mut Vec::new())
   2177                 .get_term()
   2178                 .unwrap_err()
   2179             {
   2180                 MissingTerm(i) => i == 0,
   2181                 _ => false,
   2182             }
   2183         );
   2184         #[cfg(not(feature = "rand"))]
   2185         let mut prev = None;
   2186         #[cfg(not(feature = "rand"))]
   2187         let mut cache = Cache::new();
   2188         #[cfg(not(feature = "rand"))]
   2189         Evaluator::new(b"1\n", &mut cache, &mut prev, &mut Vec::new())
   2190             .evaluate()
   2191             .unwrap();
   2192         #[cfg(not(feature = "rand"))]
   2193         Evaluator::new(b"s\n", &mut cache, &mut prev, &mut Vec::new())
   2194             .evaluate()
   2195             .unwrap();
   2196         #[cfg(not(feature = "rand"))]
   2197         assert!(
   2198             Evaluator::new(b"@", &mut cache, &mut prev, &mut Vec::new())
   2199                 .get_term()
   2200                 .unwrap()
   2201                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2202         );
   2203     }
   2204     #[cfg(not(feature = "rand"))]
   2205     #[test]
   2206     fn factorial() {
   2207         // Negative integer is not allowed.
   2208         assert!(
   2209             match Evaluator::new(b"(-1)!", &mut Cache::new(), &mut None, &mut Vec::new())
   2210                 .get_fact()
   2211                 .unwrap_err()
   2212             {
   2213                 NotNonNegIntFact(i) => i == 5,
   2214                 _ => false,
   2215             }
   2216         );
   2217         // Non-integer is not allowed.
   2218         assert!(
   2219             match Evaluator::new(b"2.5!", &mut Cache::new(), &mut None, &mut Vec::new())
   2220                 .get_fact()
   2221                 .unwrap_err()
   2222             {
   2223                 NotNonNegIntFact(i) => i == 4,
   2224                 _ => false,
   2225             }
   2226         );
   2227         // factorials always become terminal expressions eventually.
   2228         assert!(
   2229             Evaluator::new(b"7", &mut Cache::new(), &mut None, &mut Vec::new())
   2230                 .get_fact()
   2231                 .unwrap()
   2232                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![7])))
   2233         );
   2234         assert!(
   2235             Evaluator::new(b"(7)", &mut Cache::new(), &mut None, &mut Vec::new())
   2236                 .get_fact()
   2237                 .unwrap()
   2238                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![7])))
   2239         );
   2240         assert!(
   2241             Evaluator::new(b"|7|", &mut Cache::new(), &mut None, &mut Vec::new())
   2242                 .get_fact()
   2243                 .unwrap()
   2244                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![7])))
   2245         );
   2246         let mut prev = None;
   2247         let mut cache = Cache::new();
   2248         Evaluator::new(b"3\n", &mut cache, &mut prev, &mut Vec::new())
   2249             .evaluate()
   2250             .unwrap();
   2251         Evaluator::new(b"s\n", &mut cache, &mut prev, &mut Vec::new())
   2252             .evaluate()
   2253             .unwrap();
   2254         assert!(
   2255             Evaluator::new(b"@!", &mut cache, &mut prev, &mut Vec::new())
   2256                 .get_fact()
   2257                 .unwrap()
   2258                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![6])))
   2259         );
   2260         assert!(
   2261             Evaluator::new(b"@", &mut cache, &mut prev, &mut Vec::new())
   2262                 .get_fact()
   2263                 .unwrap()
   2264                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![3])))
   2265         );
   2266         // 0! = 1.
   2267         assert!(
   2268             Evaluator::new(b"0.0!", &mut Cache::new(), &mut None, &mut Vec::new())
   2269                 .get_fact()
   2270                 .unwrap()
   2271                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2272         );
   2273         // 1! = 1.
   2274         assert!(
   2275             Evaluator::new(b"1!", &mut Cache::new(), &mut None, &mut Vec::new())
   2276                 .get_fact()
   2277                 .unwrap()
   2278                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2279         );
   2280         // 4! = 24, and whitespace is not consumed.
   2281         assert!(
   2282             Evaluator::new(b"4! \t", &mut Cache::new(), &mut None, &mut Vec::new())
   2283                 .get_fact()
   2284                 .unwrap()
   2285                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![24])))
   2286         );
   2287         // Factorials can be chained.
   2288         assert!(
   2289             Evaluator::new(b"3!! ", &mut Cache::new(), &mut None, &mut Vec::new())
   2290                 .get_fact()
   2291                 .unwrap()
   2292                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![720])))
   2293         );
   2294         // only factorial is consumed.
   2295         assert!(
   2296             Evaluator::new(b"2!+3", &mut Cache::new(), &mut None, &mut Vec::new())
   2297                 .get_fact()
   2298                 .unwrap()
   2299                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2])))
   2300         );
   2301         // Error since leading/trailing whitespace is not consumed by factorial or higher precedence expressions.
   2302         assert!(
   2303             match Evaluator::new(b" 2!", &mut Cache::new(), &mut None, &mut Vec::new())
   2304                 .get_fact()
   2305                 .unwrap_err()
   2306             {
   2307                 MissingTerm(i) => i == 0,
   2308                 _ => false,
   2309             }
   2310         );
   2311         assert!(
   2312             match Evaluator::new(b"\t2!", &mut Cache::new(), &mut None, &mut Vec::new())
   2313                 .get_fact()
   2314                 .unwrap_err()
   2315             {
   2316                 MissingTerm(i) => i == 0,
   2317                 _ => false,
   2318             }
   2319         );
   2320         // Error since negation is not consumed by factorial or higher precedence expressions.
   2321         assert!(
   2322             match Evaluator::new(b"-2!", &mut Cache::new(), &mut None, &mut Vec::new())
   2323                 .get_fact()
   2324                 .unwrap_err()
   2325             {
   2326                 MissingTerm(i) => i == 0,
   2327                 _ => false,
   2328             }
   2329         );
   2330     }
   2331     #[cfg(not(feature = "rand"))]
   2332     #[test]
   2333     fn exp() {
   2334         // 1 can be raised to anything and return 1.
   2335         // Also white space is ignored between operator.
   2336         assert!(
   2337             Evaluator::new(b"1  ^\t  0", &mut Cache::new(), &mut None, &mut Vec::new())
   2338                 .get_exps()
   2339                 .unwrap()
   2340                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2341         );
   2342         assert!(
   2343             Evaluator::new(b"1^0.5", &mut Cache::new(), &mut None, &mut Vec::new())
   2344                 .get_exps()
   2345                 .unwrap()
   2346                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2347         );
   2348         assert!(
   2349             Evaluator::new(b"1^(-1/2)", &mut Cache::new(), &mut None, &mut Vec::new())
   2350                 .get_exps()
   2351                 .unwrap()
   2352                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2353         );
   2354         assert!(
   2355             Evaluator::new(b"1.0^(-2)", &mut Cache::new(), &mut None, &mut Vec::new())
   2356                 .get_exps()
   2357                 .unwrap()
   2358                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2359         );
   2360         // 0 can be raised to any non-negative value and will always return 0 unless raised to 0 which will return 1.
   2361         assert!(
   2362             Evaluator::new(b"0^0", &mut Cache::new(), &mut None, &mut Vec::new())
   2363                 .get_exps()
   2364                 .unwrap()
   2365                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2366         );
   2367         assert!(
   2368             Evaluator::new(b"0^1", &mut Cache::new(), &mut None, &mut Vec::new())
   2369                 .get_exps()
   2370                 .unwrap()
   2371                 == Ratio::from_integer(BigInt::from_biguint(Sign::NoSign, BigUint::new(vec![0])))
   2372         );
   2373         assert!(
   2374             Evaluator::new(b"0^0.5", &mut Cache::new(), &mut None, &mut Vec::new())
   2375                 .get_exps()
   2376                 .unwrap()
   2377                 == Ratio::from_integer(BigInt::from_biguint(Sign::NoSign, BigUint::new(vec![0])))
   2378         );
   2379         // Anything else can only be raised to integers.
   2380         assert!(
   2381             Evaluator::new(b"4^0", &mut Cache::new(), &mut None, &mut Vec::new())
   2382                 .get_exps()
   2383                 .unwrap()
   2384                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2385         );
   2386         assert!(
   2387             Evaluator::new(b"4^1", &mut Cache::new(), &mut None, &mut Vec::new())
   2388                 .get_exps()
   2389                 .unwrap()
   2390                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![4])))
   2391         );
   2392         assert!(
   2393             Evaluator::new(b"4^(-2)", &mut Cache::new(), &mut None, &mut Vec::new())
   2394                 .get_exps()
   2395                 .unwrap()
   2396                 == Ratio::new(
   2397                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])),
   2398                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![16]))
   2399                 )
   2400         );
   2401         assert!(
   2402             Evaluator::new(b"(-4)^0", &mut Cache::new(), &mut None, &mut Vec::new())
   2403                 .get_exps()
   2404                 .unwrap()
   2405                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2406         );
   2407         assert!(
   2408             Evaluator::new(b"(-4)^1", &mut Cache::new(), &mut None, &mut Vec::new())
   2409                 .get_exps()
   2410                 .unwrap()
   2411                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![4])))
   2412         );
   2413         assert!(
   2414             Evaluator::new(b"(-4)^2", &mut Cache::new(), &mut None, &mut Vec::new())
   2415                 .get_exps()
   2416                 .unwrap()
   2417                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![16])))
   2418         );
   2419         assert!(
   2420             Evaluator::new(b"(-4)^(-2)", &mut Cache::new(), &mut None, &mut Vec::new())
   2421                 .get_exps()
   2422                 .unwrap()
   2423                 == Ratio::new(
   2424                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])),
   2425                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![16]))
   2426                 )
   2427         );
   2428         assert!(
   2429             Evaluator::new(b"(-4)^(-3)", &mut Cache::new(), &mut None, &mut Vec::new())
   2430                 .get_exps()
   2431                 .unwrap()
   2432                 == Ratio::new(
   2433                     BigInt::from_biguint(Sign::Minus, BigUint::new(vec![1])),
   2434                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![64]))
   2435                 )
   2436         );
   2437         assert!(
   2438             Evaluator::new(b"(2/3)^0", &mut Cache::new(), &mut None, &mut Vec::new())
   2439                 .get_exps()
   2440                 .unwrap()
   2441                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2442         );
   2443         assert!(
   2444             Evaluator::new(b"(2/3)^(2)", &mut Cache::new(), &mut None, &mut Vec::new())
   2445                 .get_exps()
   2446                 .unwrap()
   2447                 == Ratio::new(
   2448                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![4])),
   2449                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![9]))
   2450                 )
   2451         );
   2452         assert!(
   2453             Evaluator::new(b"(2/3)^(-3)", &mut Cache::new(), &mut None, &mut Vec::new())
   2454                 .get_exps()
   2455                 .unwrap()
   2456                 == Ratio::new(
   2457                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![27])),
   2458                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![8]))
   2459                 )
   2460         );
   2461         assert!(
   2462             Evaluator::new(b"(-2/3)^0", &mut Cache::new(), &mut None, &mut Vec::new())
   2463                 .get_exps()
   2464                 .unwrap()
   2465                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2466         );
   2467         assert!(
   2468             Evaluator::new(b"(-2/3)^(2)", &mut Cache::new(), &mut None, &mut Vec::new())
   2469                 .get_exps()
   2470                 .unwrap()
   2471                 == Ratio::new(
   2472                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![4])),
   2473                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![9]))
   2474                 )
   2475         );
   2476         assert!(
   2477             Evaluator::new(b"(-2/3)^(3)", &mut Cache::new(), &mut None, &mut Vec::new())
   2478                 .get_exps()
   2479                 .unwrap()
   2480                 == Ratio::new(
   2481                     BigInt::from_biguint(Sign::Minus, BigUint::new(vec![8])),
   2482                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![27]))
   2483                 )
   2484         );
   2485         assert!(
   2486             Evaluator::new(
   2487                 b"(-2/3)^(-2)",
   2488                 &mut Cache::new(),
   2489                 &mut None,
   2490                 &mut Vec::new()
   2491             )
   2492             .get_exps()
   2493             .unwrap()
   2494                 == Ratio::new(
   2495                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![9])),
   2496                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![4]))
   2497                 )
   2498         );
   2499         assert!(
   2500             Evaluator::new(
   2501                 b"(-2/3)^(-3)",
   2502                 &mut Cache::new(),
   2503                 &mut None,
   2504                 &mut Vec::new()
   2505             )
   2506             .get_exps()
   2507             .unwrap()
   2508                 == Ratio::new(
   2509                     BigInt::from_biguint(Sign::Minus, BigUint::new(vec![27])),
   2510                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![8]))
   2511                 )
   2512         );
   2513         assert!(
   2514             Evaluator::new(
   2515                 b"(4/9)^(-1/2)",
   2516                 &mut Cache::new(),
   2517                 &mut None,
   2518                 &mut Vec::new()
   2519             )
   2520             .get_exps()
   2521             .unwrap()
   2522                 == Ratio::new(
   2523                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![3])),
   2524                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2]))
   2525                 )
   2526         );
   2527         // Error since 0 cannot be raised to a negative power.
   2528         assert!(
   2529             match Evaluator::new(b"0^(-1)", &mut Cache::new(), &mut None, &mut Vec::new())
   2530                 .get_exps()
   2531                 .unwrap_err()
   2532             {
   2533                 ExpDivByZero(i) => i == 6,
   2534                 _ => false,
   2535             }
   2536         );
   2537         // Error since anything other than 0 or 1 cannot be raised to a non-integer power or (+/-) 1/2.
   2538         assert!(
   2539             match Evaluator::new(b"2^(1/3)", &mut Cache::new(), &mut None, &mut Vec::new())
   2540                 .get_exps()
   2541                 .unwrap_err()
   2542             {
   2543                 ExpIsNotIntOrOneHalf(i) => i == 7,
   2544                 _ => false,
   2545             }
   2546         );
   2547         // When exponent is (+/-) 1/2, base has to be the square of a rational number.
   2548         assert!(
   2549             match Evaluator::new(b"2^(1/2)", &mut Cache::new(), &mut None, &mut Vec::new())
   2550                 .get_exps()
   2551                 .unwrap_err()
   2552             {
   2553                 SqrtDoesNotExist(i) => i == 7,
   2554                 _ => false,
   2555             }
   2556         );
   2557         // exps always become factorials eventually.
   2558         assert!(
   2559             Evaluator::new(b"3!", &mut Cache::new(), &mut None, &mut Vec::new())
   2560                 .get_exps()
   2561                 .unwrap()
   2562                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![6])))
   2563         );
   2564         // exponentiation has lower precedence than factorials.
   2565         assert!(
   2566             Evaluator::new(b"2^3!", &mut Cache::new(), &mut None, &mut Vec::new())
   2567                 .get_exps()
   2568                 .unwrap()
   2569                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![64])))
   2570         );
   2571         assert!(
   2572             Evaluator::new(b"3!^2", &mut Cache::new(), &mut None, &mut Vec::new())
   2573                 .get_exps()
   2574                 .unwrap()
   2575                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![36])))
   2576         );
   2577         // Error since leading/trailing whitespace is not consumed by exponentiation or higher precedence expressions.
   2578         assert!(
   2579             match Evaluator::new(b" 2^2", &mut Cache::new(), &mut None, &mut Vec::new())
   2580                 .get_exps()
   2581                 .unwrap_err()
   2582             {
   2583                 MissingTerm(i) => i == 0,
   2584                 _ => false,
   2585             }
   2586         );
   2587         assert!(
   2588             match Evaluator::new(b"\t2^2", &mut Cache::new(), &mut None, &mut Vec::new())
   2589                 .get_exps()
   2590                 .unwrap_err()
   2591             {
   2592                 MissingTerm(i) => i == 0,
   2593                 _ => false,
   2594             }
   2595         );
   2596     }
   2597     #[cfg(not(feature = "rand"))]
   2598     #[test]
   2599     fn neg() {
   2600         assert!(
   2601             Evaluator::new(b"-1", &mut Cache::new(), &mut None, &mut Vec::new())
   2602                 .get_neg()
   2603                 .unwrap()
   2604                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![1])))
   2605         );
   2606         assert!(
   2607             Evaluator::new(b"- \t  -  1", &mut Cache::new(), &mut None, &mut Vec::new())
   2608                 .get_neg()
   2609                 .unwrap()
   2610                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2611         );
   2612         assert!(
   2613             Evaluator::new(b"-0", &mut Cache::new(), &mut None, &mut Vec::new())
   2614                 .get_neg()
   2615                 .unwrap()
   2616                 == Ratio::from_integer(BigInt::from_biguint(
   2617                     Sign::NoSign,
   2618                     BigUint::new(Vec::new())
   2619                 ))
   2620         );
   2621         // negation has lower precedence than exponentiation.
   2622         assert!(
   2623             Evaluator::new(b"-2^2", &mut Cache::new(), &mut None, &mut Vec::new())
   2624                 .get_neg()
   2625                 .unwrap()
   2626                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![4])))
   2627         );
   2628         // negation always becomes exponentiation eventually.
   2629         assert!(
   2630             Evaluator::new(b"2.0^2.0", &mut Cache::new(), &mut None, &mut Vec::new())
   2631                 .get_neg()
   2632                 .unwrap()
   2633                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![4])))
   2634         );
   2635         // Error since leading/trailing whitespace is not consumed by exponentiation or higher precedence expressions.
   2636         assert!(
   2637             match Evaluator::new(b" -2", &mut Cache::new(), &mut None, &mut Vec::new())
   2638                 .get_neg()
   2639                 .unwrap_err()
   2640             {
   2641                 MissingTerm(i) => i == 0,
   2642                 _ => false,
   2643             }
   2644         );
   2645         assert!(
   2646             match Evaluator::new(b"\t-2", &mut Cache::new(), &mut None, &mut Vec::new())
   2647                 .get_neg()
   2648                 .unwrap_err()
   2649             {
   2650                 MissingTerm(i) => i == 0,
   2651                 _ => false,
   2652             }
   2653         );
   2654     }
   2655     #[cfg(not(feature = "rand"))]
   2656     #[test]
   2657     fn mult() {
   2658         assert!(
   2659             Evaluator::new(b"2  *   3", &mut Cache::new(), &mut None, &mut Vec::new())
   2660                 .get_mults()
   2661                 .unwrap()
   2662                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![6])))
   2663         );
   2664         assert!(
   2665             Evaluator::new(
   2666                 b"-2  * \t  3",
   2667                 &mut Cache::new(),
   2668                 &mut None,
   2669                 &mut Vec::new()
   2670             )
   2671             .get_mults()
   2672             .unwrap()
   2673                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![6])))
   2674         );
   2675         assert!(
   2676             Evaluator::new(
   2677                 b"2\t  *   -3.0",
   2678                 &mut Cache::new(),
   2679                 &mut None,
   2680                 &mut Vec::new()
   2681             )
   2682             .get_mults()
   2683             .unwrap()
   2684                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![6])))
   2685         );
   2686         assert!(
   2687             Evaluator::new(b"-2.5*-3.5", &mut Cache::new(), &mut None, &mut Vec::new())
   2688                 .get_mults()
   2689                 .unwrap()
   2690                 == Ratio::new(
   2691                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![35])),
   2692                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![4]))
   2693                 )
   2694         );
   2695         assert!(
   2696             Evaluator::new(b"4.0\t /  6", &mut Cache::new(), &mut None, &mut Vec::new())
   2697                 .get_mults()
   2698                 .unwrap()
   2699                 == Ratio::new(
   2700                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2])),
   2701                     BigInt::from_biguint(Sign::Plus, BigUint::new(vec![3]))
   2702                 )
   2703         );
   2704         assert!(
   2705             Evaluator::new(b"6/3", &mut Cache::new(), &mut None, &mut Vec::new())
   2706                 .get_mults()
   2707                 .unwrap()
   2708                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2])))
   2709         );
   2710         assert!(
   2711             Evaluator::new(b"-6/3", &mut Cache::new(), &mut None, &mut Vec::new())
   2712                 .get_mults()
   2713                 .unwrap()
   2714                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![2])))
   2715         );
   2716         assert!(
   2717             Evaluator::new(b"6/-3", &mut Cache::new(), &mut None, &mut Vec::new())
   2718                 .get_mults()
   2719                 .unwrap()
   2720                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![2])))
   2721         );
   2722         assert!(
   2723             Evaluator::new(
   2724                 b"-  6 /\t -  3",
   2725                 &mut Cache::new(),
   2726                 &mut None,
   2727                 &mut Vec::new()
   2728             )
   2729             .get_mults()
   2730             .unwrap()
   2731                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2])))
   2732         );
   2733         // Number literals are not strictly equivalent to "ratios" as "ratios" don't exist (i.e., 2/3 is not the ratio of 2 to 3 but is the rational number two divided by the rational number 3).
   2734         assert!(
   2735             Evaluator::new(b"1/1.5", &mut Cache::new(), &mut None, &mut Vec::new())
   2736                 .get_mults()
   2737                 .unwrap()
   2738                 != Evaluator::new(b"1/3/2", &mut Cache::new(), &mut None, &mut Vec::new())
   2739                     .get_mults()
   2740                     .unwrap()
   2741         );
   2742         assert!(
   2743             Evaluator::new(b"1/1.5", &mut Cache::new(), &mut None, &mut Vec::new())
   2744                 .get_mults()
   2745                 .unwrap()
   2746                 == Evaluator::new(b"1/(3/2)", &mut Cache::new(), &mut None, &mut Vec::new())
   2747                     .get_mults()
   2748                     .unwrap()
   2749         );
   2750         // multiplication always becomes negation eventually.
   2751         assert!(
   2752             Evaluator::new(b"-2.0", &mut Cache::new(), &mut None, &mut Vec::new())
   2753                 .get_mults()
   2754                 .unwrap()
   2755                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![2])))
   2756         );
   2757         // Error since leading/trailing whitespace is not consumed by multiplication or higher precedence expressions.
   2758         assert!(
   2759             match Evaluator::new(b" 2*2", &mut Cache::new(), &mut None, &mut Vec::new())
   2760                 .get_mults()
   2761                 .unwrap_err()
   2762             {
   2763                 MissingTerm(i) => i == 0,
   2764                 _ => false,
   2765             }
   2766         );
   2767         assert!(
   2768             match Evaluator::new(b"\t2/2", &mut Cache::new(), &mut None, &mut Vec::new())
   2769                 .get_mults()
   2770                 .unwrap_err()
   2771             {
   2772                 MissingTerm(i) => i == 0,
   2773                 _ => false,
   2774             }
   2775         );
   2776         assert!(
   2777             Evaluator::new(
   2778                 b"4.0\t mod  6",
   2779                 &mut Cache::new(),
   2780                 &mut None,
   2781                 &mut Vec::new()
   2782             )
   2783             .get_mults()
   2784             .unwrap()
   2785                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![4])),)
   2786         );
   2787         assert!(
   2788             Evaluator::new(b"5 mod 3", &mut Cache::new(), &mut None, &mut Vec::new())
   2789                 .get_mults()
   2790                 .unwrap()
   2791                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2])))
   2792         );
   2793         assert!(
   2794             Evaluator::new(b"-5 mod 3", &mut Cache::new(), &mut None, &mut Vec::new())
   2795                 .get_mults()
   2796                 .unwrap()
   2797                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2798         );
   2799         assert!(
   2800             Evaluator::new(b"5 mod -3", &mut Cache::new(), &mut None, &mut Vec::new())
   2801                 .get_mults()
   2802                 .unwrap()
   2803                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2])))
   2804         );
   2805         assert!(
   2806             Evaluator::new(
   2807                 b"-5   mod\t -3",
   2808                 &mut Cache::new(),
   2809                 &mut None,
   2810                 &mut Vec::new()
   2811             )
   2812             .get_mults()
   2813             .unwrap()
   2814                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2815         );
   2816         // Cannot divide by 0.
   2817         assert!(
   2818             match Evaluator::new(b"2/0", &mut Cache::new(), &mut None, &mut Vec::new())
   2819                 .get_mults()
   2820                 .unwrap_err()
   2821             {
   2822                 DivByZero(i) => i == 3,
   2823                 _ => false,
   2824             }
   2825         );
   2826         assert!(
   2827             match Evaluator::new(b"2 mod 0", &mut Cache::new(), &mut None, &mut Vec::new())
   2828                 .get_mults()
   2829                 .unwrap_err()
   2830             {
   2831                 ModZero(i) => i == 7,
   2832                 _ => false,
   2833             }
   2834         );
   2835         // Right and left operands of mod must be integers.
   2836         assert!(
   2837             match Evaluator::new(b"3.2 mod 1", &mut Cache::new(), &mut None, &mut Vec::new())
   2838                 .get_mults()
   2839                 .unwrap_err()
   2840             {
   2841                 ModIsNotInt(i) => i == 4,
   2842                 _ => false,
   2843             }
   2844         );
   2845         assert!(
   2846             match Evaluator::new(b"3 mod 3.2", &mut Cache::new(), &mut None, &mut Vec::new())
   2847                 .get_mults()
   2848                 .unwrap_err()
   2849             {
   2850                 ModIsNotInt(i) => i == 9,
   2851                 _ => false,
   2852             }
   2853         );
   2854         // multiplication has lower precedence than exponentiation.
   2855         assert!(
   2856             Evaluator::new(b"2*2^2", &mut Cache::new(), &mut None, &mut Vec::new())
   2857                 .get_mults()
   2858                 .unwrap()
   2859                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![8])))
   2860         );
   2861         assert!(
   2862             Evaluator::new(b"8/2^2", &mut Cache::new(), &mut None, &mut Vec::new())
   2863                 .get_mults()
   2864                 .unwrap()
   2865                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2])))
   2866         );
   2867         assert!(
   2868             Evaluator::new(b"8 mod 3^2", &mut Cache::new(), &mut None, &mut Vec::new())
   2869                 .get_mults()
   2870                 .unwrap()
   2871                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![8])))
   2872         );
   2873     }
   2874     #[cfg(not(feature = "rand"))]
   2875     #[test]
   2876     fn add() {
   2877         assert!(
   2878             Evaluator::new(b"2  +   3", &mut Cache::new(), &mut None, &mut Vec::new())
   2879                 .get_adds()
   2880                 .unwrap()
   2881                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![5])))
   2882         );
   2883         assert!(
   2884             Evaluator::new(b"-2  +   3", &mut Cache::new(), &mut None, &mut Vec::new())
   2885                 .get_adds()
   2886                 .unwrap()
   2887                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2888         );
   2889         assert!(
   2890             Evaluator::new(
   2891                 b"2  +  \t -3.0",
   2892                 &mut Cache::new(),
   2893                 &mut None,
   2894                 &mut Vec::new()
   2895             )
   2896             .get_adds()
   2897             .unwrap()
   2898                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![1])))
   2899         );
   2900         assert!(
   2901             Evaluator::new(b"-2.5+-3.5", &mut Cache::new(), &mut None, &mut Vec::new())
   2902                 .get_adds()
   2903                 .unwrap()
   2904                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![6])))
   2905         );
   2906         assert!(
   2907             Evaluator::new(b"4.0\t -  6", &mut Cache::new(), &mut None, &mut Vec::new())
   2908                 .get_adds()
   2909                 .unwrap()
   2910                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![2])))
   2911         );
   2912         assert!(
   2913             Evaluator::new(b"6-3", &mut Cache::new(), &mut None, &mut Vec::new())
   2914                 .get_adds()
   2915                 .unwrap()
   2916                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![3])))
   2917         );
   2918         assert!(
   2919             Evaluator::new(b"-6-3", &mut Cache::new(), &mut None, &mut Vec::new())
   2920                 .get_adds()
   2921                 .unwrap()
   2922                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![9])))
   2923         );
   2924         assert!(
   2925             Evaluator::new(b"6--3", &mut Cache::new(), &mut None, &mut Vec::new())
   2926                 .get_adds()
   2927                 .unwrap()
   2928                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![9])))
   2929         );
   2930         assert!(
   2931             Evaluator::new(
   2932                 b"-  6 -\t -  3",
   2933                 &mut Cache::new(),
   2934                 &mut None,
   2935                 &mut Vec::new()
   2936             )
   2937             .get_adds()
   2938             .unwrap()
   2939                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![3])))
   2940         );
   2941         // addition always becomes multiplication eventually.
   2942         assert!(
   2943             Evaluator::new(b"2 * 8", &mut Cache::new(), &mut None, &mut Vec::new())
   2944                 .get_adds()
   2945                 .unwrap()
   2946                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![16])))
   2947         );
   2948         assert!(
   2949             Evaluator::new(b"8 /\t 2", &mut Cache::new(), &mut None, &mut Vec::new())
   2950                 .get_adds()
   2951                 .unwrap()
   2952                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![4])))
   2953         );
   2954         // Error since leading/trailing whitespace is not consumed by addition or higher precedence expressions.
   2955         assert!(
   2956             match Evaluator::new(b" 2+2", &mut Cache::new(), &mut None, &mut Vec::new())
   2957                 .get_adds()
   2958                 .unwrap_err()
   2959             {
   2960                 MissingTerm(i) => i == 0,
   2961                 _ => false,
   2962             }
   2963         );
   2964         assert!(
   2965             match Evaluator::new(b" 2-2", &mut Cache::new(), &mut None, &mut Vec::new())
   2966                 .get_adds()
   2967                 .unwrap_err()
   2968             {
   2969                 MissingTerm(i) => i == 0,
   2970                 _ => false,
   2971             }
   2972         );
   2973         // addition has lower precedence than multiplication.
   2974         assert!(
   2975             Evaluator::new(b"2+2*2", &mut Cache::new(), &mut None, &mut Vec::new())
   2976                 .get_adds()
   2977                 .unwrap()
   2978                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![6])))
   2979         );
   2980         assert!(
   2981             Evaluator::new(b"2+2/2", &mut Cache::new(), &mut None, &mut Vec::new())
   2982                 .get_adds()
   2983                 .unwrap()
   2984                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![3])))
   2985         );
   2986         assert!(
   2987             Evaluator::new(b"2-2*2", &mut Cache::new(), &mut None, &mut Vec::new())
   2988                 .get_adds()
   2989                 .unwrap()
   2990                 == Ratio::from_integer(BigInt::from_biguint(Sign::Minus, BigUint::new(vec![2])))
   2991         );
   2992         assert!(
   2993             Evaluator::new(b"2-2/2", &mut Cache::new(), &mut None, &mut Vec::new())
   2994                 .get_adds()
   2995                 .unwrap()
   2996                 == Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1])))
   2997         );
   2998     }
   2999     #[cfg(not(feature = "rand"))]
   3000     #[test]
   3001     fn exit() {
   3002         assert!(
   3003             match Evaluator::new(b"  q    \n", &mut Cache::new(), &mut None, &mut Vec::new())
   3004                 .evaluate()
   3005                 .unwrap()
   3006             {
   3007                 O::Exit => true,
   3008                 _ => false,
   3009             }
   3010         );
   3011         assert!(match Evaluator::new(
   3012             b"  q    \r\n",
   3013             &mut Cache::new(),
   3014             &mut None,
   3015             &mut Vec::new()
   3016         )
   3017         .evaluate()
   3018         .unwrap()
   3019         {
   3020             O::Exit => true,
   3021             _ => false,
   3022         });
   3023         assert!(
   3024             match Evaluator::new(b"q\n", &mut Cache::new(), &mut None, &mut Vec::new())
   3025                 .evaluate()
   3026                 .unwrap()
   3027             {
   3028                 O::Exit => true,
   3029                 _ => false,
   3030             }
   3031         );
   3032         assert!(
   3033             match Evaluator::new(b"q\r\n", &mut Cache::new(), &mut None, &mut Vec::new())
   3034                 .evaluate()
   3035                 .unwrap()
   3036             {
   3037                 O::Exit => true,
   3038                 _ => false,
   3039             }
   3040         );
   3041         assert!(
   3042             match Evaluator::new(b"\rq\n", &mut Cache::new(), &mut None, &mut Vec::new())
   3043                 .evaluate()
   3044                 .unwrap_err()
   3045             {
   3046                 MissingTerm(i) => i == 0,
   3047                 _ => false,
   3048             }
   3049         );
   3050         assert!(
   3051             match Evaluator::new(b"\tq\n", &mut Cache::new(), &mut None, &mut Vec::new())
   3052                 .evaluate()
   3053                 .unwrap()
   3054             {
   3055                 O::Exit => true,
   3056                 _ => false,
   3057             }
   3058         );
   3059         assert!(
   3060             match Evaluator::new(b"q\n\n", &mut Cache::new(), &mut None, &mut Vec::new())
   3061                 .evaluate()
   3062                 .unwrap_err()
   3063             {
   3064                 InvalidQuit => true,
   3065                 _ => false,
   3066             }
   3067         );
   3068         assert!(
   3069             match Evaluator::new(b"\nq\n", &mut Cache::new(), &mut None, &mut Vec::new())
   3070                 .evaluate()
   3071                 .unwrap_err()
   3072             {
   3073                 MissingTerm(i) => i == 0,
   3074                 _ => false,
   3075             }
   3076         );
   3077         assert!(
   3078             match Evaluator::new(b"q", &mut Cache::new(), &mut None, &mut Vec::new())
   3079                 .evaluate()
   3080                 .unwrap()
   3081             {
   3082                 O::Exit => true,
   3083                 _ => false,
   3084             }
   3085         );
   3086     }
   3087     #[cfg(not(feature = "rand"))]
   3088     #[test]
   3089     fn store() {
   3090         let mut prev = None;
   3091         let mut cache = Cache::new();
   3092         Evaluator::new(b"1\n", &mut cache, &mut prev, &mut Vec::new())
   3093             .evaluate()
   3094             .unwrap();
   3095         assert!(cache.is_empty());
   3096         assert!(
   3097             match Evaluator::new(b"s\n", &mut cache, &mut prev, &mut Vec::new())
   3098                 .evaluate()
   3099                 .unwrap()
   3100             {
   3101                 O::Store(o) =>
   3102                     o.as_ref().unwrap()
   3103                         == &Ratio::from_integer(BigInt::from_biguint(
   3104                             Sign::Plus,
   3105                             BigUint::new(vec![1])
   3106                         )),
   3107                 _ => false,
   3108             }
   3109         );
   3110         assert!(cache.len() == 1);
   3111     }
   3112     #[cfg(not(feature = "rand"))]
   3113     #[test]
   3114     fn eval() {
   3115         use core::str::FromStr;
   3116         let mut prev = None;
   3117         let mut cache = Cache::new();
   3118         let mut exp = Vec::new();
   3119         assert!(
   3120             match Evaluator::new(b"1+2\n", &mut cache, &mut prev, &mut exp)
   3121                 .evaluate()
   3122                 .unwrap()
   3123             {
   3124                 O::Eval(i) =>
   3125                     i == &Ratio::from_integer(BigInt::from_biguint(
   3126                         Sign::Plus,
   3127                         BigUint::new(vec![3])
   3128                     )),
   3129                 _ => false,
   3130             }
   3131         );
   3132         assert!(
   3133             match Evaluator::new(b"\t  s  \n", &mut cache, &mut prev, &mut exp)
   3134                 .evaluate()
   3135                 .unwrap()
   3136             {
   3137                 O::Store(o) =>
   3138                     o.as_ref().unwrap()
   3139                         == &Ratio::from_integer(BigInt::from_biguint(
   3140                             Sign::Plus,
   3141                             BigUint::new(vec![3])
   3142                         )),
   3143                 _ => false,
   3144             }
   3145         );
   3146         assert!(
   3147             match Evaluator::new(b"-1/2+2*@\n", &mut cache, &mut prev, &mut exp)
   3148                 .evaluate()
   3149                 .unwrap()
   3150             {
   3151                 O::Eval(i) =>
   3152                     i == &Ratio::new(
   3153                         BigInt::from_biguint(Sign::Plus, BigUint::new(vec![11])),
   3154                         BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2]))
   3155                     ),
   3156                 _ => false,
   3157             }
   3158         );
   3159         assert!(
   3160             match Evaluator::new(b"s\n", &mut cache, &mut prev, &mut exp)
   3161                 .evaluate()
   3162                 .unwrap()
   3163             {
   3164                 O::Store(o) =>
   3165                     o == &Some(Ratio::new(
   3166                         BigInt::from_biguint(Sign::Plus, BigUint::new(vec![11])),
   3167                         BigInt::from_biguint(Sign::Plus, BigUint::new(vec![2]))
   3168                     )),
   3169                 _ => false,
   3170             }
   3171         );
   3172         assert!(
   3173             match Evaluator::new(b"@^@2!\r\n", &mut cache, &mut prev, &mut exp)
   3174                 .evaluate()
   3175                 .unwrap()
   3176             {
   3177                 O::Eval(i) =>
   3178                     i == &Ratio::new(
   3179                         BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1771561])),
   3180                         BigInt::from_biguint(Sign::Plus, BigUint::new(vec![64]))
   3181                     ),
   3182                 _ => false,
   3183             }
   3184         );
   3185         assert!(
   3186             match Evaluator::new(b"s\n", &mut cache, &mut prev, &mut exp)
   3187                 .evaluate()
   3188                 .unwrap()
   3189             {
   3190                 O::Store(o) =>
   3191                     o == &Some(Ratio::new(
   3192                         BigInt::from_biguint(Sign::Plus, BigUint::new(vec![1771561])),
   3193                         BigInt::from_biguint(Sign::Plus, BigUint::new(vec![64]))
   3194                     )),
   3195                 _ => false,
   3196             }
   3197         );
   3198         // Verified with Wolfram Alpha.
   3199         assert!(match Evaluator::new(b" \t 1 + (2 * |(7.98\t - 12/7)|) / 4!^@3!^|1-3|\t  \n", &mut cache, &mut prev, &mut exp).evaluate().unwrap() {
   3200             O::Eval(i) => i == &Ratio::from_str("2841328814244153299237884950647090899374680152474331/2841328814244153299237884950647090899374680152473600").unwrap(),
   3201             _ => false,
   3202         });
   3203         assert!(match Evaluator::new(
   3204             b" \t round(19/6,0)!\t  \r\n",
   3205             &mut cache,
   3206             &mut prev,
   3207             &mut exp
   3208         )
   3209         .evaluate()
   3210         .unwrap()
   3211         {
   3212             O::Eval(i) =>
   3213                 i == &Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![6]))),
   3214             _ => false,
   3215         });
   3216         assert!(match Evaluator::new(
   3217             b" \t 2^round(19/6,0)!\t  \r\n",
   3218             &mut cache,
   3219             &mut prev,
   3220             &mut exp
   3221         )
   3222         .evaluate()
   3223         .unwrap()
   3224         {
   3225             O::Eval(i) =>
   3226                 i == &Ratio::from_integer(BigInt::from_biguint(Sign::Plus, BigUint::new(vec![64]))),
   3227             _ => false,
   3228         });
   3229         assert!(
   3230             match Evaluator::new(b"round(19/6,0)^2\t\n", &mut cache, &mut prev, &mut exp)
   3231                 .evaluate()
   3232                 .unwrap()
   3233             {
   3234                 O::Eval(i) =>
   3235                     i == &Ratio::from_integer(BigInt::from_biguint(
   3236                         Sign::Plus,
   3237                         BigUint::new(vec![9])
   3238                     )),
   3239                 _ => false,
   3240             }
   3241         );
   3242         // Invalid UTF-8 does not cause a panic!.
   3243         assert!(
   3244             match Evaluator::new(&[255, 255, 255, b'\n'], &mut cache, &mut prev, &mut exp)
   3245                 .evaluate()
   3246                 .unwrap_err()
   3247             {
   3248                 MissingTerm(i) => i == 0,
   3249                 _ => false,
   3250             }
   3251         );
   3252         assert!(
   3253             match Evaluator::new(&[b'2', 255, b'\n'], &mut cache, &mut prev, &mut exp)
   3254                 .evaluate()
   3255                 .unwrap_err()
   3256             {
   3257                 TrailingSyms(i) => i == 1,
   3258                 _ => false,
   3259             }
   3260         );
   3261         // Exactly one newline is required.
   3262         assert!(
   3263             match Evaluator::new(b"2\n\n", &mut cache, &mut prev, &mut exp)
   3264                 .evaluate()
   3265                 .unwrap_err()
   3266             {
   3267                 TrailingSyms(i) => i == 1,
   3268                 _ => false,
   3269             }
   3270         );
   3271         assert!(
   3272             prev == Some(Ratio::from_integer(BigInt::from_biguint(
   3273                 Sign::Plus,
   3274                 BigUint::new(vec![9])
   3275             )))
   3276         );
   3277         assert!(match Evaluator::new(b"\n", &mut cache, &mut prev, &mut exp)
   3278             .evaluate()
   3279             .unwrap()
   3280         {
   3281             O::Empty(o) =>
   3282                 o == &Some(Ratio::from_integer(BigInt::from_biguint(
   3283                     Sign::Plus,
   3284                     BigUint::new(vec![9])
   3285                 ))),
   3286             _ => false,
   3287         });
   3288         assert!(
   3289             prev == Some(Ratio::from_integer(BigInt::from_biguint(
   3290                 Sign::Plus,
   3291                 BigUint::new(vec![9])
   3292             )))
   3293         );
   3294         assert!(
   3295             match Evaluator::new(b"\r\n", &mut cache, &mut prev.clone(), &mut exp)
   3296                 .evaluate()
   3297                 .unwrap()
   3298             {
   3299                 O::Empty(o) => *o == prev,
   3300                 _ => false,
   3301             }
   3302         );
   3303         assert!(
   3304             match Evaluator::new(&[0u8; 0], &mut cache, &mut prev.clone(), &mut exp)
   3305                 .evaluate()
   3306                 .unwrap()
   3307             {
   3308                 O::Empty(o) => *o == prev,
   3309                 _ => false,
   3310             }
   3311         );
   3312     }
   3313     #[cfg(feature = "rand")]
   3314     #[test]
   3315     fn eval_iter() {
   3316         use super::*;
   3317         use num_traits::ToPrimitive;
   3318         use std::io::{self, BufRead, Error, ErrorKind, Read};
   3319         struct Reader<'a> {
   3320             data: &'a [u8],
   3321             err: bool,
   3322         }
   3323         impl<'a> Reader<'a> {
   3324             fn new(data: &'a [u8]) -> Self {
   3325                 Self { data, err: true }
   3326             }
   3327         }
   3328         impl<'a> Read for Reader<'a> {
   3329             fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
   3330                 if self.err {
   3331                     self.err = false;
   3332                     Err(Error::new(ErrorKind::Other, ""))
   3333                 } else {
   3334                     let len = usize::min(buf.len(), self.data.len());
   3335                     buf[..len].copy_from_slice(&self.data[..len]);
   3336                     Ok(len)
   3337                 }
   3338             }
   3339         }
   3340         impl<'a> BufRead for Reader<'a> {
   3341             fn fill_buf(&mut self) -> io::Result<&[u8]> {
   3342                 if self.err {
   3343                     self.err = false;
   3344                     Err(Error::new(ErrorKind::Other, ""))
   3345                 } else {
   3346                     Ok(self.data)
   3347                 }
   3348             }
   3349             fn consume(&mut self, amt: usize) {
   3350                 self.data = &self.data[amt..];
   3351             }
   3352         }
   3353         let mut iter = EvalIter::new(Reader::new(
   3354             b"1+2\n4\n\nq\n5\ns\nrand() + rand(-139/@, 2984/134)\nab",
   3355         ));
   3356         assert!(match iter.lend_next().unwrap().unwrap_err() {
   3357             E::Error(_) => true,
   3358             _ => false,
   3359         });
   3360         assert!(match iter.lend_next().unwrap().unwrap() {
   3361             O::Eval(r) => r.numer().to_i32().unwrap() == 3,
   3362             _ => false,
   3363         });
   3364         assert!(match iter.lend_next().unwrap().unwrap() {
   3365             O::Eval(r) => r.numer().to_i32().unwrap() == 4,
   3366             _ => false,
   3367         });
   3368         assert!(match iter.lend_next().unwrap().unwrap() {
   3369             O::Empty(r) => r.as_ref().unwrap().numer().to_i32().unwrap() == 4,
   3370             _ => false,
   3371         });
   3372         assert!(iter.lend_next().is_none());
   3373         assert!(match iter.lend_next().unwrap().unwrap() {
   3374             O::Eval(r) => r.numer().to_i32().unwrap() == 5,
   3375             _ => false,
   3376         });
   3377         assert!(match iter.lend_next().unwrap().unwrap() {
   3378             O::Store(r) => r.as_ref().unwrap().numer().to_i32().unwrap() == 5,
   3379             _ => false,
   3380         });
   3381         assert!(match iter.lend_next().unwrap().unwrap() {
   3382             O::Eval(r) => r.is_integer(),
   3383             _ => false,
   3384         });
   3385         assert!(match iter.lend_next().unwrap().unwrap_err() {
   3386             E::LangErr(e) => match e {
   3387                 LangErr::MissingTerm(_) => true,
   3388                 _ => false,
   3389             },
   3390             _ => false,
   3391         });
   3392         assert!(iter.lend_next().is_none());
   3393         assert!(iter.lend_next().is_none());
   3394         assert!(iter.lend_next().is_none());
   3395     }
   3396 }