rust_lisp 0.18.0

A Rust-embeddable Lisp, with support for interop with native Rust functions
Documentation
use rust_lisp::{
    default_env,
    interpreter::eval,
    lisp,
    model::{IntType, RuntimeError, Value},
    parser::parse,
};
use std::{cell::RefCell, rc::Rc};

#[test]
fn one() {
    assert_eq!(
        eval_str("(car (list 1 2 3))"),
        Ok(Value::from(Into::<IntType>::into(1)))
    );
}

#[test]
fn two() {
    assert_eq!(
        eval_str("(car (list (list 1 2 3) 4 5 6))"),
        Ok(lisp! { (1 2 3) })
    );
}

#[test]
fn three() {
    assert_eq!(
        eval_str("(car (list))"),
        Err(RuntimeError {
            msg: "Attempted to apply car on nil".to_owned()
        })
    );
}

#[test]
fn four() {
    assert_eq!(
        eval_str("(car (car (list (list \"hotdogs\") \"and\")))"),
        Ok(lisp! { "hotdogs" })
    );
}

#[test]
fn five() {
    assert_eq!(eval_str("(cdr (list 1 2 3))"), Ok(lisp! { (2 3) }));
}

#[test]
fn six() {
    assert_eq!(
        eval_str("(cons (list 1 2 3) 4)"),
        Err(RuntimeError {
            msg: "\"cons\" requires argument 2 to be a list; got 4".to_owned()
        })
    );
}

#[test]
fn seven() {
    assert_eq!(eval_str("(cons 4 (list 1 2 3))"), Ok(lisp! { (4 1 2 3) }));
}

#[cfg(test)]
fn eval_str(source: &str) -> Result<Value, RuntimeError> {
    let ast = parse(source).next().unwrap().unwrap();
    let env = Rc::new(RefCell::new(default_env()));
    return eval(env, &ast);
}