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(())
})
}