#[macro_export]
macro_rules! expr {
(true) => { $crate::Expr::from($crate::Symbol::new("System`True")) };
(false) => { $crate::Expr::from($crate::Symbol::new("System`False")) };
($k:tt -> $v:tt) => {
$crate::Expr::normal(
$crate::Symbol::new("System`Rule"),
vec![$crate::expr!($k), $crate::expr!($v)],
)
};
(:: $name:ident [ $($args:tt)* ]) => {
$crate::Expr::normal(
$crate::Symbol::new(stringify!($name)),
$crate::__expr_args![$($args)*],
)
};
(:: $d:tt $name:ident [ $($args:tt)* ]) => {
$crate::Expr::normal(
$crate::Symbol::new(concat!(stringify!($d), stringify!($name))),
$crate::__expr_args![$($args)*],
)
};
(:: $name:ident) => {
$crate::Expr::symbol($crate::Symbol::new(stringify!($name)))
};
(:: $d:tt $name:ident) => {
$crate::Expr::symbol(
$crate::Symbol::new(concat!(stringify!($d), stringify!($name)))
)
};
($head:ident $(:: $seg:ident)+ [ $($args:tt)* ]) => {
$crate::Expr::normal(
$crate::Symbol::new(concat!(stringify!($head) $(, "`", stringify!($seg))+)),
$crate::__expr_args![$($args)*],
)
};
($head:ident [ $($args:tt)* ]) => {
$crate::Expr::normal($head, $crate::__expr_args![$($args)*])
};
({ $($assoc:tt)* }) => {
$crate::Expr::new($crate::ExprKind::Association(
$crate::__expr_assoc![$($assoc)*]
))
};
($head:ident $(:: $seg:ident)+) => {
$crate::Expr::symbol($crate::Symbol::new(
concat!(stringify!($head) $(, "`", stringify!($seg))+)
))
};
($e:expr) => { $crate::Expr::from($e) };
}
#[doc(hidden)]
#[macro_export]
macro_rules! __expr_args {
() => { vec![] };
(,) => { vec![] };
(:: $name:ident [ $($inner:tt)* ], $($rest:tt)*) => {{
let mut __args = vec![$crate::expr!(:: $name [ $($inner)* ])];
__args.extend($crate::__expr_args![$($rest)*]);
__args
}};
(:: $name:ident [ $($inner:tt)* ]) => {
vec![$crate::expr!(:: $name [ $($inner)* ])]
};
(:: $name:ident, $($rest:tt)*) => {{
let mut __args = vec![$crate::expr!(:: $name)];
__args.extend($crate::__expr_args![$($rest)*]);
__args
}};
(:: $name:ident) => {
vec![$crate::expr!(:: $name)]
};
(:: $d:tt $name:ident [ $($inner:tt)* ], $($rest:tt)*) => {{
let mut __args = vec![$crate::expr!(:: $d $name [ $($inner)* ])];
__args.extend($crate::__expr_args![$($rest)*]);
__args
}};
(:: $d:tt $name:ident [ $($inner:tt)* ]) => {
vec![$crate::expr!(:: $d $name [ $($inner)* ])]
};
(:: $d:tt $name:ident, $($rest:tt)*) => {{
let mut __args = vec![$crate::expr!(:: $d $name)];
__args.extend($crate::__expr_args![$($rest)*]);
__args
}};
(:: $d:tt $name:ident) => {
vec![$crate::expr!(:: $d $name)]
};
($k:tt -> $v:tt, $($rest:tt)*) => {{
let mut __args = vec![$crate::expr!($k -> $v)];
__args.extend($crate::__expr_args![$($rest)*]);
__args
}};
($k:tt -> $v:tt) => { vec![$crate::expr!($k -> $v)] };
($head:ident $(:: $seg:ident)+ [ $($inner:tt)* ], $($rest:tt)*) => {{
let mut __args = vec![$crate::expr!($head $(:: $seg)+ [ $($inner)* ])];
__args.extend($crate::__expr_args![$($rest)*]);
__args
}};
($head:ident $(:: $seg:ident)+ [ $($inner:tt)* ]) => {
vec![$crate::expr!($head $(:: $seg)+ [ $($inner)* ])]
};
($head:ident $(:: $seg:ident)+, $($rest:tt)*) => {{
let mut __args = vec![$crate::expr!($head $(:: $seg)+)];
__args.extend($crate::__expr_args![$($rest)*]);
__args
}};
($head:ident $(:: $seg:ident)+) => {
vec![$crate::expr!($head $(:: $seg)+)]
};
( .. $e:expr, $($rest:tt)* ) => {{
let mut __args: ::std::vec::Vec<$crate::Expr> =
::core::iter::IntoIterator::into_iter($e)
.map(|__x| $crate::Expr::from(__x))
.collect();
__args.extend($crate::__expr_args![$($rest)*]);
__args
}};
( .. $e:expr ) => {
::core::iter::IntoIterator::into_iter($e)
.map(|__x| $crate::Expr::from(__x))
.collect::<::std::vec::Vec<$crate::Expr>>()
};
($head:ident [ $($inner:tt)* ], $($rest:tt)*) => {{
let mut __args = vec![$crate::expr!($head [ $($inner)* ])];
__args.extend($crate::__expr_args![$($rest)*]);
__args
}};
($head:ident [ $($inner:tt)* ]) => {
vec![$crate::expr!($head [ $($inner)* ])]
};
($arg:tt, $($rest:tt)*) => {{
let mut __args = vec![$crate::expr!($arg)];
__args.extend($crate::__expr_args![$($rest)*]);
__args
}};
($arg:tt) => { vec![$crate::expr!($arg)] };
}
#[doc(hidden)]
#[macro_export]
macro_rules! __expr_assoc {
() => { vec![] };
(,) => { vec![] };
($k:tt -> :: $vname:ident [ $($vinner:tt)* ], $($rest:tt)*) => {{
let mut __v = vec![$crate::RuleEntry::rule(
$crate::expr!($k),
$crate::expr!(:: $vname [ $($vinner)* ]),
)];
__v.extend($crate::__expr_assoc![$($rest)*]);
__v
}};
($k:tt -> :: $vname:ident [ $($vinner:tt)* ]) => {
vec![$crate::RuleEntry::rule(
$crate::expr!($k),
$crate::expr!(:: $vname [ $($vinner)* ]),
)]
};
($k:tt -> :: $vname:ident, $($rest:tt)*) => {{
let mut __v = vec![$crate::RuleEntry::rule(
$crate::expr!($k),
$crate::expr!(:: $vname),
)];
__v.extend($crate::__expr_assoc![$($rest)*]);
__v
}};
($k:tt -> :: $vname:ident) => {
vec![$crate::RuleEntry::rule($crate::expr!($k), $crate::expr!(:: $vname))]
};
($k:tt -> $vh:ident $(:: $vseg:ident)+ [ $($vinner:tt)* ], $($rest:tt)*) => {{
let mut __v = vec![$crate::RuleEntry::rule(
$crate::expr!($k),
$crate::expr!($vh $(:: $vseg)+ [ $($vinner)* ]),
)];
__v.extend($crate::__expr_assoc![$($rest)*]);
__v
}};
($k:tt -> $vh:ident $(:: $vseg:ident)+ [ $($vinner:tt)* ]) => {
vec![$crate::RuleEntry::rule(
$crate::expr!($k),
$crate::expr!($vh $(:: $vseg)+ [ $($vinner)* ]),
)]
};
($k:tt -> $vh:ident $(:: $vseg:ident)+, $($rest:tt)*) => {{
let mut __v = vec![$crate::RuleEntry::rule(
$crate::expr!($k),
$crate::expr!($vh $(:: $vseg)+),
)];
__v.extend($crate::__expr_assoc![$($rest)*]);
__v
}};
($k:tt -> $vh:ident $(:: $vseg:ident)+) => {
vec![$crate::RuleEntry::rule($crate::expr!($k), $crate::expr!($vh $(:: $vseg)+))]
};
($k:tt -> $vhead:ident [ $($vinner:tt)* ], $($rest:tt)*) => {{
let mut __v = vec![$crate::RuleEntry::rule(
$crate::expr!($k),
$crate::expr!($vhead [ $($vinner)* ]),
)];
__v.extend($crate::__expr_assoc![$($rest)*]);
__v
}};
($k:tt -> $vhead:ident [ $($vinner:tt)* ]) => {
vec![$crate::RuleEntry::rule(
$crate::expr!($k),
$crate::expr!($vhead [ $($vinner)* ]),
)]
};
($k:tt -> $v:tt, $($rest:tt)*) => {{
let mut __v = vec![$crate::RuleEntry::rule($crate::expr!($k), $crate::expr!($v))];
__v.extend($crate::__expr_assoc![$($rest)*]);
__v
}};
($k:tt -> $v:tt) => {
vec![$crate::RuleEntry::rule($crate::expr!($k), $crate::expr!($v))]
};
}