use crate::{Environment, eval::apply::eval_apply, value::Value};
pub(crate) fn builtin(args: &[Value], env: &Environment) -> Option<(Value, Environment)> {
if let [module, Value::Identity(symbol)] = &args[..] {
match eval_apply(module, env) {
Some((Value::Module(name, mdoule_env), _)) => match mdoule_env.get(symbol) {
Some(val) => Some((val.clone(), Environment::new())),
None => {
eprintln!(
concat!(
"Error[ksl::builtin::use]: ",
"Symbol `{}` is not bound in module `{}`."
),
symbol, name
);
None
}
},
Some((e, _)) => {
eprintln!(
concat!(
"Error[ksl::builtin::use]: ",
"Expected a module, but got `{:?}`."
),
e
);
None
}
None => {
eprintln!(
concat!(
"Error[ksl::builtin::use]: ",
"Cannot evaluate expression {:?}."
),
module
);
None
}
}
} else {
eprintln!(
concat!(
"Error[ksl::builtin::use]: ",
"Only accepts a module and a symbol as arguments, but got {:?}.",
),
args
);
None
}
}