use std::{cell::Cell, rc::Rc};
use eclisp::{Lisp, LispError};
fn main() -> Result<(), LispError> {
let lisp = Lisp::new()?;
lisp.enter(|ctx| -> Result<(), LispError> {
let multiplier = 10;
ctx.defun("multiply", move |ctx, args| {
if args.len() != 1 {
return Err(LispError::RuntimeError(
"multiply expects one argument".into(),
));
}
let value = args[0].try_as_i64()?;
ctx.int(value * multiplier)
})?;
let result = ctx.eval("(multiply 5)")?;
println!("Result of (multiply 5): {:?}", result.try_as_i64());
let counter = Rc::new(Cell::new(0));
let captured = Rc::clone(&counter);
ctx.defun("increment", move |ctx, args| {
if !args.is_empty() {
return Err(LispError::RuntimeError(
"increment expects no arguments".into(),
));
}
let value = captured.get() + 1;
captured.set(value);
ctx.int(value)
})?;
println!("Counter before increment: {}", counter.get());
println!(
"Result of (increment): {:?}",
ctx.eval("(increment)")?.try_as_i64()
);
println!("Counter after increment: {}", counter.get());
Ok(())
})?;
Ok(())
}