ksl 0.1.7

KSL core library and interpreter
Documentation
//! # ksl::builtin::has
//!
//! Built-in function `Has`.

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

pub(crate) fn builtin(args: &[Value], env: &Environment) -> Option<(Value, Environment)> {
    if let [Value::Identity(id)] = &args[..] {
        if env.contains_key(id) {
            Some((Value::Atom(String::from(TRUE_SYMBOL)), Environment::new()))
        } else {
            Some((Value::Atom(String::from(FALSE_SYMBOL)), Environment::new()))
        }
    } else if let [obj, k] = &args[..] {
        match (eval_apply(obj, env), eval_apply(k, env)) {
            (Some((Value::Object(_, dict), _)), Some((Value::String(key), _))) => {
                if dict.contains_key(&key) {
                    Some((Value::Atom(String::from(TRUE_SYMBOL)), Environment::new()))
                } else {
                    Some((Value::Atom(String::from(FALSE_SYMBOL)), Environment::new()))
                }
            }
            (Some((Value::Module(_, m_env), _)), Some((Value::String(key), _))) => {
                if m_env.contains_key(&key) {
                    Some((Value::Atom(String::from(TRUE_SYMBOL)), Environment::new()))
                } else {
                    Some((Value::Atom(String::from(FALSE_SYMBOL)), Environment::new()))
                }
            }
            (Some((e1, _)), Some((e2, _))) => {
                eprintln!(
                    concat!(
                        "Error[ksl::builtin::has]: ",
                        "Expected an object and a string, but got `{:?}`."
                    ),
                    (e1, e2)
                );
                None
            }
            _ => {
                eprintln!(
                    concat!(
                        "Error[ksl::builtin::has]: ",
                        "Cannot evaluate expression `{:?}`."
                    ),
                    (obj, k)
                );
                None
            }
        }
    } else {
        eprintln!(
            concat!(
                "Error[ksl::builtin::has]: ",
                "Only accepts a symbol or an object and a string as arguments, ",
                "but `{:?}` were passed."
            ),
            args
        );
        None
    }
}