#[macro_use] extern crate ketos;
#[macro_use] extern crate ketos_derive;
use std::cell::Cell;
use std::rc::Rc;
use ketos::{Error, Interpreter, Value};
#[derive(Debug, ForeignValue, FromValueRef)]
pub struct Hello {
who: String,
}
impl Hello {
pub fn new(who: String) -> Hello {
Hello{who: who}
}
pub fn say_hello(&self) -> String {
format!("Hello, {}!", self.who)
}
}
#[derive(Debug, ForeignValue, FromValueRef)]
pub struct Counter {
count: Cell<u32>,
}
impl Counter {
pub fn new() -> Counter {
Counter{count: Cell::new(0)}
}
pub fn count(&self) -> u32 {
let old = self.count.get();
self.count.set(old + 1);
old
}
}
fn say_hello(hello: &Hello) -> Result<String, Error> {
Ok(hello.say_hello())
}
fn count(counter: &Counter) -> Result<u32, Error> {
Ok(counter.count())
}
fn main() {
let interp = Interpreter::new();
let hello = Rc::new(Hello::new("world".into()));
let counter = Rc::new(Counter::new());
ketos_fn!{ interp.scope() => "count" =>
fn count(counter: &Counter) -> u32 }
ketos_fn!{ interp.scope() => "say-hello" =>
fn say_hello(hello: &Hello) -> String }
interp.run_code(r#"
(define (main hello counter)
(do
(println "Hello from Ketos: ~a" (say-hello hello))
(println "Count from Ketos: ~a" (count counter))))
"#, None).unwrap();
interp.call("main", vec![
Value::Foreign(hello.clone()),
Value::Foreign(counter.clone()),
]).unwrap();
println!("Hello from Rust: {}", hello.say_hello());
println!("Count from Rust: {}", counter.count());
}