ksl 0.1.5

KSL core library and interpreter
Documentation
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
    }
}