expr_solver/
lib.rs

1pub mod ast;
2pub mod interpreter;
3pub mod lexer;
4pub mod parser;
5pub mod token;
6pub mod utils;
7
8use interpreter::Interpreter;
9use lexer::Lexer;
10use parser::Parser;
11
12/// Takes mathematical expression as string, resolves it.
13/// # Arguments
14/// * input_string
15/// # Returns
16/// Result enum with solved value or incase of an error, error string.
17/// # Examples
18/// ```
19/// use expr_solver::resolve;
20///
21/// // simple binary expression.
22/// assert_eq!(resolve("2+2".to_string()), Ok(4.0));
23/// assert_eq!(resolve("3!".to_string()), Ok(6.0));
24///
25/// // follows precendence, 2 + (2 * 2) and NOT (2 + 2) * 2
26/// assert_eq!(resolve("2+2*2".to_string()), Ok(6.0));
27///
28/// // unary expression.
29/// assert_eq!(resolve("-2".to_string()), Ok(-2.0));
30///
31/// // even chain them. -(-2)
32/// assert_eq!(resolve("--2".to_string()), Ok(2.0));
33///
34/// // binary and unary in one expression.
35/// assert_eq!(resolve("2+-2".to_string()), Ok(0.0));
36///
37/// // gives syntax error.
38/// assert!(matches!(resolve("2&2".to_string()), Err(String)));
39/// ```
40pub fn resolve(input_string: String) -> Result<f64, String> {
41    log::debug!("[expr-resolve] input_string={}", &input_string);
42
43    // create a new lexer
44    // and parse input string into tokens.
45    let mut lexer = Lexer::new(&input_string);
46    lexer.scan();
47
48    if lexer.has_errors {
49        log::debug!(
50            "[expr-resolve] Found lexical errors in expression : {}",
51            &input_string
52        );
53        return Err("Found lexical error(s) in the expression.".to_string());
54    }
55
56    // create a new parser
57    let mut parser = Parser::new(&mut lexer);
58    // and parse tokens into AST.
59    let ast = parser.parse();
60
61    // if the ast is correct.
62    match ast {
63        Ok(ast) => {
64            // we walk the ast with our interpreter.
65            Interpreter::walk_ast(&ast)
66        }
67        // otherwise we return the error we got from the parser.
68        Err(err) => Err(err),
69    }
70}