aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_macros/src/lib.rs1
-rw-r--r--crates/ra_macros/src/mbe.rs2
-rw-r--r--crates/ra_macros/src/mbe_parser.rs102
-rw-r--r--crates/ra_macros/src/tt_cursor.rs92
4 files changed, 101 insertions, 96 deletions
diff --git a/crates/ra_macros/src/lib.rs b/crates/ra_macros/src/lib.rs
index 9485b1c3d..e35a056cc 100644
--- a/crates/ra_macros/src/lib.rs
+++ b/crates/ra_macros/src/lib.rs
@@ -12,5 +12,6 @@ macro_rules! impl_froms {
12 12
13pub mod tt; 13pub mod tt;
14pub mod mbe; 14pub mod mbe;
15mod tt_cursor;
15mod mbe_parser; 16mod mbe_parser;
16mod mbe_expander; 17mod mbe_expander;
diff --git a/crates/ra_macros/src/mbe.rs b/crates/ra_macros/src/mbe.rs
index ec811c5f0..6a168a1b5 100644
--- a/crates/ra_macros/src/mbe.rs
+++ b/crates/ra_macros/src/mbe.rs
@@ -1,6 +1,6 @@
1use smol_str::SmolStr; 1use smol_str::SmolStr;
2 2
3use crate::tt::{self, Delimiter}; 3use crate::tt::Delimiter;
4 4
5pub use crate::{ 5pub use crate::{
6 mbe_parser::parse, 6 mbe_parser::parse,
diff --git a/crates/ra_macros/src/mbe_parser.rs b/crates/ra_macros/src/mbe_parser.rs
index 93c2d40b4..024d3a040 100644
--- a/crates/ra_macros/src/mbe_parser.rs
+++ b/crates/ra_macros/src/mbe_parser.rs
@@ -1,99 +1,12 @@
1use crate::{tt, mbe}; 1use crate::{tt, mbe};
2use crate::tt_cursor::TtCursor;
2 3
3/// This module parses a raw `tt::TokenStream` into macro-by-example token 4/// This module parses a raw `tt::TokenStream` into macro-by-example token
4/// stream. This is a *mostly* identify function, expect for handling of 5/// stream. This is a *mostly* identify function, expect for handling of
5/// `$var:tt_kind` and `$(repeat),*` constructs. 6/// `$var:tt_kind` and `$(repeat),*` constructs.
6 7
7struct RulesParser<'a> {
8 subtree: &'a tt::Subtree,
9 pos: usize,
10}
11
12impl<'a> RulesParser<'a> {
13 fn new(subtree: &'a tt::Subtree) -> RulesParser<'a> {
14 RulesParser { subtree, pos: 0 }
15 }
16
17 fn is_eof(&self) -> bool {
18 self.pos == self.subtree.token_trees.len()
19 }
20
21 fn current(&self) -> Option<&'a tt::TokenTree> {
22 self.subtree.token_trees.get(self.pos)
23 }
24
25 fn at_punct(&self) -> Option<&'a tt::Punct> {
26 match self.current() {
27 Some(tt::TokenTree::Leaf(tt::Leaf::Punct(it))) => Some(it),
28 _ => None,
29 }
30 }
31
32 fn at_char(&self, char: char) -> bool {
33 match self.at_punct() {
34 Some(tt::Punct { char: c }) if *c == char => true,
35 _ => false,
36 }
37 }
38
39 fn at_ident(&mut self) -> Option<&'a tt::Ident> {
40 match self.current() {
41 Some(tt::TokenTree::Leaf(tt::Leaf::Ident(i))) => Some(i),
42 _ => None,
43 }
44 }
45
46 fn bump(&mut self) {
47 self.pos += 1;
48 }
49
50 fn eat(&mut self) -> Option<&'a tt::TokenTree> {
51 match self.current() {
52 Some(it) => {
53 self.bump();
54 Some(it)
55 }
56 None => None,
57 }
58 }
59
60 fn eat_subtree(&mut self) -> Option<&'a tt::Subtree> {
61 match self.current()? {
62 tt::TokenTree::Subtree(sub) => {
63 self.bump();
64 Some(sub)
65 }
66 _ => return None,
67 }
68 }
69
70 fn eat_punct(&mut self) -> Option<&'a tt::Punct> {
71 if let Some(it) = self.at_punct() {
72 self.bump();
73 return Some(it);
74 }
75 None
76 }
77
78 fn eat_ident(&mut self) -> Option<&'a tt::Ident> {
79 if let Some(i) = self.at_ident() {
80 self.bump();
81 return Some(i);
82 }
83 None
84 }
85
86 fn expect_char(&mut self, char: char) -> Option<()> {
87 if self.at_char(char) {
88 self.bump();
89 return Some(());
90 }
91 None
92 }
93}
94
95pub fn parse(tt: &tt::Subtree) -> Option<mbe::MacroRules> { 8pub fn parse(tt: &tt::Subtree) -> Option<mbe::MacroRules> {
96 let mut parser = RulesParser::new(tt); 9 let mut parser = TtCursor::new(tt);
97 let mut rules = Vec::new(); 10 let mut rules = Vec::new();
98 while !parser.is_eof() { 11 while !parser.is_eof() {
99 rules.push(parse_rule(&mut parser)?) 12 rules.push(parse_rule(&mut parser)?)
@@ -101,7 +14,7 @@ pub fn parse(tt: &tt::Subtree) -> Option<mbe::MacroRules> {
101 Some(mbe::MacroRules { rules }) 14 Some(mbe::MacroRules { rules })
102} 15}
103 16
104fn parse_rule(p: &mut RulesParser) -> Option<mbe::Rule> { 17fn parse_rule(p: &mut TtCursor) -> Option<mbe::Rule> {
105 let lhs = parse_subtree(p.eat_subtree()?)?; 18 let lhs = parse_subtree(p.eat_subtree()?)?;
106 p.expect_char('=')?; 19 p.expect_char('=')?;
107 p.expect_char('>')?; 20 p.expect_char('>')?;
@@ -111,7 +24,7 @@ fn parse_rule(p: &mut RulesParser) -> Option<mbe::Rule> {
111 24
112fn parse_subtree(tt: &tt::Subtree) -> Option<mbe::Subtree> { 25fn parse_subtree(tt: &tt::Subtree) -> Option<mbe::Subtree> {
113 let mut token_trees = Vec::new(); 26 let mut token_trees = Vec::new();
114 let mut p = RulesParser::new(tt); 27 let mut p = TtCursor::new(tt);
115 while let Some(tt) = p.eat() { 28 while let Some(tt) = p.eat() {
116 let child: mbe::TokenTree = match tt { 29 let child: mbe::TokenTree = match tt {
117 tt::TokenTree::Leaf(leaf) => match leaf { 30 tt::TokenTree::Leaf(leaf) => match leaf {
@@ -142,7 +55,7 @@ fn parse_subtree(tt: &tt::Subtree) -> Option<mbe::Subtree> {
142 }) 55 })
143} 56}
144 57
145fn parse_var(p: &mut RulesParser) -> Option<mbe::Var> { 58fn parse_var(p: &mut TtCursor) -> Option<mbe::Var> {
146 let ident = p.eat_ident().unwrap(); 59 let ident = p.eat_ident().unwrap();
147 let text = ident.text.clone(); 60 let text = ident.text.clone();
148 let kind = if p.at_char(':') { 61 let kind = if p.at_char(':') {
@@ -150,8 +63,7 @@ fn parse_var(p: &mut RulesParser) -> Option<mbe::Var> {
150 if let Some(ident) = p.eat_ident() { 63 if let Some(ident) = p.eat_ident() {
151 Some(ident.text.clone()) 64 Some(ident.text.clone())
152 } else { 65 } else {
153 // ugly as hell :( 66 p.rev_bump();
154 p.pos -= 1;
155 None 67 None
156 } 68 }
157 } else { 69 } else {
@@ -160,7 +72,7 @@ fn parse_var(p: &mut RulesParser) -> Option<mbe::Var> {
160 Some(mbe::Var { text, kind }) 72 Some(mbe::Var { text, kind })
161} 73}
162 74
163fn parse_repeat(p: &mut RulesParser) -> Option<mbe::Repeat> { 75fn parse_repeat(p: &mut TtCursor) -> Option<mbe::Repeat> {
164 let subtree = p.eat_subtree().unwrap(); 76 let subtree = p.eat_subtree().unwrap();
165 let subtree = parse_subtree(subtree)?; 77 let subtree = parse_subtree(subtree)?;
166 let sep = p.eat_punct()?; 78 let sep = p.eat_punct()?;
diff --git a/crates/ra_macros/src/tt_cursor.rs b/crates/ra_macros/src/tt_cursor.rs
new file mode 100644
index 000000000..380c60b40
--- /dev/null
+++ b/crates/ra_macros/src/tt_cursor.rs
@@ -0,0 +1,92 @@
1use crate::tt;
2
3pub(crate) struct TtCursor<'a> {
4 subtree: &'a tt::Subtree,
5 pos: usize,
6}
7
8impl<'a> TtCursor<'a> {
9 pub(crate) fn new(subtree: &'a tt::Subtree) -> TtCursor<'a> {
10 TtCursor { subtree, pos: 0 }
11 }
12
13 pub(crate) fn is_eof(&self) -> bool {
14 self.pos == self.subtree.token_trees.len()
15 }
16
17 pub(crate) fn current(&self) -> Option<&'a tt::TokenTree> {
18 self.subtree.token_trees.get(self.pos)
19 }
20
21 pub(crate) fn at_punct(&self) -> Option<&'a tt::Punct> {
22 match self.current() {
23 Some(tt::TokenTree::Leaf(tt::Leaf::Punct(it))) => Some(it),
24 _ => None,
25 }
26 }
27
28 pub(crate) fn at_char(&self, char: char) -> bool {
29 match self.at_punct() {
30 Some(tt::Punct { char: c }) if *c == char => true,
31 _ => false,
32 }
33 }
34
35 pub(crate) fn at_ident(&mut self) -> Option<&'a tt::Ident> {
36 match self.current() {
37 Some(tt::TokenTree::Leaf(tt::Leaf::Ident(i))) => Some(i),
38 _ => None,
39 }
40 }
41
42 pub(crate) fn bump(&mut self) {
43 self.pos += 1;
44 }
45 pub(crate) fn rev_bump(&mut self) {
46 self.pos -= 1;
47 }
48
49 pub(crate) fn eat(&mut self) -> Option<&'a tt::TokenTree> {
50 match self.current() {
51 Some(it) => {
52 self.bump();
53 Some(it)
54 }
55 None => None,
56 }
57 }
58
59 pub(crate) fn eat_subtree(&mut self) -> Option<&'a tt::Subtree> {
60 match self.current()? {
61 tt::TokenTree::Subtree(sub) => {
62 self.bump();
63 Some(sub)
64 }
65 _ => return None,
66 }
67 }
68
69 pub(crate) fn eat_punct(&mut self) -> Option<&'a tt::Punct> {
70 if let Some(it) = self.at_punct() {
71 self.bump();
72 return Some(it);
73 }
74 None
75 }
76
77 pub(crate) fn eat_ident(&mut self) -> Option<&'a tt::Ident> {
78 if let Some(i) = self.at_ident() {
79 self.bump();
80 return Some(i);
81 }
82 None
83 }
84
85 pub(crate) fn expect_char(&mut self, char: char) -> Option<()> {
86 if self.at_char(char) {
87 self.bump();
88 return Some(());
89 }
90 None
91 }
92}