diff options
Diffstat (limited to 'crates/mbe/src/mbe_expander')
-rw-r--r-- | crates/mbe/src/mbe_expander/matcher.rs | 32 | ||||
-rw-r--r-- | crates/mbe/src/mbe_expander/transcriber.rs | 29 |
2 files changed, 32 insertions, 29 deletions
diff --git a/crates/mbe/src/mbe_expander/matcher.rs b/crates/mbe/src/mbe_expander/matcher.rs index 44722c0f1..ab5f87c48 100644 --- a/crates/mbe/src/mbe_expander/matcher.rs +++ b/crates/mbe/src/mbe_expander/matcher.rs | |||
@@ -2,10 +2,10 @@ | |||
2 | 2 | ||
3 | use crate::{ | 3 | use crate::{ |
4 | mbe_expander::{Binding, Bindings, Fragment}, | 4 | mbe_expander::{Binding, Bindings, Fragment}, |
5 | parser::{parse_pattern, Op, RepeatKind, Separator}, | 5 | parser::{Op, RepeatKind, Separator}, |
6 | subtree_source::SubtreeTokenSource, | 6 | subtree_source::SubtreeTokenSource, |
7 | tt_iter::TtIter, | 7 | tt_iter::TtIter, |
8 | ExpandError, | 8 | ExpandError, MetaTemplate, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | use super::ExpandResult; | 11 | use super::ExpandResult; |
@@ -83,7 +83,7 @@ impl Match { | |||
83 | // sense to try using it. Matching errors are added to the `Match`. It might | 83 | // sense to try using it. Matching errors are added to the `Match`. It might |
84 | // make sense to make pattern parsing a separate step? | 84 | // make sense to make pattern parsing a separate step? |
85 | 85 | ||
86 | pub(super) fn match_(pattern: &tt::Subtree, src: &tt::Subtree) -> Result<Match, ExpandError> { | 86 | pub(super) fn match_(pattern: &MetaTemplate, src: &tt::Subtree) -> Result<Match, ExpandError> { |
87 | assert!(pattern.delimiter == None); | 87 | assert!(pattern.delimiter == None); |
88 | 88 | ||
89 | let mut res = Match::default(); | 89 | let mut res = Match::default(); |
@@ -101,12 +101,12 @@ pub(super) fn match_(pattern: &tt::Subtree, src: &tt::Subtree) -> Result<Match, | |||
101 | 101 | ||
102 | fn match_subtree( | 102 | fn match_subtree( |
103 | res: &mut Match, | 103 | res: &mut Match, |
104 | pattern: &tt::Subtree, | 104 | pattern: &MetaTemplate, |
105 | src: &mut TtIter, | 105 | src: &mut TtIter, |
106 | ) -> Result<(), ExpandError> { | 106 | ) -> Result<(), ExpandError> { |
107 | for op in parse_pattern(pattern) { | 107 | for op in pattern.iter() { |
108 | match op? { | 108 | match op.as_ref().map_err(|err| err.clone())? { |
109 | Op::TokenTree(tt::TokenTree::Leaf(lhs)) => { | 109 | Op::Leaf(lhs) => { |
110 | let rhs = match src.expect_leaf() { | 110 | let rhs = match src.expect_leaf() { |
111 | Ok(l) => l, | 111 | Ok(l) => l, |
112 | Err(()) => { | 112 | Err(()) => { |
@@ -132,7 +132,7 @@ fn match_subtree( | |||
132 | } | 132 | } |
133 | } | 133 | } |
134 | } | 134 | } |
135 | Op::TokenTree(tt::TokenTree::Subtree(lhs)) => { | 135 | Op::Subtree(lhs) => { |
136 | let rhs = match src.expect_subtree() { | 136 | let rhs = match src.expect_subtree() { |
137 | Ok(s) => s, | 137 | Ok(s) => s, |
138 | Err(()) => { | 138 | Err(()) => { |
@@ -172,7 +172,7 @@ fn match_subtree( | |||
172 | } | 172 | } |
173 | } | 173 | } |
174 | Op::Repeat { subtree, kind, separator } => { | 174 | Op::Repeat { subtree, kind, separator } => { |
175 | match_repeat(res, subtree, kind, separator, src)?; | 175 | match_repeat(res, subtree, *kind, separator, src)?; |
176 | } | 176 | } |
177 | } | 177 | } |
178 | } | 178 | } |
@@ -372,9 +372,9 @@ impl<'a> TtIter<'a> { | |||
372 | 372 | ||
373 | pub(super) fn match_repeat( | 373 | pub(super) fn match_repeat( |
374 | res: &mut Match, | 374 | res: &mut Match, |
375 | pattern: &tt::Subtree, | 375 | pattern: &MetaTemplate, |
376 | kind: RepeatKind, | 376 | kind: RepeatKind, |
377 | separator: Option<Separator>, | 377 | separator: &Option<Separator>, |
378 | src: &mut TtIter, | 378 | src: &mut TtIter, |
379 | ) -> Result<(), ExpandError> { | 379 | ) -> Result<(), ExpandError> { |
380 | // Dirty hack to make macro-expansion terminate. | 380 | // Dirty hack to make macro-expansion terminate. |
@@ -489,12 +489,12 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult<Option<Fragmen | |||
489 | result.map(|tt| if kind == "expr" { tt.map(Fragment::Ast) } else { tt.map(Fragment::Tokens) }) | 489 | result.map(|tt| if kind == "expr" { tt.map(Fragment::Ast) } else { tt.map(Fragment::Tokens) }) |
490 | } | 490 | } |
491 | 491 | ||
492 | fn collect_vars(buf: &mut Vec<SmolStr>, pattern: &tt::Subtree) -> Result<(), ExpandError> { | 492 | fn collect_vars(buf: &mut Vec<SmolStr>, pattern: &MetaTemplate) -> Result<(), ExpandError> { |
493 | for op in parse_pattern(pattern) { | 493 | for op in pattern.iter() { |
494 | match op? { | 494 | match op.as_ref().map_err(|e| e.clone())? { |
495 | Op::Var { name, .. } => buf.push(name.clone()), | 495 | Op::Var { name, .. } => buf.push(name.clone()), |
496 | Op::TokenTree(tt::TokenTree::Leaf(_)) => (), | 496 | Op::Leaf(_) => (), |
497 | Op::TokenTree(tt::TokenTree::Subtree(subtree)) => collect_vars(buf, subtree)?, | 497 | Op::Subtree(subtree) => collect_vars(buf, subtree)?, |
498 | Op::Repeat { subtree, .. } => collect_vars(buf, subtree)?, | 498 | Op::Repeat { subtree, .. } => collect_vars(buf, subtree)?, |
499 | } | 499 | } |
500 | } | 500 | } |
diff --git a/crates/mbe/src/mbe_expander/transcriber.rs b/crates/mbe/src/mbe_expander/transcriber.rs index 57592dc92..720531237 100644 --- a/crates/mbe/src/mbe_expander/transcriber.rs +++ b/crates/mbe/src/mbe_expander/transcriber.rs | |||
@@ -6,8 +6,8 @@ use syntax::SmolStr; | |||
6 | use super::ExpandResult; | 6 | use super::ExpandResult; |
7 | use crate::{ | 7 | use crate::{ |
8 | mbe_expander::{Binding, Bindings, Fragment}, | 8 | mbe_expander::{Binding, Bindings, Fragment}, |
9 | parser::{parse_template, Op, RepeatKind, Separator}, | 9 | parser::{Op, RepeatKind, Separator}, |
10 | ExpandError, | 10 | ExpandError, MetaTemplate, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | impl Bindings { | 13 | impl Bindings { |
@@ -50,7 +50,10 @@ impl Bindings { | |||
50 | } | 50 | } |
51 | } | 51 | } |
52 | 52 | ||
53 | pub(super) fn transcribe(template: &tt::Subtree, bindings: &Bindings) -> ExpandResult<tt::Subtree> { | 53 | pub(super) fn transcribe( |
54 | template: &MetaTemplate, | ||
55 | bindings: &Bindings, | ||
56 | ) -> ExpandResult<tt::Subtree> { | ||
54 | assert!(template.delimiter == None); | 57 | assert!(template.delimiter == None); |
55 | let mut ctx = ExpandCtx { bindings: &bindings, nesting: Vec::new() }; | 58 | let mut ctx = ExpandCtx { bindings: &bindings, nesting: Vec::new() }; |
56 | let mut arena: Vec<tt::TokenTree> = Vec::new(); | 59 | let mut arena: Vec<tt::TokenTree> = Vec::new(); |
@@ -76,35 +79,35 @@ struct ExpandCtx<'a> { | |||
76 | 79 | ||
77 | fn expand_subtree( | 80 | fn expand_subtree( |
78 | ctx: &mut ExpandCtx, | 81 | ctx: &mut ExpandCtx, |
79 | template: &tt::Subtree, | 82 | template: &MetaTemplate, |
80 | arena: &mut Vec<tt::TokenTree>, | 83 | arena: &mut Vec<tt::TokenTree>, |
81 | ) -> ExpandResult<tt::Subtree> { | 84 | ) -> ExpandResult<tt::Subtree> { |
82 | // remember how many elements are in the arena now - when returning, we want to drain exactly how many elements we added. This way, the recursive uses of the arena get their own "view" of the arena, but will reuse the allocation | 85 | // remember how many elements are in the arena now - when returning, we want to drain exactly how many elements we added. This way, the recursive uses of the arena get their own "view" of the arena, but will reuse the allocation |
83 | let start_elements = arena.len(); | 86 | let start_elements = arena.len(); |
84 | let mut err = None; | 87 | let mut err = None; |
85 | for op in parse_template(template) { | 88 | for op in template.iter() { |
86 | let op = match op { | 89 | let op = match op { |
87 | Ok(op) => op, | 90 | Ok(op) => op, |
88 | Err(e) => { | 91 | Err(e) => { |
89 | err = Some(e); | 92 | err = Some(e.clone()); |
90 | break; | 93 | break; |
91 | } | 94 | } |
92 | }; | 95 | }; |
93 | match op { | 96 | match op { |
94 | Op::TokenTree(tt @ tt::TokenTree::Leaf(..)) => arena.push(tt.clone()), | 97 | Op::Leaf(tt) => arena.push(tt.clone().into()), |
95 | Op::TokenTree(tt::TokenTree::Subtree(tt)) => { | 98 | Op::Subtree(tt) => { |
96 | let ExpandResult { value: tt, err: e } = expand_subtree(ctx, tt, arena); | 99 | let ExpandResult { value: tt, err: e } = expand_subtree(ctx, &tt, arena); |
97 | err = err.or(e); | 100 | err = err.or(e); |
98 | arena.push(tt.into()); | 101 | arena.push(tt.into()); |
99 | } | 102 | } |
100 | Op::Var { name, .. } => { | 103 | Op::Var { name, .. } => { |
101 | let ExpandResult { value: fragment, err: e } = expand_var(ctx, name); | 104 | let ExpandResult { value: fragment, err: e } = expand_var(ctx, &name); |
102 | err = err.or(e); | 105 | err = err.or(e); |
103 | push_fragment(arena, fragment); | 106 | push_fragment(arena, fragment); |
104 | } | 107 | } |
105 | Op::Repeat { subtree, kind, separator } => { | 108 | Op::Repeat { subtree, kind, separator } => { |
106 | let ExpandResult { value: fragment, err: e } = | 109 | let ExpandResult { value: fragment, err: e } = |
107 | expand_repeat(ctx, subtree, kind, separator, arena); | 110 | expand_repeat(ctx, subtree, *kind, separator, arena); |
108 | err = err.or(e); | 111 | err = err.or(e); |
109 | push_fragment(arena, fragment) | 112 | push_fragment(arena, fragment) |
110 | } | 113 | } |
@@ -161,9 +164,9 @@ fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> { | |||
161 | 164 | ||
162 | fn expand_repeat( | 165 | fn expand_repeat( |
163 | ctx: &mut ExpandCtx, | 166 | ctx: &mut ExpandCtx, |
164 | template: &tt::Subtree, | 167 | template: &MetaTemplate, |
165 | kind: RepeatKind, | 168 | kind: RepeatKind, |
166 | separator: Option<Separator>, | 169 | separator: &Option<Separator>, |
167 | arena: &mut Vec<tt::TokenTree>, | 170 | arena: &mut Vec<tt::TokenTree>, |
168 | ) -> ExpandResult<Fragment> { | 171 | ) -> ExpandResult<Fragment> { |
169 | let mut buf: Vec<tt::TokenTree> = Vec::new(); | 172 | let mut buf: Vec<tt::TokenTree> = Vec::new(); |