ksl 0.1.30

KSL core library and interpreter
Documentation
//! # ksl::builtin::math
//!
//! Built-in math functions which expects one number argument.
//!
//! - Abs
//! - ArcCos
//! - ArcSin
//! - ArcTan
//! - Cos
//! - Cosh
//! - Exp
//! - Ln
//! - Neg
//! - Sin
//! - Sinh
//! - Sqrt
//! - Tan
//! - Tanh
//! - Trunc

use crate::{Environment, builtin::MathFunctionType, eval::apply::eval_apply, is_number_eq, value::Value};

pub(crate) fn builtin(args: &[Value], ftype: MathFunctionType, env: Environment) -> Result<Value, std::sync::Arc<str>> {
    if let [v] = args {
        match eval_apply(v, env)? {
            Value::Number(n) => Ok(Value::Number(match ftype {
                MathFunctionType::Abs => n.abs(),
                MathFunctionType::ArcCos => n.acos(),
                MathFunctionType::ArcSin => n.asin(),
                MathFunctionType::ArcTan => n.atan(),
                MathFunctionType::Ceiling => n.ceil(),
                MathFunctionType::Cos => n.cos(),
                MathFunctionType::Cosh => n.cosh(),
                MathFunctionType::Exp => n.exp(),
                MathFunctionType::Floor => n.floor(),
                MathFunctionType::Ln => {
                    if n > 0.0 {
                        n.ln()
                    } else {
                        return Err(std::sync::Arc::from(concat!(
                            "Error[ksl::builtin::Ln]: ",
                            "Logarithm of non-positive number.",
                        )));
                    }
                }
                MathFunctionType::Neg => {
                    if is_number_eq(n, 0.0) {
                        0.0
                    } else {
                        -n
                    }
                }
                MathFunctionType::Round => n.round(),
                MathFunctionType::Sin => n.sin(),
                MathFunctionType::Sinh => n.sinh(),
                MathFunctionType::Sqrt => n.sqrt(),
                MathFunctionType::Tan => n.tan(),
                MathFunctionType::Tanh => n.tanh(),
                MathFunctionType::Trunc => n.trunc(),
            })),
            e => Err(std::sync::Arc::from(format!(
                concat!(
                    "Error[ksl::builtin::{:?}]: ",
                    "Expected a number, but got: `{}`."
                ),
                ftype, e
            ))),
        }
    } else {
        Err(std::sync::Arc::from(format!(
            concat!(
                "Error[ksl::builtin::{:?}]: ",
                "Expected 1 parameter, but {} were passed."
            ),
            ftype,
            args.len()
        )))
    }
}