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
use ast::{EvaluationResult, NumericLiteral};
use std::collections::HashMap;

pub type Args = Vec<NumericLiteral>;
pub type Func = fn(&Args) -> EvaluationResult;
pub type CustomFn = Func;

lazy_static! {
    pub static ref FUNCTIONS: HashMap<&'static str, Func> = {
        let mut m = HashMap::with_capacity(15);


        let sin  = |args: &Args| Ok(args[0].to_radians().sin());
        let cos  = |args: &Args| Ok(args[0].to_radians().cos());
        let tan  = |args: &Args| Ok(args[0].to_radians().tan());

        let max =  |args: &Args| Ok(args.iter().fold(0. / 0., |acc: NumericLiteral, x| acc.max(*x)));
        let min  =  |args: &Args| Ok(args.iter().fold(0. / 0., |acc: NumericLiteral, x| acc.min(*x)));
        let abs  = |args: &Args| Ok(args[0].abs());

        let sqrt = |args: &Args| Ok(args[0].sqrt());
        let cbrt  = |args: &Args| Ok(args[0].cbrt());

        let log = |args: &Args| Ok(args[1].log(args[0]));
        let log_10 = |args: &Args| Ok(args[0].log(10.0));
        let ln = |args: &Args| Ok(args[0].ln());

        let floor = |args: &Args| Ok(args[0].floor());
        let ceil = |args: &Args| Ok(args[0].ceil());

        // comparison
        m.insert("min", min as Func);
        m.insert("max", max as Func);
        m.insert("abs", abs as Func);
        m.insert("sqrt", sqrt as Func);
        m.insert("cbrt", cbrt as Func);

        // trig
        m.insert("sin", sin as Func);
        m.insert("cos", cos as Func);
        m.insert("tan", tan as Func);

        m.insert("log", log as Func);
        m.insert("log_10", log_10 as Func);
        m.insert("ln", ln as Func);

        m.insert("floor", floor as Func);
        m.insert("ceil", ceil as Func);

        m
    };
}