1mod expression;
7mod token;
8
9pub fn evaluate(raw_expression: &str) -> Result<f64, String> {
45 let expression = expression::Expression::new(raw_expression);
46 return expression.infix().postfix().evaluate();
47}
48
49#[cfg(test)]
51mod tests {
52 use super::*;
53
54 fn relative_error(value: f64, reference: f64) -> f64 {
55 if reference == 0.0 {
56 return value.abs();
57 } else {
58 return (value - reference).abs() / reference.abs();
59 }
60 }
61
62 #[test]
63 fn test_evaluation_expression_with_numbers_binary_operator() {
64 let expression: String = String::from("43.75 - 20.97");
65 let reference: f64 = 43.75 - 20.97;
66
67 match evaluate(expression.as_str()) {
68 Ok(result) => assert!(relative_error(result, reference) < 0.01),
69 Err(_) => assert!(false),
70 }
71 }
72
73 #[test]
74 fn test_evaluation_expresion_with_numbers_operators() {
75 let expression: String = String::from("-43.75 + 20.97");
76 let reference: f64 = -43.75 + 20.97;
77
78 match evaluate(expression.as_str()) {
79 Ok(result) => {
80 println!("Evaluation = {}", result);
81 println!("Reference = {}", reference);
82 assert!(relative_error(result, reference) < 0.01);
83 }
84 Err(_) => assert!(false),
85 }
86 }
87
88 #[test]
89 fn test_evaluation_expression_with_numbers_operators_parenthesis() {
90 let expression: String = String::from("43.75 + (-20.97 / 2.87) * 3.14");
91 let reference: f64 = 43.75 + (-20.97 / 2.87) * 3.14;
92
93 match evaluate(expression.as_str()) {
94 Ok(result) => assert!(relative_error(result, reference) < 0.01),
95 Err(_) => assert!(false),
96 }
97 }
98
99 #[test]
100 fn test_evaluation_expression_with_function_and_number() {
101 let expression: String = String::from("sqrt(9.0)");
102 let reference: f64 = 3.0;
103
104 match evaluate(expression.as_str()) {
105 Ok(result) => assert!(relative_error(result, reference) < 0.01),
106 Err(_) => assert!(false),
107 }
108 }
109
110 #[test]
111 fn test_evaluation_expression_with_constant_and_number() {
112 let expression: String = String::from("pi / 2.0");
113 let reference: f64 = std::f64::consts::PI / 2.0;
114
115 match evaluate(expression.as_str()) {
116 Ok(result) => assert!(relative_error(result, reference) < 0.01),
117 Err(_) => assert!(false),
118 }
119 }
120
121 #[test]
122 fn test_evaluation_expression_with_all() {
123 let expression: String = String::from("sin(2.0 - pi) * cos((-pi + 2.0) / 2.0)");
124 let reference: f64 =
125 (2.0 - std::f64::consts::PI).sin() * ((-std::f64::consts::PI + 2.0) / 2.0).cos();
126
127 match evaluate(expression.as_str()) {
128 Ok(result) => assert!(relative_error(result, reference) < 0.01),
129 Err(_) => assert!(false),
130 }
131 }
132}