scheme4r 0.2.3

Scheme interpreter for rust
Documentation
use super::*;

pub(super) fn install(env: &mut Environment) {
    define_builtin(env, "boolean?", is_boolean);
    define_builtin(env, "boolean=?", boolean_equal);
    define_builtin(env, "not", not);
}

fn is_boolean(_: &Engine, args: &[Value]) -> Result<Value, SchemeError> {
    expect_arity("boolean?", args, 1)?;
    Ok(Value::Boolean(matches!(args[0], Value::Boolean(_))))
}

fn boolean_equal(_: &Engine, args: &[Value]) -> Result<Value, SchemeError> {
    if args.is_empty() {
        return Err(SchemeError::arity(
            "'boolean=?' expects at least 1 argument",
        ));
    }

    let mut previous = expect_boolean("boolean=?", &args[0])?;
    for value in &args[1..] {
        let current = expect_boolean("boolean=?", value)?;
        if current != previous {
            return Ok(Value::Boolean(false));
        }
        previous = current;
    }
    Ok(Value::Boolean(true))
}

fn not(_: &Engine, args: &[Value]) -> Result<Value, SchemeError> {
    expect_arity("not", args, 1)?;
    Ok(Value::Boolean(matches!(args[0], Value::Boolean(false))))
}

fn expect_boolean(name: &str, value: &Value) -> Result<bool, SchemeError> {
    match value {
        Value::Boolean(boolean) => Ok(*boolean),
        other => Err(SchemeError::type_error(format!(
            "'{name}' expected a boolean, got {other}"
        ))),
    }
}