tulisp 0.29.0

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

impl TulispContext {
    pub(crate) fn compile_1_arg_call(
        &mut self,
        _name: &TulispObject,
        args: &TulispObject,
        has_rest: bool,
        mut lambda: impl FnMut(
            &mut TulispContext,
            &TulispObject,
            &TulispObject,
        ) -> Result<Vec<Instruction>, Error>,
    ) -> Result<Vec<Instruction>, Error> {
        if args.null() {
            return Err(Error::missing_argument("Too few arguments".to_string()));
        }
        args.car_and_then(|arg1| {
            args.cdr_and_then(|rest| {
                if !has_rest && !rest.null() {
                    return Err(Error::invalid_argument("Too many arguments".to_string()));
                }
                lambda(self, arg1, rest)
            })
        })
    }

    pub(crate) fn compile_2_arg_call(
        &mut self,
        _name: &TulispObject,
        args: &TulispObject,
        has_rest: bool,
        mut lambda: impl FnMut(
            &mut TulispContext,
            &TulispObject,
            &TulispObject,
            &TulispObject,
        ) -> Result<Vec<Instruction>, Error>,
    ) -> Result<Vec<Instruction>, Error> {
        let (TulispValue::List { cons: args, .. }, _) = &*args.inner_ref() else {
            return Err(Error::missing_argument("Too few arguments".to_string()));
        };
        if args.cdr().null() {
            return Err(Error::missing_argument("Too few arguments".to_string()));
        }
        let arg1 = args.car();
        args.cdr().car_and_then(|arg2| {
            args.cdr().cdr_and_then(|rest| {
                if !has_rest && !rest.null() {
                    return Err(Error::invalid_argument("Too many arguments".to_string()));
                }
                lambda(self, arg1, arg2, rest)
            })
        })
    }
}