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),
}
}