use crate::{Environment, FALSE_SYMBOL, TRUE_SYMBOL, eval::apply::eval_apply, read_from_environment, value::Value};
pub(crate) fn builtin(args: &[Value], env: Environment) -> Result<Value, std::sync::Arc<str>> {
match args {
[sym_expr] => match sym_expr {
Value::Symbol(var_sym) => {
let exists = read_from_environment(&env, var_sym).is_some();
Ok(if exists {
TRUE_SYMBOL.clone()
} else {
FALSE_SYMBOL.clone()
})
}
e => Err(std::sync::Arc::from(format!(
"Error[ksl::builtin::Has]: Expected a Symbol, but got `{}`.",
e
))),
},
[obj_expr, key_expr] => {
let obj_val = eval_apply(obj_expr, env.clone())?;
let key_val = eval_apply(key_expr, env.clone())?;
match (obj_val, key_val) {
(Value::Object(_, dict), Value::Atom(key)) => {
let exists = dict.contains_key(&key);
Ok(if exists {
TRUE_SYMBOL.clone()
} else {
FALSE_SYMBOL.clone()
})
}
(Value::Object(_, _), e) => Err(std::sync::Arc::from(format!(
"Error[ksl::builtin::Has]: Expected an Atom for the key, but got `{}`.",
e
))),
(e, _) => Err(std::sync::Arc::from(format!(
"Error[ksl::builtin::Has]: Expected an Object, but got `{}`.",
e
))),
}
}
_ => Err(std::sync::Arc::from(format!(
concat!(
"Error[ksl::builtin::Has]: ",
"Expected 1 or 2 parameters, but {} were passed."
),
args.len()
))),
}
}