From c5983b85fc9e520208684a8c625cdb96bb219b31 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 19 Apr 2019 21:21:47 +0800 Subject: Add literal matcher --- crates/ra_mbe/src/lib.rs | 12 ++++++++++++ crates/ra_mbe/src/mbe_expander.rs | 9 +++++++++ crates/ra_mbe/src/tt_cursor.rs | 14 ++++++++++++++ 3 files changed, 35 insertions(+) (limited to 'crates/ra_mbe') diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs index a143eaa36..b9dd22dc9 100644 --- a/crates/ra_mbe/src/lib.rs +++ b/crates/ra_mbe/src/lib.rs @@ -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;"#); + } } diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs index cacc3da19..548b15535 100644 --- a/crates/ra_mbe/src/mbe_expander.rs +++ b/crates/ra_mbe/src/mbe_expander.rs @@ -185,6 +185,15 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result { + 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), } } diff --git a/crates/ra_mbe/src/tt_cursor.rs b/crates/ra_mbe/src/tt_cursor.rs index 9c49648fa..6184fb31f 100644 --- a/crates/ra_mbe/src/tt_cursor.rs +++ b/crates/ra_mbe/src/tt_cursor.rs @@ -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 { let parser = Parser::new(&mut self.pos, self.subtree); parser.parse_path() -- cgit v1.2.3