1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
//! This crate is specifically used for one thing: turning expressions inside of a string //! into a value. This crate acts as a scientific calculator, and includes several functions. //! //! If you need a portion of the calculator changed or removed, please fork it, and make your //! changes. We encourage others to change RSC to their liking. You do not need to attribute //! anything to us. This is MIT licensed software. //! //! Anyone can easily create a [Calculator](computer/struct.Computer.html) and begin working with expressions. Calculators //! also remember variables using a HashMap. You can create and begin using the Calculator like so: //! ``` //! extern crate rsc; //! //! use rsc::computer::Computer; //! //! fn main() { //! let mut c = Computer::new(); //! //! assert!(c.eval("x = 5").unwrap() == 5.0); //! assert!(c.eval("x^2").unwrap() == 25.0); //! } //! ``` //! //! In most cases a simple `eval` should be all you need, but just as many times you may need //! to directly access the tokens and AST. Some reasons may include: //! * For performance or caching; lexing and parsing an expression only once, to calculate it later hundreds //! of times in a loop. //! * Better error messages or visual information for what is happening. //! ``` //! extern crate rsc; //! //! use rsc::lexer::tokenize; //! use rsc::parser::{Expr, parse}; //! use rsc::computer::Computer; //! //! fn main() { //! let expr = "x^2"; //! let tokens = tokenize(expr).unwrap(); //! let ast = parse(&tokens).unwrap(); //! let mut computer = Computer::new(); //! //! for x in 2..=5 { //! let mut ast = ast.clone(); //! ast.replace(&Expr::Identifier("x"), &Expr::Constant(x as f64), false); //! println!("{}", computer.compute(&ast).unwrap()); //! } //! } //! //! // Output: //! // 4 //! // 9 //! // 16 //! // 25 //! ``` pub mod lexer; pub mod parser; pub mod computer; #[derive(Debug, Clone)] pub enum EvalError { ComputeError(computer::ComputeError), ParserError(parser::ParserError), LexerError(lexer::LexerError), } /// Turn an expression inside a string into a number. /// If you are looking for more control, you may want to use /// the `lexer`, `parser`, and `computer` modules individually. /// ``` /// assert_eq!(eval("3.1 + 2.2"), Ok(5.3)); /// ``` pub fn eval(input: &str) -> Result<f64, EvalError> { match lexer::tokenize(input) { Ok(tokens) => match parser::parse(&tokens) { Ok(ast) => match computer::Computer::new().compute(&ast) { Ok(num) => Ok(num), Err(compute_err) => Err(EvalError::ComputeError(compute_err)), } Err(parser_err) => Err(EvalError::ParserError(parser_err)), } Err(lexer_err) => Err(EvalError::LexerError(lexer_err)), } }