locrian 0.2.2

A simple embeddable functional programming language.
Documentation
use crate::eval::EvalResult;

pub(crate) fn add(args: Vec<EvalResult>) -> EvalResult {
    EvalResult::Number(
        args.iter()
            .map(|val| {
                if let EvalResult::Number(n) = val {
                    *n
                } else {
                    0 as f64
                }
            })
            .reduce(|a, b| a + b)
            .unwrap_or(0 as f64),
    )
}

pub(crate) fn sub(args: Vec<EvalResult>) -> EvalResult {
    EvalResult::Number(
        args.iter()
            .map(|val| {
                if let EvalResult::Number(n) = val {
                    *n
                } else {
                    0 as f64
                }
            })
            .reduce(|a, b| a - b)
            .unwrap_or(0 as f64),
    )
}

pub(crate) fn mul(args: Vec<EvalResult>) -> EvalResult {
    EvalResult::Number(
        args.iter()
            .map(|val| {
                if let EvalResult::Number(n) = val {
                    *n
                } else {
                    0 as f64
                }
            })
            .reduce(|a, b| a * b)
            .unwrap_or(0 as f64),
    )
}

pub(crate) fn div(args: Vec<EvalResult>) -> EvalResult {
    EvalResult::Number(
        args.iter()
            .map(|val| {
                if let EvalResult::Number(n) = val {
                    *n
                } else {
                    0 as f64
                }
            })
            .reduce(|a, b| a / b)
            .unwrap_or(0 as f64),
    )
}

pub(crate) fn pow(args: Vec<EvalResult>) -> EvalResult {
    EvalResult::Number(
        args.iter()
            .map(|val| {
                if let EvalResult::Number(n) = val {
                    *n
                } else {
                    0 as f64
                }
            })
            .reduce(|a, b| a.powf(b))
            .unwrap_or(0 as f64),
    )
}

#[cfg(test)]
mod tests {
    use crate::{eval::EvalResult, eval_str, parser::parse_expr, stdlib::STDLIB};

    #[test]
    fn test_add() {
        assert_eq!(
            eval_str(
                "add(2, 2)",
                STDLIB
                    .clone()
                    .with_var("$use", parse_expr(r#"["num"]"#).unwrap())
            )
            .unwrap(),
            EvalResult::Number(4 as f64)
        );
    }
    #[test]
    fn test_sub() {
        assert_eq!(
            eval_str(
                "sub(2, 2)",
                STDLIB
                    .clone()
                    .with_var("$use", parse_expr(r#"["num"]"#).unwrap())
            )
            .unwrap(),
            EvalResult::Number(0 as f64)
        );
    }
    #[test]
    fn test_mul() {
        assert_eq!(
            eval_str(
                "mul(2, 2)",
                STDLIB
                    .clone()
                    .with_var("$use", parse_expr(r#"["num"]"#).unwrap())
            )
            .unwrap(),
            EvalResult::Number(4 as f64)
        );
    }
    #[test]
    fn test_div() {
        assert_eq!(
            eval_str(
                "div(2, 2)",
                STDLIB
                    .clone()
                    .with_var("$use", parse_expr(r#"["num"]"#).unwrap())
            )
            .unwrap(),
            EvalResult::Number(1 as f64)
        );
    }
    #[test]
    fn test_pow() {
        assert_eq!(
            eval_str(
                "pow(2, 3)",
                STDLIB
                    .clone()
                    .with_var("$use", parse_expr(r#"["num"]"#).unwrap())
            )
            .unwrap(),
            EvalResult::Number(8 as f64)
        );
    }
}