#[macro_export]
macro_rules! caml_ffi {
($code:tt) => {
let mut caml_frame = $crate::core::memory::caml_local_roots.clone();
$code;
return
};
($code:tt => $result:expr) => {
let mut caml_frame = $crate::core::memory::caml_local_roots;
$code;
return $crate::core::mlvalues::Value::from($result);
}
}
#[macro_export]
macro_rules! caml_param {
(@step $idx:expr, $caml_roots:ident,) => {
$caml_roots.ntables = $idx;
};
(@step $idx:expr, $caml_roots:ident, $param:expr, $($tail:expr,)*) => {
$caml_roots.tables[$idx] = &mut $param;
caml_param!(@step $idx + 1usize, $caml_roots, $($tail,)*);
};
($($n:expr),*) => {
let mut caml_roots: $crate::core::memory::CamlRootsBlock = ::std::default::Default::default();
caml_roots.next = $crate::core::memory::caml_local_roots;
$crate::core::memory::caml_local_roots = (&mut caml_roots) as *mut $crate::core::memory::CamlRootsBlock;
caml_roots.nitems = 1; caml_param!(@step 0usize, caml_roots, $($n,)*);
}
}
#[macro_export]
macro_rules! caml_local {
($($local:ident),*) => {
$(let mut $local = $crate::value::Value::new($crate::core::mlvalues::UNIT);)*
caml_param!($($local.0),*);
}
}
#[macro_export]
macro_rules! caml_body {
(||, <$($local:ident),*>, $code:block) => {
let caml_frame = $crate::core::memory::caml_local_roots;
caml_local!($($local),*);
{
$(let mut $param = Value::new($param);
{
let _ = $param;
})*
$code;
}
$crate::core::memory::caml_local_roots = caml_frame;
};
(|$($param:ident),*|, @code $code:block) => {
let caml_frame = $crate::core::memory::caml_local_roots;
caml_param!($($param),*);
{
$(let mut $param = Value::new($param);
{
let _ = $param;
})*
$code;
}
$crate::core::memory::caml_local_roots = caml_frame;
};
(|$($param:ident),*|, <$($local:ident),*>, $code:block) => {
let caml_frame = $crate::core::memory::caml_local_roots;
caml_param!($($param),*);
caml_local!($($local),*);
{
$(let mut $param = Value::new($param);
{
let _ = $param;
})*
$code;
}
$crate::core::memory::caml_local_roots = caml_frame;
}
}
#[macro_export]
macro_rules! caml {
($name:ident, |$($param:ident),*|, <$($local:ident),*>, $code:block -> $retval:ident) => {
#[allow(unused_mut)]
#[no_mangle]
pub unsafe extern fn $name ($(mut $param: $crate::core::mlvalues::Value,)*) -> $crate::core::mlvalues::Value {
caml_body!(|$($param),*|, <$($local),*>, $code);
return $crate::core::mlvalues::Value::from($retval)
}
};
($name:ident, |$($param:ident),*|, $code:block) => {
#[allow(unused_mut)]
#[no_mangle]
pub unsafe extern fn $name ($(mut $param: $crate::core::mlvalues::Value,)*) {
caml_body!(|$($param),*|, @code $code);
return;
}
};
($name:ident, |$($param:ident),*|, $code:block -> $retval:ident) => {
#[allow(unused_mut)]
#[no_mangle]
pub unsafe extern fn $name ($(mut $param: $crate::core::mlvalues::Value,)*) -> $crate::core::mlvalues::Value {
caml_body!(|$($param),*|, @code $code);
return $crate::core::mlvalues::Value::from($retval);
}
};
}
#[macro_export]
macro_rules! tuple {
($($x:expr),*) => {
$crate::Tuple::from(&[$($x.to_value(),)*]).into()
}
}
#[macro_export]
macro_rules! array {
($($x:expr),*) => {
$crate::Array::from(&[$($x.to_value(),)*]).into()
}
}
#[macro_export]
macro_rules! list {
($($x:expr),*) => {
$crate::List::from(&[$($x.to_value(),)*]).into()
}
}