extern crate mec_mrbc_sys;
extern crate mrubyedge;
mod helpers;
use std::rc::Rc;
use helpers::*;
use mrubyedge::Error;
use mrubyedge::yamrb::helpers::mrb_define_cmethod;
use mrubyedge::yamrb::value::RObject;
use mrubyedge::yamrb::vm::VM;
#[test]
fn fncall_test() {
let code = "
def double(n)
n * 2
end
";
let binary = mrbc_compile("fncall", code);
let mut rite = mrubyedge::rite::load(&binary).unwrap();
let mut vm = mrubyedge::yamrb::vm::VM::open(&mut rite);
vm.run().unwrap();
fn rust_method_calling_mrb_funcall(
vm: &mut VM,
args: &[Rc<RObject>],
) -> Result<Rc<RObject>, Error> {
let n = if !args.is_empty() {
let arg: i64 = args[0].as_ref().try_into()?;
arg
} else {
0
};
let args_for_call = vec![Rc::new(RObject::integer(n))];
let result = mrb_funcall(vm, None, "double", &args_for_call)?;
Ok(result)
}
let kernel = vm.object_class.clone();
mrb_define_cmethod(
&mut vm,
kernel,
"call_double",
Box::new(rust_method_calling_mrb_funcall),
);
let args = vec![Rc::new(RObject::integer(5))];
let result = mrb_funcall(&mut vm, None, "call_double", &args).unwrap();
let result: i64 = result.as_ref().try_into().unwrap();
assert_eq!(result, 10);
}
#[test]
fn nested_fncall_test() {
let code = "
def add(a, b)
a + b
end
def multiply(a, b)
do_multiply(a, b)
end
complex_calc(2, 3)
";
let binary = mrbc_compile("nested_fncall", code);
let mut rite = mrubyedge::rite::load(&binary).unwrap();
let mut vm = mrubyedge::yamrb::vm::VM::open(&mut rite);
fn rust_method_do_multiply(_vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error> {
let a: i64 = args[0].as_ref().try_into()?;
let b: i64 = args[1].as_ref().try_into()?;
let result = a * b;
Ok(Rc::new(RObject::integer(result)))
}
fn complex_calculation(vm: &mut VM, args: &[Rc<RObject>]) -> Result<Rc<RObject>, Error> {
let a: i64 = args[0].as_ref().try_into()?;
let b: i64 = args[1].as_ref().try_into()?;
let add_args = vec![Rc::new(RObject::integer(a)), Rc::new(RObject::integer(b))];
let sum = mrb_funcall(vm, None, "add", &add_args)?;
let sum_val: i64 = sum.as_ref().try_into()?;
let mul_args = vec![
Rc::new(RObject::integer(sum_val)),
Rc::new(RObject::integer(3)),
];
let result = mrb_funcall(vm, None, "multiply", &mul_args)?;
Ok(result)
}
let kernel = vm.object_class.clone();
mrb_define_cmethod(
&mut vm,
kernel.clone(),
"do_multiply",
Box::new(rust_method_do_multiply),
);
mrb_define_cmethod(
&mut vm,
kernel.clone(),
"complex_calc",
Box::new(complex_calculation),
);
let result = vm.run().unwrap();
let result: i64 = result.as_ref().try_into().unwrap();
assert_eq!(result, 15);
let args = vec![Rc::new(RObject::integer(2)), Rc::new(RObject::integer(3))];
let result = mrb_funcall(&mut vm, None, "complex_calc", &args).unwrap();
let result: i64 = result.as_ref().try_into().unwrap();
assert_eq!(result, 15);
}