Skip to content

Instantly share code, notes, and snippets.

@torkleyy
Created May 15, 2018 15:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save torkleyy/330a24803623649ada8aa779abbffcaa to your computer and use it in GitHub Desktop.
Save torkleyy/330a24803623649ada8aa779abbffcaa to your computer and use it in GitHub Desktop.
Macro experiments with Rust
($num:expr;$($field:ident),*;$($rev:ident),*) => {
impl<$($field,)*> Pop for ($($field,)*)
where
$($field: Pop),*
{
fn tag() -> Ty {
unreachable!()
}
fn pop_tags(stack: &mut Stack) -> Result<()> {
stack.expect_tag(Ty::Tuple)?;
let num_elems = stack.pop_u64()?;
if num_elems != $num as u64 {
// we need to re-push length and tuple tag
stack.push_u64(num_elems);
stack.push_tag(Ty::Tuple);
return Err(TupleMismatch {
expected: $num as usize,
got: num_elems as usize,
}.into());
}
impl_tuple_and_array!(@pop_tags stack num_elems;$($field)*;);
Ok(())
}
fn pop_value(stack: &mut Stack) -> Result<Self> {
Ok(($($field::pop_value(stack)?,)*))
}
}
};
(@pop_tags $stack:ident $num_elems:ident;;$($pushed:ident)*) => {
};
(@pop_tags $stack:ident $num_elems:ident; $field0:ident $($field:ident)*; $($pushed:ident)*) => {
match $field0::pop_tags($stack) {
Ok(_) => {}
Err(e) => {
// restore popped tags
$(
$pushed::restore_tags($stack);
)*
$stack.push_u64($num_elems);
$stack.push_tag(Ty::Tuple);
return Err(e);
}
}
impl_tuple_and_array!(@pop_tags $stack $num_elems; $($field)*; $field0 $($pushed)*);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment