eclisp 0.1.5

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

fn main() -> Result<(), LispError> {
    let lisp = Lisp::new()?;

    lisp.enter(|ctx| -> Result<(), LispError> {
        ctx.defclass(
            &Class::new("vehicle").slot(
                Slot::new("speed")
                    .initarg("speed")
                    .accessor("vehicle-speed"),
            ),
        )?;

        ctx.defclass(
            &Class::new("canoe").superclass("vehicle").slot(
                Slot::new("rowers")
                    .initarg("rowers")
                    .accessor("canoe-rowers")
                    .initform("0"),
            ),
        )?;

        ctx.defmethod("describe-vehicle", &[("object", "vehicle")], |ctx, args| {
            let vehicle = ctx.root(args[0])?;
            let speed = ctx.call("vehicle-speed", &[&vehicle])?;
            ctx.string(format!("Vehicle with speed {speed}"))
        })?;

        ctx.defmethod("describe-vehicle", &[("object", "canoe")], |ctx, args| {
            let canoe = ctx.root(args[0])?;
            let rowers = ctx.call("canoe-rowers", &[&canoe])?;
            ctx.string(format!("Canoe with {rowers} rowers"))
        })?;

        let vehicle = ctx.eval("(make-instance 'vehicle :speed 20)")?;
        let canoe = ctx.eval("(make-instance 'canoe :speed 10 :rowers 6)")?;

        let vehicle_description = ctx.call("describe-vehicle", &[&vehicle])?;
        let canoe_description = ctx.call("describe-vehicle", &[&canoe])?;

        println!("{}", vehicle_description.try_as_string()?);
        println!("{}", canoe_description.try_as_string()?);

        Ok(())
    })
}