use crate::{Environment, FALSE_SYMBOL, TRUE_SYMBOL, builtin::ValueType, eval::apply::eval_apply, is_number_eq, value::Value};
pub(crate) fn builtin(args: &[Value], vtype: ValueType, env: Environment) -> Result<Value, std::sync::Arc<str>> {
if let [v] = args {
Ok(match (eval_apply(v, env)?, vtype) {
(Value::Atom(_), ValueType::Atom)
| (Value::Builtin(_), ValueType::Builtin)
| (Value::Lambda(_, _, _), ValueType::Lambda)
| (Value::NativeObject(_, _), ValueType::NativeObject)
| (Value::Thread(_), ValueType::Thread)
| (Value::Number(_), ValueType::Number)
| (Value::Object(_, _), ValueType::Object)
| (Value::Plugin(_, _), ValueType::Plugin)
| (Value::String(_), ValueType::String) => TRUE_SYMBOL.clone(),
(Value::Number(n), ValueType::Integer) if is_number_eq(n.round(), n) => TRUE_SYMBOL.clone(),
(Value::List(_), ValueType::List) | (Value::Unit, ValueType::Unit) => TRUE_SYMBOL.clone(),
_ => FALSE_SYMBOL.clone(),
})
} else {
Err(std::sync::Arc::from(format!(
concat!(
"Error[ksl::builtin::{:?}]: ",
"Expected 1 parameter, but {} were passed."
),
vtype,
args.len()
)))
}
}