ksl 0.1.7

KSL core library and interpreter
Documentation
//! # ksl::builtin::is
//!
//! Built-in functions for checking if the value is the specified type.

use crate::{Environment, FALSE_SYMBOL, TRUE_SYMBOL, builtin::ValueType, eval::apply::eval_apply, is_number_eq, value::Value};

pub(crate) fn builtin(args: &[Value], value_type: ValueType, env: &Environment) -> Option<(Value, Environment)> {
    if let [v] = &args[..] {
        match eval_apply(v, env) {
            Some((e, new_env)) => Some((
                Value::Atom(String::from(match (e, value_type) {
                    (Value::Atom(_), ValueType::Atom)
                    | (Value::Builtin(_), ValueType::Builtin)
                    | (Value::Lambda(_, _, _), ValueType::Lambda)
                    | (Value::Number(_), ValueType::Number)
                    | (Value::Object(_, _), ValueType::Object)
                    | (Value::Plugin(_, _), ValueType::Plugin)
                    | (Value::String(_), ValueType::String) => TRUE_SYMBOL,
                    (Value::Number(n), ValueType::Integer) if is_number_eq(n.round(), n) => TRUE_SYMBOL,
                    (Value::List(_), ValueType::List) | (Value::Unit, ValueType::Unit) => TRUE_SYMBOL,
                    _ => FALSE_SYMBOL,
                })),
                new_env,
            )),
            None => {
                eprintln!(
                    concat!(
                        "Error[ksl::builtin::is<{:?}>]: ",
                        "Cannot evaluate expression {:?}."
                    ),
                    value_type, v
                );
                None
            }
        }
    } else {
        eprintln!(
            concat!(
                "Error[ksl::builtin::is<{:?}>]: ",
                "Only accepts 1 argument, but {} were passed."
            ),
            value_type,
            args.len()
        );
        None
    }
}