sexprs-vm 0.0.5

sexprs is a minimal lisp dialect to evaluate written in Rust.
Documentation
use sexprs_data_structures as ds;
use sexprs_data_structures::{AsCell, Quotable, Value};
use sexprs_util::try_result;
use unique_pointer::UniquePointer;

use crate::helpers::runtime_error;
use crate::{Context, Result};

pub fn list<'c>(vm: UniquePointer<Context<'c>>, list: Value<'c>) -> Result<Value<'c>> {
    Ok(ds::list(try_result!(vm.clone().eval(list))))
}

pub fn cons<'c>(_vm: UniquePointer<Context<'c>>, list: Value<'c>) -> Result<Value<'c>> {
    let cell = ds::cons(ds::car(&list), &mut ds::cdr(&list).as_cell());
    Ok(if list.is_quoted() {
        Value::quoted_list(cell)
    } else {
        Value::list(cell)
    })
}
pub fn quote<'c>(
    _vm: UniquePointer<Context<'c>>,
    value: Value<'c>,
) -> Result<Value<'c>> {
    Ok(match &value {
        Value::List(_) => value.clone().quote(),
        Value::QuotedList(_) => value.clone().quote(),
        Value::Symbol(_) => value.clone().quote(),
        Value::QuotedSymbol(_) => value.clone().quote(),
        item =>
            return Err(runtime_error(
                format!("quote invoked with non-symbol and non-list: {:#?}", item),
                None,
            )),
    })
}
pub fn backquote<'c>(
    _vm: UniquePointer<Context<'c>>,
    list: Value<'c>,
) -> Result<Value<'c>> {
    Ok(list)
}

pub fn car<'c>(_vm: UniquePointer<Context<'c>>, list: Value<'c>) -> Result<Value<'c>> {
    Ok(ds::car(&ds::append(list)))
}

pub fn cdr<'c>(_vm: UniquePointer<Context<'c>>, list: Value<'c>) -> Result<Value<'c>> {
    Ok(ds::cdr(&ds::append(list)))
}
pub fn append<'c>(
    _vm: UniquePointer<Context<'c>>,
    list: Value<'c>,
) -> Result<Value<'c>> {
    Ok(ds::append(list))
}