aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2019-04-19 14:21:47 +0100
committerEdwin Cheng <[email protected]>2019-04-19 14:21:47 +0100
commitc5983b85fc9e520208684a8c625cdb96bb219b31 (patch)
treea990c96f3c973656663ab49d3f292dfca95a97b2 /crates/ra_mbe
parent313854c728c45ce236f23ff7a8834690e06d8306 (diff)
Add literal matcher
Diffstat (limited to 'crates/ra_mbe')
-rw-r--r--crates/ra_mbe/src/lib.rs12
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs9
-rw-r--r--crates/ra_mbe/src/tt_cursor.rs14
3 files changed, 35 insertions, 0 deletions
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)
797 ); 797 );
798 assert_expansion(&rules, r#"foo!{'a}"#, r#"struct Ref < 'a > {s : & 'a str}"#); 798 assert_expansion(&rules, r#"foo!{'a}"#, r#"struct Ref < 'a > {s : & 'a str}"#);
799 } 799 }
800
801 #[test]
802 fn test_literal() {
803 let rules = create_rules(
804 r#"
805 macro_rules! foo {
806 ($ type:ty $ lit:literal) => { const VALUE: $ type = $ lit;};
807 }
808"#,
809 );
810 assert_expansion(&rules, r#"foo!(u8 0)"#, r#"const VALUE: u8 = 0;"#);
811 }
800} 812}
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<Bindings,
185 input.eat_lifetime().ok_or(ExpandError::UnexpectedToken)?.clone(); 185 input.eat_lifetime().ok_or(ExpandError::UnexpectedToken)?.clone();
186 res.inner.insert(text.clone(), Binding::Simple(lifetime.into())); 186 res.inner.insert(text.clone(), Binding::Simple(lifetime.into()));
187 } 187 }
188 "literal" => {
189 let literal =
190 input.eat_literal().ok_or(ExpandError::UnexpectedToken)?.clone();
191 res.inner.insert(
192 text.clone(),
193 Binding::Simple(tt::Leaf::from(literal).into()),
194 );
195 }
196
188 _ => return Err(ExpandError::UnexpectedToken), 197 _ => return Err(ExpandError::UnexpectedToken),
189 } 198 }
190 } 199 }
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> {
41 } 41 }
42 } 42 }
43 43
44 pub(crate) fn at_literal(&mut self) -> Option<&'a tt::Literal> {
45 match self.current() {
46 Some(tt::TokenTree::Leaf(tt::Leaf::Literal(i))) => Some(i),
47 _ => None,
48 }
49 }
50
44 pub(crate) fn bump(&mut self) { 51 pub(crate) fn bump(&mut self) {
45 self.pos += 1; 52 self.pos += 1;
46 } 53 }
@@ -79,6 +86,13 @@ impl<'a> TtCursor<'a> {
79 }) 86 })
80 } 87 }
81 88
89 pub(crate) fn eat_literal(&mut self) -> Option<&'a tt::Literal> {
90 self.at_literal().map(|i| {
91 self.bump();
92 i
93 })
94 }
95
82 pub(crate) fn eat_path(&mut self) -> Option<tt::TokenTree> { 96 pub(crate) fn eat_path(&mut self) -> Option<tt::TokenTree> {
83 let parser = Parser::new(&mut self.pos, self.subtree); 97 let parser = Parser::new(&mut self.pos, self.subtree);
84 parser.parse_path() 98 parser.parse_path()