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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use ast::{resolve_fn, resolve_var, Args, Node, Root, Scope};
use error::Error;
use tokens::{Operator, Token};
pub type NumericLiteral = f64;
pub type EvaluationResult = Result<NumericLiteral, Error>;
pub trait Evaluate {
fn eval_with(&self, scope: &Scope) -> EvaluationResult;
fn eval(&self) -> EvaluationResult;
}
pub fn eval_operator(
operator: &Operator,
args: &Option<Args>,
scope: &Scope,
) -> EvaluationResult {
let args = args.as_ref()
.ok_or_else(|| Error::MissingOperands(format!("{:?}", operator)))?
.into_iter()
.map(|node| node.eval_with(scope))
.collect::<Result<Vec<NumericLiteral>, Error>>()?;
let ref mut evaled_args = args.iter();
match operator {
Operator::Add => Ok(evaled_args.sum()),
Operator::Substract => Ok(evaled_args.nth(0).ok_or(
Error::MissingOperands(format!("{:?}", operator)),
)?
- evaled_args.sum::<NumericLiteral>()),
Operator::Multiply => Ok(evaled_args.product()),
Operator::Divide => Ok(evaled_args.nth(0).ok_or(
Error::MissingOperands(format!("{:?}", operator)),
)?
/ evaled_args.product::<NumericLiteral>()),
Operator::Exponentiate => {
let base = evaled_args.nth(0).ok_or_else(|| {
Error::MissingOperands(format!("{:?}", operator))
})?;
Ok(evaled_args.fold(*base, |acc, v| acc.powf(*v)))
},
}
}
fn eval_args(
args: &Option<Args>,
scope: &Scope,
fn_name: String,
) -> Result<Vec<NumericLiteral>, Error> {
if let Some(args) = args {
return args.into_iter()
.map(|n| n.eval_with(scope))
.collect::<Result<Vec<NumericLiteral>, _>>();
}
Err(Error::NotEnoughFunctionParams(fn_name))
}
impl Evaluate for Node {
fn eval_with(&self, scope: &Scope) -> EvaluationResult {
match self.token {
Token::Operator(ref operator) => {
eval_operator(&operator, &self.args, scope)
},
Token::Function(ref f) => resolve_fn(&f.name.as_ref(), scope)?(
&eval_args(&self.args, scope, f.name.clone())?,
),
Token::Number(ref num) => Ok(num.value),
Token::Variable(ref var) => {
if let Ok(value) = resolve_var(&var.name, scope) {
return Ok(value.clone());
}
Err(Error::UnknownVariable(var.name.clone()))
},
_ => Err(Error::CannotEvaluateToken(format!(
"{:?}",
self.token
))),
}
}
fn eval(&self) -> EvaluationResult {
let empty_scope = Scope::new();
self.eval_with(&empty_scope)
}
}
impl<'a> Evaluate for Root<'a> {
fn eval(&self) -> EvaluationResult {
self.node.eval_with(self.scope)
}
fn eval_with(&self, scope: &Scope) -> EvaluationResult {
self.node.eval_with(scope)
}
}