tulisp 0.26.1

An embeddable lisp interpreter.
Documentation
use crate::{Error, TulispContext, TulispObject, TulispValue, destruct_eval_bind};

fn string_cmp(
    ctx: &mut TulispContext,
    args: &TulispObject,
    oper: impl Fn(&str, &str) -> bool,
) -> Result<TulispObject, Error> {
    let args_other = args;
    destruct_eval_bind!(ctx, (string1 string2) = args_other);
    let string1 = string1.inner_ref();
    let string2 = string2.inner_ref();
    match (&string1.0, &string2.0) {
        (TulispValue::String { value: string1 }, TulispValue::String { value: string2 }) => {
            Ok(oper(string1, string2).into())
        }
        (_, _) => Err(
            Error::type_mismatch("Both arguments need to be strings".to_string()).with_trace(
                if string1.0.stringp() {
                    args.cadr()?
                } else {
                    args.car()?
                },
            ),
        ),
    }
}

pub(crate) fn add(ctx: &mut TulispContext) {
    ctx.add_special_form("string<", |ctx, args| string_cmp(ctx, args, PartialOrd::lt));
    ctx.add_special_form("string>", |ctx, args| string_cmp(ctx, args, PartialOrd::gt));
    ctx.add_special_form("string=", |ctx, args| string_cmp(ctx, args, PartialEq::eq));
    ctx.add_special_form("string-lessp", |ctx, args| {
        string_cmp(ctx, args, PartialOrd::lt)
    });
    ctx.add_special_form("string-greaterp", |ctx, args| {
        string_cmp(ctx, args, PartialOrd::gt)
    });
    ctx.add_special_form("string-equal", |ctx, args| {
        string_cmp(ctx, args, PartialEq::eq)
    });
}