#[macro_export]
macro_rules! sexpr {
{ $(;)? } => {
$crate::HNil
};
{ ; { $($head:tt)* } } => {
$crate::sexpr!{ $($head)* }
};
{ ; @ {$($head:tt)*} $(= $val:expr)? } => {
$crate::Quote< $crate::sexpr!{ $($head)* } >
};
{ ; @ $head:ty $(= $val:expr)? } => {
$crate::Quote< $head >
};
{ ; $head:ty } => { $head };
{ { $($head:tt)* } ; $($tail:tt)+ } => {
$crate::HCons< $crate::sexpr!{$($head)*},
$crate::sexpr!{;$($tail)*} >
};
{ @ {$($head:tt)*} $(= $val:expr)? ; $($tail:tt)+ } => {
$crate::HCons< $crate::Quote< $crate::sexpr!{$($head)*}>,
$crate::sexpr!{;$($tail)*} >
};
{ @ $head:ty $(= $val:expr)?; $($tail:tt)+ } => {
$crate::HCons< $crate::Quote< $head >,
$crate::sexpr!{;$($tail)*} >
};
{ $head:ty ; $($tail:tt)+ } => {
$crate::HCons< $head,
$crate::sexpr!{;$($tail)*} >
};
{ { $($head:tt)* } $(, $($tail:tt)*)? } => {
$crate::HCons< $crate::sexpr!{$($head)*},
$crate::sexpr!{$($($tail)*)?} >
};
{ @ {$($head:tt)*} $(= $val:expr)? $(, $($tail:tt)*)? } => {
$crate::HCons< $crate::Quote< $crate::sexpr!{ $($head)* } >,
$crate::sexpr!{$($($tail)*)?} >
};
{ @ $head:ty $(= $val:expr)? $(, $($tail:tt)*)? } => {
$crate::HCons< $crate::Quote< $head >,
$crate::sexpr!{$($($tail)*)?} >
};
{ $head:ty $(, $($tail:tt)*)? } => {
$crate::HCons< $head,
$crate::sexpr!{$($($tail)*)?} >
};
}
#[macro_export]
macro_rules! sexpr_quoted_types {
{ $(;)? } => {
$crate::HNil
};
{ ; { $($head:tt)* } } => { () };
{ ; @ {$($head:tt)*}=$val:expr } => {
$crate::sexpr!{$($head:tt)*} = $val
};
{ ; @ {$($head:tt)*} } => { () };
{ ; @ $head:ty=$val:expr } => {
$head = $val
};
{ ; @ $head:ty } => { () };
{ ; $head:ty } => { () };
{ { $($head:tt)* } ; $($tail:tt)+ } => {
$crate::HCons < $crate::sexpr_quoted_types!{$($head)*},
$crate::sexpr_quoted_types!{;$($tail)*} >
};
{ @ {$($head:tt)*} = $val:expr ; $($tail:tt)+ } => {
$crate::HCons < $crate::sexpr!{$($head:tt)*},
$crate::sexpr_quoted_types!{;$($tail)*} >
};
{ @ {$($head:tt)*} ; $($tail:tt)+ } => {
$crate::HCons < (),
$crate::sexpr_quoted_types!{;$($tail)*} >
};
{ @ $head:ty = $val:expr; $($tail:tt)+ } => {
$crate::HCons< $head,
$crate::sexpr_quoted_types!{;$($tail)*} >
};
{ @ $head:ty; $($tail:tt)+ } => {
$crate::HCons< (),
$crate::sexpr_quoted_types!{;$($tail)*} >
};
{ $head:ty ; $($tail:tt)+ } => {
$crate::HCons< (),
$crate::sexpr_quoted_types!{;$($tail)*} >
};
{ { $($head:tt)* } $(, $($tail:tt)*)? } => {
$crate::HCons< $crate::sexpr_quoted_types!{$($head)*},
$crate::sexpr_quoted_types!{$($($tail)*)?} >
};
{ @ {$($head:tt)*} = $val:expr $(, $($tail:tt)*)? } => {
$crate::HCons< $crate::sexpr!{$($head:tt)*},
$crate::sexpr_quoted_types!{$($($tail)*)?} >
};
{ @ {$($head:tt)*} $(, $($tail:tt)*)? } => {
$crate::HCons< (),
$crate::sexpr_quoted_types!{$($($tail)*)?} >
};
{ @ $head:ty = $val:expr $(, $($tail:tt)*)? } => {
$crate::HCons< $head,
$crate::sexpr_quoted_types!{$($($tail)*)?} >
};
{ @ $head:ty $(, $($tail:tt)*)? } => {
$crate::HCons< (),
$crate::sexpr_quoted_types!{$($($tail)*)?} >
};
{ $head:ty $(, $($tail:tt)*)? } => {
$crate::HCons< (),
$crate::sexpr_quoted_types!{$($($tail)*)?} >
};
}
#[macro_export]
macro_rules! sexpr_quoted_vals {
{ $(;)? } => {
$crate::HNil
};
{ ; { $($head:tt)* } } => { () };
{ ; @ {$($head:tt)*}=$val:expr } => {
{let _x:$crate::sexpr!{$($head:tt)*} = $val; _x}
};
{ ; @ {$($head:tt)*} } => { () };
{ ; @ $head:ty=$val:expr } => {
{let _x:$head = $val; _x}
};
{ ; @ $head:ty } => { () };
{ ; $head:ty } => { () };
{ { $($head:tt)* } ; $($tail:tt)+ } => {
$crate::HCons { head : $crate::sexpr_quoted_vals!{$($head)*},
tail : $crate::sexpr_quoted_vals!{;$($tail)*} }
};
{ @ {$($head:tt)*} = $val:expr ; $($tail:tt)+ } => {
$crate::HCons { head : {let _x:$crate::sexpr!{$($head:tt)*} = $val; _x},
tail : $crate::sexpr_quoted_vals!{;$($tail)*} }
};
{ @ {$($head:tt)*} ; $($tail:tt)+ } => {
$crate::HCons { head: (),
tail: $crate::sexpr_quoted_vals!{;$($tail)*} }
};
{ @ $head:ty = $val:expr; $($tail:tt)+ } => {
$crate::HCons{ head: {let _x:$head = $val; _x},
tail: $crate::sexpr_quoted_vals!{;$($tail)*} }
};
{ @ $head:ty; $($tail:tt)+ } => {
$crate::HCons{ head: (),
tail: $crate::sexpr_quoted_vals!{;$($tail)*} }
};
{ $head:ty ; $($tail:tt)+ } => {
$crate::HCons{ head: (),
tail: $crate::sexpr_quoted_vals!{;$($tail)*} }
};
{ { $($head:tt)* } $(, $($tail:tt)*)? } => {
$crate::HCons{ head: $crate::sexpr_quoted_vals!{$($head)*},
tail: $crate::sexpr_quoted_vals!{$($($tail)*)?} }
};
{ @ {$($head:tt)*} = $val:expr $(, $($tail:tt)*)? } => {
$crate::HCons{ head: {let _x:$crate::sexpr!{$($head:tt)*} = $val; _x},
tail: $crate::sexpr_quoted_vals!{$($($tail)*)?} }
};
{ @ {$($head:tt)*} $(, $($tail:tt)*)? } => {
$crate::HCons{ head: (),
tail: $crate::sexpr_quoted_vals!{$($($tail)*)?} }
};
{ @ $head:ty = $val:expr $(, $($tail:tt)*)? } => {
$crate::HCons{ head: {let _x:$head = $val; _x},
tail: $crate::sexpr_quoted_vals!{$($($tail)*)?} }
};
{ @ $head:ty $(, $($tail:tt)*)? } => {
$crate::HCons{ head: (),
tail: $crate::sexpr_quoted_vals!{$($($tail)*)?} }
};
{ $head:ty $(, $($tail:tt)*)? } => {
$crate::HCons{ head: (),
tail: $crate::sexpr_quoted_vals!{$($($tail)*)?} }
};
}
#[macro_export]
macro_rules! sexpr_val {
{ $(;)? } => {
$crate::HNil
};
{ ; @{ $($head:tt)* } } => { $crate::sexpr_val!{$($head)*} };
{ ; $head:expr } => { $head };
{ @{ $($head:tt)* } ; $($tail:tt)* } => {
$crate::HCons{ head: $crate::sexpr_val!{$($head)*},
tail: $crate::sexpr_val!{;$($tail)*} }
};
{ $head:expr ; $($tail:tt)* } => {
$crate::HCons{ head: $head,
tail: $crate::sexpr_val!{;$($tail)*} }
};
{ @{ $($head:tt)* } $(, $($tail:tt)*)? } => {
$crate::HCons{ head: $crate::sexpr_val!{$($head)*},
tail: $crate::sexpr_val!{$($($tail)*)?} }
};
{ $head:expr $(, $($tail:tt)*)? } => {
$crate::HCons{ head: $head,
tail: $crate::sexpr_val!{$($($tail)*)?} }
};
}
#[macro_export]
macro_rules! sexpr_pat_ty {
{ $(;)? } => {
$crate::HNil
};
{ ; { $($head:tt)* } } => { $crate::sexpr_pat_ty!{$($head)*} };
{ ; $head:tt : $ty:ty } => { $ty };
{ { $($head:tt)* } ; $($tail:tt)* } => {
$crate::HCons< $crate::sexpr_pat_ty!{$($head)*},
$crate::sexpr_pat_ty!{;$($tail)*} >
};
{ $head:tt : $ty:ty; $($tail:tt)* } => {
$crate::HCons< $ty,
$crate::sexpr_pat_ty!{;$($tail)*} >
};
{ { $($head:tt)* } $(, $($tail:tt)*)? } => {
$crate::HCons< $crate::sexpr_pat_ty!{$($head)*},
$crate::sexpr_pat_ty!{$($($tail)*)?} >
};
{ $head:tt : $ty:ty $(, $($tail:tt)*)? } => {
$crate::HCons< $ty,
$crate::sexpr_pat_ty!{$($($tail)*)?} >
};
}
#[macro_export]
macro_rules! sexpr_pat {
{ $(;)? } => {
$crate::HNil
};
{ ; { $($head:tt)* } } => { $crate::sexpr_pat!{$($head)*} };
{ ; $head:tt : $ty:ty } => { $head };
{ { $($head:tt)* } ; $($tail:tt)* } => {
$crate::HCons{ head: $crate::sexpr_pat!{$($head)*},
tail: $crate::sexpr_pat!{;$($tail)*} }
};
{ $head:tt : $ty:ty; $($tail:tt)* } => {
$crate::HCons{ head: $head,
tail: $crate::sexpr_pat!{;$($tail)*} }
};
{ { $($head:tt)* } $(, $($tail:tt)*)? } => {
$crate::HCons{ head: $crate::sexpr_pat!{$($head)*},
tail: $crate::sexpr_pat!{$($($tail)*)?} }
};
{ $head:tt : $ty:ty $(, $($tail:tt)*)? } => {
$crate::HCons{ head: $head,
tail: $crate::sexpr_pat!{$($($tail)*)?} }
};
}
#[macro_export]
macro_rules! eval { ($($expr:tt)*) => { <$crate::sexpr!{$($expr)*} as $crate::engine::Eval>::Result } }
#[macro_export]
macro_rules! partial { ($($expr:tt)*) => { $crate::ops::PartialImpl<$crate::sexpr!{$($expr)*}> }}
#[macro_export]
macro_rules! calc { ($($expr:tt)*) => {
$crate::engine::calc::<$crate::sexpr!{$($expr)*}, $crate::sexpr_quoted_types!{$($expr)*}>(
$crate::sexpr_quoted_vals!{$($expr)*}
)
}}
#[macro_export]
macro_rules! calc_ty { ($($expr:tt)*) => {
<$crate::sexpr!{$($expr)*} as $crate::engine::Calc<$crate::sexpr_quoted_types!{$($expr)*}>>::Result
}}
#[macro_export]
macro_rules! calc_bound { ($($expr:tt)*) => {
$crate::engine::Calc<$crate::sexpr_quoted_types!{$($expr)*}>
}}
#[macro_export]
macro_rules! literal {
{ $(
$({$($gen:tt)*})? $ty:ty
);+ } => { $(
impl$(<$($gen)*>)? $crate::engine::Eval for $ty { type Result = Self; }
impl<Q,$($($gen)*)?> $crate::engine::Calc<Q> for $ty where Self: ::std::default::Default {
type Result = Self;
#[inline(always)]
fn calc(_:Q)->Self { ::std::default::Default::default() }
}
impl$(<$($gen)*>)? $crate::LispId for $ty { type Id = $crate::uuid_new_v4!(| $crate::typenum); }
)* }
}
#[cfg(feature="const")]
#[macro_export]
macro_rules! literal_with_id {
{ $(
$({$($gen:tt)*})? $ty:ty : $id:literal
);+ } => { $(
impl$(<$($gen)*>)? $crate::engine::Eval for $ty { type Result = Self; }
impl<Q,$($($gen)*)?> $crate::engine::Calc<Q> for $ty where Self: ::std::default::Default {
type Result = Self;
#[inline(always)]
fn calc(_:Q)->Self { ::std::default::Default::default() }
}
impl$(<$($gen)*>)? $crate::LispId for $ty {
type Id = $crate::ConstId<$id>;
}
)* }
}
#[macro_export]
macro_rules! non_calc_literal {
{ $(
$({$($gen:tt)*})? $ty:ty
);+ } => { $(
impl$(<$($gen)+>)? $crate::engine::Eval for $ty { type Result = Self; }
impl$(<$($gen)+>)? $crate::LispId for $ty { type Id = $crate::uuid_new_v4!(| $crate::typenum); }
)* }
}
#[macro_export]
macro_rules! defun {
{$id:ty { $($body:tt)* }} => {$crate::defun!{@self () $id { $($body)* }}};
{@$self: tt ($($id_gen:tt)*) $id:ty { $(
($($generics:tt)*) $(calc where ($($calcbound:tt)*))? { $($args:tt)* } $({$($preamble:stmt;)*})? => { $($out:tt)* };
)* }} => {
$crate::defun_nocalc!{($($id_gen)*) $id {$(
( $($generics)* ) { $($args)* } => { $($out)* };
)*}}
$(
impl<$($generics)*> $crate::engine::FunCalc< $crate::sexpr_pat_ty!{$($args)*} > for $id
where
$crate::sexpr!{$($out)*}: $crate::engine::Calc< $crate::sexpr_quoted_types!{$($out)*} >,
$($($calcbound)*)?
{
type Result = <$crate::sexpr!{ $($out)* } as $crate::engine::Calc< $crate::sexpr_quoted_types!{$($out)*} >>::Result;
#[inline(always)]
fn calc($self, args: $crate::sexpr_pat_ty!{$($args)*})
-> Self::Result {
#[allow(redundant_semicolons)]
let syntax: $crate::sexpr_quoted_types!{$($out)*} = {
let $crate::sexpr_pat!{$($args)*}: $crate::sexpr_pat_ty!{$($args)*} = args;
$($($preamble;)*)?
$crate::sexpr_quoted_vals!{$($out)*}
};
<$crate::sexpr!{$($out)*} as $crate::engine::Calc< $crate::sexpr_quoted_types!{$($out)*} >>::calc(syntax)
}
}
)*
}
}
pub trait Everything {}
impl<T:?Sized> Everything for T {}
#[macro_export]
macro_rules! defun_rust {
( ($($header:tt)+) -> {$($expr:tt)*} $((as $($res_bound:tt)+))? $(where $($bound:tt)+)? ) => {
$($header)+ -> <$crate::sexpr!{ $($expr)* } as $crate::engine::Calc< $crate::sexpr_quoted_types!{$($expr)*} >>::Result
where $crate::sexpr!{$($expr)*}: $crate::engine::Calc< $crate::sexpr_quoted_types!{$($expr)*} >,
<$crate::sexpr!{ $($expr)* } as $crate::engine::Calc< $crate::sexpr_quoted_types!{$($expr)*} >>::Result: $crate::macros::Everything + $($($res_bound)+,)?
$( $($bound)+)?
{
let syntax: $crate::sexpr_quoted_types!{$($expr)*} = $crate::sexpr_quoted_vals!{$($expr)*};
<$crate::sexpr!{$($expr)*} as $crate::engine::Calc< $crate::sexpr_quoted_types!{$($expr)*} >>::calc(syntax)
}
}
}
#[macro_export]
macro_rules! defun_nocalc {
{($($id_gen:tt)*) $id:ty { $(
($($generics:tt)*) { $($args:tt)* } $(where ($($bound:tt)+))? => { $($out:tt)* };
)* }} => {
$crate::literal!{{$($id_gen)*} $id}
impl<$($id_gen)*> $crate::engine::Call for $id { type Conv=$crate::engine::cc::Func; }
$(
impl<$($generics)*> $crate::engine::FunCall< $crate::sexpr_pat_ty!{$($args)*} > for $id
where $crate::sexpr!{$($out)*}: $crate::engine::Eval $(,$($bound)+)? {
type Result = $crate::eval!{ $($out)* };
}
)*
}
}
#[macro_export]
macro_rules! defmacro {
{$id:ty { $(
($($generics:tt)*) { $($args:tt)* } => { $($out:tt)* };
)* }} => {
$crate::literal!{$id}
impl $crate::engine::Call for $id { type Conv=$crate::engine::cc::Syntax; }
$(
impl<$($generics)*> $crate::engine::SynCall< sexpr!{$($args)*} > for $id
where $crate::sexpr!{$($out)*}: $crate::engine::Eval {
type Result = $crate::eval!{ $($out)* };
}
)*
}
}
#[cfg(test)]
macro_rules! assert_type_eq {
($a:ty, $b:ty) => { let _: ::core::marker::PhantomData<$a>=
<::core::marker::PhantomData<$b> as ::core::default::Default>::default();
}
}