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
pub mod ast;
pub mod interpreter;
pub mod lexer;
pub mod parser;
pub mod token;

use interpreter::Interpreter;
use lexer::Lexer;
use parser::Parser;

/// Takes mathematical expression as string, resolves it.
/// # Arguments
/// * input_string
/// # Returns
/// Result<f_64, String>
/// # Examples
/// ```
/// use expr_solver::resolve;
///
/// // simple binary expression.
/// assert_eq!(resolve("2+2".to_string()), Ok(4.0));
///
/// // follows precendence, 2 + (2 * 2) and NOT (2 + 2) * 2
/// assert_eq!(resolve("2+2*2".to_string()), Ok(6.0));
///
/// // unary expression.
/// assert_eq!(resolve("-2".to_string()), Ok(-2.0));
///
/// // even chain them. -(-2)
/// assert_eq!(resolve("--2".to_string()), Ok(2.0));
///
/// // binary and unary in one expression.
/// assert_eq!(resolve("2+-2".to_string()), Ok(0.0));
///
/// // gives syntax error.
/// assert!(matches!(resolve("2)2".to_string()), Err(String)));
/// ```
pub fn resolve(input_string: String) -> Result<f64, String> {
    // create a new lexer
    // and parse input string into tokens.
    let mut lexer = Lexer::new(input_string);
    lexer.scan();

    if lexer.has_errors {
        return Err("Found lexical error(s) in the expression.".to_string());
    }

    // create a new parser
    let mut parser = Parser::new(&mut lexer);
    // and parse tokens into AST.
    let ast = parser.parse();

    // if the ast is correct.
    match ast {
        Ok(ast) => {
            // we walk the ast with our interpreter.
            Interpreter::walk_ast(&ast)
        }
        // otherwise we return the error we got from the parser.
        Err(err) => Err(err),
    }
}