Created
May 15, 2018 15:26
-
-
Save torkleyy/330a24803623649ada8aa779abbffcaa to your computer and use it in GitHub Desktop.
Macro experiments with Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
($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