Add literal matcher

This commit is contained in:
Edwin Cheng 2019-04-19 21:21:47 +08:00
parent 313854c728
commit c5983b85fc
3 changed files with 35 additions and 0 deletions

View File

@ -797,4 +797,16 @@ MACRO_ITEMS@[0; 40)
);
assert_expansion(&rules, r#"foo!{'a}"#, r#"struct Ref < 'a > {s : & 'a str}"#);
}
#[test]
fn test_literal() {
let rules = create_rules(
r#"
macro_rules! foo {
($ type:ty $ lit:literal) => { const VALUE: $ type = $ lit;};
}
"#,
);
assert_expansion(&rules, r#"foo!(u8 0)"#, r#"const VALUE: u8 = 0;"#);
}
}

View File

@ -185,6 +185,15 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
input.eat_lifetime().ok_or(ExpandError::UnexpectedToken)?.clone();
res.inner.insert(text.clone(), Binding::Simple(lifetime.into()));
}
"literal" => {
let literal =
input.eat_literal().ok_or(ExpandError::UnexpectedToken)?.clone();
res.inner.insert(
text.clone(),
Binding::Simple(tt::Leaf::from(literal).into()),
);
}
_ => return Err(ExpandError::UnexpectedToken),
}
}

View File

@ -41,6 +41,13 @@ impl<'a> TtCursor<'a> {
}
}
pub(crate) fn at_literal(&mut self) -> Option<&'a tt::Literal> {
match self.current() {
Some(tt::TokenTree::Leaf(tt::Leaf::Literal(i))) => Some(i),
_ => None,
}
}
pub(crate) fn bump(&mut self) {
self.pos += 1;
}
@ -79,6 +86,13 @@ impl<'a> TtCursor<'a> {
})
}
pub(crate) fn eat_literal(&mut self) -> Option<&'a tt::Literal> {
self.at_literal().map(|i| {
self.bump();
i
})
}
pub(crate) fn eat_path(&mut self) -> Option<tt::TokenTree> {
let parser = Parser::new(&mut self.pos, self.subtree);
parser.parse_path()