aboutsummaryrefslogtreecommitdiff
path: root/crates/mbe/src/expander/matcher.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mbe/src/expander/matcher.rs')
-rw-r--r--crates/mbe/src/expander/matcher.rs94
1 files changed, 50 insertions, 44 deletions
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs
index 987a4f676..800931cd1 100644
--- a/crates/mbe/src/expander/matcher.rs
+++ b/crates/mbe/src/expander/matcher.rs
@@ -70,7 +70,7 @@ pub(super) struct Match {
70} 70}
71 71
72impl Match { 72impl Match {
73 pub(super) fn add_err(&mut self, err: ExpandError) { 73 fn add_err(&mut self, err: ExpandError) {
74 let prev_err = self.err.take(); 74 let prev_err = self.err.take();
75 self.err = prev_err.or(Some(err)); 75 self.err = prev_err.or(Some(err));
76 self.err_count += 1; 76 self.err_count += 1;
@@ -79,12 +79,10 @@ impl Match {
79 79
80/// Matching errors are added to the `Match`. 80/// Matching errors are added to the `Match`.
81pub(super) fn match_(pattern: &MetaTemplate, src: &tt::Subtree) -> Match { 81pub(super) fn match_(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
82 assert!(pattern.delimiter == None);
83
84 let mut res = Match::default(); 82 let mut res = Match::default();
85 let mut src = TtIter::new(src); 83 let mut src = TtIter::new(src);
86 84
87 match_subtree(&mut res, pattern, &mut src); 85 match_tokens(&mut res, pattern, &mut src);
88 86
89 if src.len() > 0 { 87 if src.len() > 0 {
90 res.unmatched_tts += src.len(); 88 res.unmatched_tts += src.len();
@@ -94,36 +92,16 @@ pub(super) fn match_(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
94 res 92 res
95} 93}
96 94
97fn match_subtree(res: &mut Match, pattern: &MetaTemplate, src: &mut TtIter) { 95fn match_tokens(res: &mut Match, pattern: &MetaTemplate, src: &mut TtIter) {
98 for op in pattern.iter() { 96 for op in pattern.iter() {
99 match op { 97 match op {
100 Op::Leaf(lhs) => { 98 Op::Leaf(lhs) => {
101 let rhs = match src.expect_leaf() { 99 if let Err(err) = match_leaf(lhs, src) {
102 Ok(l) => l, 100 res.add_err(err);
103 Err(()) => { 101 continue;
104 res.add_err(err!("expected leaf: `{}`", lhs));
105 continue;
106 }
107 };
108 match (lhs, rhs) {
109 (
110 tt::Leaf::Punct(tt::Punct { char: lhs, .. }),
111 tt::Leaf::Punct(tt::Punct { char: rhs, .. }),
112 ) if lhs == rhs => (),
113 (
114 tt::Leaf::Ident(tt::Ident { text: lhs, .. }),
115 tt::Leaf::Ident(tt::Ident { text: rhs, .. }),
116 ) if lhs == rhs => (),
117 (
118 tt::Leaf::Literal(tt::Literal { text: lhs, .. }),
119 tt::Leaf::Literal(tt::Literal { text: rhs, .. }),
120 ) if lhs == rhs => (),
121 _ => {
122 res.add_err(ExpandError::UnexpectedToken);
123 }
124 } 102 }
125 } 103 }
126 Op::Subtree(lhs) => { 104 Op::Subtree { tokens, delimiter: delim } => {
127 let rhs = match src.expect_subtree() { 105 let rhs = match src.expect_subtree() {
128 Ok(s) => s, 106 Ok(s) => s,
129 Err(()) => { 107 Err(()) => {
@@ -131,12 +109,12 @@ fn match_subtree(res: &mut Match, pattern: &MetaTemplate, src: &mut TtIter) {
131 continue; 109 continue;
132 } 110 }
133 }; 111 };
134 if lhs.delimiter_kind() != rhs.delimiter_kind() { 112 if delim.map(|it| it.kind) != rhs.delimiter_kind() {
135 res.add_err(err!("mismatched delimiter")); 113 res.add_err(err!("mismatched delimiter"));
136 continue; 114 continue;
137 } 115 }
138 let mut src = TtIter::new(rhs); 116 let mut src = TtIter::new(rhs);
139 match_subtree(res, lhs, &mut src); 117 match_tokens(res, tokens, &mut src);
140 if src.len() > 0 { 118 if src.len() > 0 {
141 res.add_err(err!("leftover tokens")); 119 res.add_err(err!("leftover tokens"));
142 } 120 }
@@ -162,14 +140,42 @@ fn match_subtree(res: &mut Match, pattern: &MetaTemplate, src: &mut TtIter) {
162 res.add_err(err); 140 res.add_err(err);
163 } 141 }
164 } 142 }
165 Op::Repeat { subtree, kind, separator } => { 143 Op::Repeat { tokens: subtree, kind, separator } => {
166 match_repeat(res, subtree, *kind, separator, src); 144 match_repeat(res, subtree, *kind, separator, src);
167 } 145 }
168 } 146 }
169 } 147 }
170} 148}
171 149
172pub(super) fn match_repeat( 150fn match_leaf(lhs: &tt::Leaf, src: &mut TtIter) -> Result<(), ExpandError> {
151 let rhs = match src.expect_leaf() {
152 Ok(l) => l,
153 Err(()) => {
154 return Err(err!("expected leaf: `{}`", lhs));
155 }
156 };
157 match (lhs, rhs) {
158 (
159 tt::Leaf::Punct(tt::Punct { char: lhs, .. }),
160 tt::Leaf::Punct(tt::Punct { char: rhs, .. }),
161 ) if lhs == rhs => (),
162 (
163 tt::Leaf::Ident(tt::Ident { text: lhs, .. }),
164 tt::Leaf::Ident(tt::Ident { text: rhs, .. }),
165 ) if lhs == rhs => (),
166 (
167 tt::Leaf::Literal(tt::Literal { text: lhs, .. }),
168 tt::Leaf::Literal(tt::Literal { text: rhs, .. }),
169 ) if lhs == rhs => (),
170 _ => {
171 return Err(ExpandError::UnexpectedToken);
172 }
173 }
174
175 Ok(())
176}
177
178fn match_repeat(
173 res: &mut Match, 179 res: &mut Match,
174 pattern: &MetaTemplate, 180 pattern: &MetaTemplate,
175 kind: RepeatKind, 181 kind: RepeatKind,
@@ -191,7 +197,7 @@ pub(super) fn match_repeat(
191 } 197 }
192 198
193 let mut nested = Match::default(); 199 let mut nested = Match::default();
194 match_subtree(&mut nested, pattern, &mut fork); 200 match_tokens(&mut nested, pattern, &mut fork);
195 if nested.err.is_none() { 201 if nested.err.is_none() {
196 limit -= 1; 202 limit -= 1;
197 if limit == 0 { 203 if limit == 0 {
@@ -292,8 +298,8 @@ fn collect_vars(buf: &mut Vec<SmolStr>, pattern: &MetaTemplate) {
292 match op { 298 match op {
293 Op::Var { name, .. } => buf.push(name.clone()), 299 Op::Var { name, .. } => buf.push(name.clone()),
294 Op::Leaf(_) => (), 300 Op::Leaf(_) => (),
295 Op::Subtree(subtree) => collect_vars(buf, subtree), 301 Op::Subtree { tokens, .. } => collect_vars(buf, tokens),
296 Op::Repeat { subtree, .. } => collect_vars(buf, subtree), 302 Op::Repeat { tokens, .. } => collect_vars(buf, tokens),
297 } 303 }
298 } 304 }
299} 305}
@@ -325,7 +331,7 @@ impl<'a> TtIter<'a> {
325 ok 331 ok
326 } 332 }
327 333
328 pub(crate) fn expect_tt(&mut self) -> Result<tt::TokenTree, ()> { 334 fn expect_tt(&mut self) -> Result<tt::TokenTree, ()> {
329 match self.peek_n(0) { 335 match self.peek_n(0) {
330 Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) if punct.char == '\'' => { 336 Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) if punct.char == '\'' => {
331 return self.expect_lifetime(); 337 return self.expect_lifetime();
@@ -386,7 +392,7 @@ impl<'a> TtIter<'a> {
386 } 392 }
387 } 393 }
388 394
389 pub(crate) fn expect_lifetime(&mut self) -> Result<tt::TokenTree, ()> { 395 fn expect_lifetime(&mut self) -> Result<tt::TokenTree, ()> {
390 let punct = self.expect_punct()?; 396 let punct = self.expect_punct()?;
391 if punct.char != '\'' { 397 if punct.char != '\'' {
392 return Err(()); 398 return Err(());
@@ -403,13 +409,13 @@ impl<'a> TtIter<'a> {
403 .into()) 409 .into())
404 } 410 }
405 411
406 pub(crate) fn expect_fragment( 412 fn expect_fragment(
407 &mut self, 413 &mut self,
408 fragment_kind: parser::FragmentKind, 414 fragment_kind: parser::FragmentKind,
409 ) -> ExpandResult<Option<tt::TokenTree>> { 415 ) -> ExpandResult<Option<tt::TokenTree>> {
410 pub(crate) struct OffsetTokenSink<'a> { 416 struct OffsetTokenSink<'a> {
411 pub(crate) cursor: Cursor<'a>, 417 cursor: Cursor<'a>,
412 pub(crate) error: bool, 418 error: bool,
413 } 419 }
414 420
415 impl<'a> TreeSink for OffsetTokenSink<'a> { 421 impl<'a> TreeSink for OffsetTokenSink<'a> {
@@ -465,7 +471,7 @@ impl<'a> TtIter<'a> {
465 ExpandResult { value: res, err } 471 ExpandResult { value: res, err }
466 } 472 }
467 473
468 pub(crate) fn eat_vis(&mut self) -> Option<tt::TokenTree> { 474 fn eat_vis(&mut self) -> Option<tt::TokenTree> {
469 let mut fork = self.clone(); 475 let mut fork = self.clone();
470 match fork.expect_fragment(Visibility) { 476 match fork.expect_fragment(Visibility) {
471 ExpandResult { value: tt, err: None } => { 477 ExpandResult { value: tt, err: None } => {
@@ -476,7 +482,7 @@ impl<'a> TtIter<'a> {
476 } 482 }
477 } 483 }
478 484
479 pub(crate) fn eat_char(&mut self, c: char) -> Option<tt::TokenTree> { 485 fn eat_char(&mut self, c: char) -> Option<tt::TokenTree> {
480 let mut fork = self.clone(); 486 let mut fork = self.clone();
481 match fork.expect_char(c) { 487 match fork.expect_char(c) {
482 Ok(_) => { 488 Ok(_) => {