macro_rules! testcase {
($name: ident, $input: expr, $res: expr) => {
#[test]
fn $name() {
let mut opp = opparser_factory();
assert_eq!(
opp.parse($input),
IResult::Done("".as_bytes(), $res)
);
}
}
}
macro_rules! t {
($left: expr, $op: expr, $right: expr) => {
$crate::Expr::BinExpr {
left: Box::new($left),
op: $op,
right: Box::new($right),
}
};
($op: expr, $left: expr) => {
$crate::Expr::UnExpr {
item: Box::new($left),
op: $op,
}
};
($a: expr) => {
$crate::Expr::Atom(format!("{}", $a).as_bytes())
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! alt_operator {
(__impl $i:expr,
$op_path: path,
$token: path,
$assoc: expr,
$prec: expr => $($rest:tt)* ) => (
alt_operator!(__impl $i, $op_path, call!($token), $assoc, $prec => $($rest)*);
);
(__impl $i:expr,
$op_path: path,
$token: ident!( $($token_args:tt)* ),
$assoc: expr,
$prec: expr => $($rest:tt)*) => (
match $token!( $i, $($token_args)* ) {
$crate::IResult::Error(_) => {
alt_operator!(__impl $i, $($rest)* )
},
$crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
$crate::IResult::Done(i, _) => {
$crate::IResult::Done(i, OperatorInfo {
op: $op_path,
associativity: $assoc,
precedence: $prec,
})
}
}
);
(__impl $i:expr,
$op_path: path,
$token: path,
$assoc: expr,
$prec: expr) => (
alt_operator!(__impl $i, $op_path, call!($token), $assoc, $prec, $($rest)*);
);
(__impl $i:expr,
$op_path: path,
$token: ident!( $($token_args:tt)* ),
$assoc: expr,
$prec: expr) => (
match $token!( $i, $($token_args)* ) {
$crate::IResult::Error(e) => $crate::IResult::Error(e),
$crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
$crate::IResult::Done(i, _) => {
$crate::IResult::Done(i, OperatorInfo {
op: $op_path,
associativity: $assoc,
precedence: $prec,
})
}
}
);
($i:expr, $($rest:tt)*) => (
{
alt_operator!(__impl $i, $($rest)*)
}
);
}
#[macro_export]
#[doc(hidden)]
macro_rules! extract_result {
( $($input:tt)* ) => {
match $($input)* {
$crate::IResult::Incomplete(x) => {
return $crate::IResult::Incomplete(x);
},
$crate::IResult::Error(e) => {
return $crate::IResult::Error(e);
},
$crate::IResult::Done(i, o) => (i, o),
}
}
}
#[macro_export]
macro_rules! parse_operator {
(__impl
$i: expr,
// TODO: the final macro ideally wouldn't require type info
<$ty: ty, $op_ty: ty>,
$atom: path,
$($ops:tt)*) => {
parse_operator!(__impl $i, <$ty, $op_ty>, call!($atom), $($ops)*)
};
(__impl
$i: expr,
// TODO: the final macro ideally wouldn't require type info
<$ty: ty, $op_ty: ty>,
$atom: ident!( $($atom_args:tt)* ),
$($ops:tt)*) => {{
use $crate::Expr;
use OperatorInfo;
fn recurse(i: &[u8], min_prec: u32) ->
$crate::IResult<&[u8], Expr<$ty, $op_ty>> {
}
recurse($i, 0)
}};
($i: expr, <$ty: ty, $op_ty: ty>, $($rest:tt)* ) => {
parse_operator!(__impl $i, <$ty, $op_ty>, $($rest)*)
}
}