eclisp 0.2.0

Bindings for Embeddable Common Lisp
use eclisp::{Lisp, LispError};

fn main() -> Result<(), LispError> {
    // Creates a LISP instance. ELC only supports one per process, so you should only call this once
    // in your program. Destruction will happen automatically on Drop.
    let lisp = Lisp::new()?;

    // All LISP values stay alive within the `lisp.enter(|ctx: LispContext<'_>| -> T {})` lambda. If
    // values need to be stored outside, `ValueRef` can be used.
    lisp.enter(|ctx| -> Result<(), LispError> {
        // `.eval` evaluates lisp code within he context. It can return a LISP value.
        let value = ctx.eval("(+ 1 2)")?;
        println!("Result of (+ 1 2): {:?}", value.try_as_i64());

        let list = ctx.eval("'(10 20 30)")?;

        println!("Result of '(10 20 30): {}", list);
        for value in list.iter() {
            // Any LISP value can be printed via `Debug` or `Display`
            println!("{}", value?);
        }

        Ok(())
    })?;

    // All definitions persist acros eval calls as per the ECL design.
    lisp.enter(|ctx| ctx.eval("(defun double (n) (* n 2))"))?;

    // `lisp.fun`, a wrapper around `ctx.fun`, returns a `Function<'_>` referecnce.
    if let Some(doubled_fun) = lisp.fun("double")? {
        // `.callfun` calls the function be reference.
        let doubled = lisp.callfun(&doubled_fun, &[&lisp.int(3)?])?.try_as_i64()?;
        println!("3 doubled = {}", doubled);
    } else {
        println!("Function 'double' not found");
    }

    // `Lisp` is destroyed here
    Ok(())
}