Skip to content

Commit 60c5449

Browse files
bors[bot]matklad
andauthored
Merge #10431
10431: internal: cleanup mbe a bit r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents e504f8a + 4e35227 commit 60c5449

File tree

3 files changed

+95
-84
lines changed

3 files changed

+95
-84
lines changed

crates/mbe/src/expander/matcher.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use std::rc::Rc;
6363

6464
use crate::{
6565
expander::{Binding, Bindings, Fragment},
66-
parser::{Op, OpDelimited, OpDelimitedIter, RepeatKind, Separator},
66+
parser::{Op, RepeatKind, Separator},
6767
tt_iter::TtIter,
6868
ExpandError, MetaTemplate,
6969
};
@@ -750,6 +750,64 @@ fn collect_vars(buf: &mut Vec<SmolStr>, pattern: &MetaTemplate) {
750750
}
751751
}
752752

753+
impl MetaTemplate {
754+
fn iter_delimited<'a>(&'a self, delimited: Option<&'a tt::Delimiter>) -> OpDelimitedIter<'a> {
755+
OpDelimitedIter { inner: &self.0, idx: 0, delimited }
756+
}
757+
}
758+
759+
#[derive(Debug, Clone, Copy)]
760+
enum OpDelimited<'a> {
761+
Op(&'a Op),
762+
Open,
763+
Close,
764+
}
765+
766+
#[derive(Debug, Clone, Copy)]
767+
struct OpDelimitedIter<'a> {
768+
inner: &'a [Op],
769+
delimited: Option<&'a tt::Delimiter>,
770+
idx: usize,
771+
}
772+
773+
impl<'a> OpDelimitedIter<'a> {
774+
fn is_eof(&self) -> bool {
775+
let len = self.inner.len() + if self.delimited.is_some() { 2 } else { 0 };
776+
self.idx >= len
777+
}
778+
779+
fn peek(&self) -> Option<OpDelimited<'a>> {
780+
match self.delimited {
781+
None => self.inner.get(self.idx).map(OpDelimited::Op),
782+
Some(_) => match self.idx {
783+
0 => Some(OpDelimited::Open),
784+
i if i == self.inner.len() + 1 => Some(OpDelimited::Close),
785+
i => self.inner.get(i - 1).map(OpDelimited::Op),
786+
},
787+
}
788+
}
789+
790+
fn reset(&self) -> Self {
791+
Self { inner: self.inner, idx: 0, delimited: self.delimited }
792+
}
793+
}
794+
795+
impl<'a> Iterator for OpDelimitedIter<'a> {
796+
type Item = OpDelimited<'a>;
797+
798+
fn next(&mut self) -> Option<Self::Item> {
799+
let res = self.peek();
800+
self.idx += 1;
801+
res
802+
}
803+
804+
fn size_hint(&self) -> (usize, Option<usize>) {
805+
let len = self.inner.len() + if self.delimited.is_some() { 2 } else { 0 };
806+
let remain = len.saturating_sub(self.idx);
807+
(remain, Some(remain))
808+
}
809+
}
810+
753811
impl<'a> TtIter<'a> {
754812
fn expect_separator(&mut self, separator: &Separator, idx: usize) -> bool {
755813
let mut fork = self.clone();

crates/mbe/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ mod token_map;
1919
use std::fmt;
2020

2121
use crate::{
22-
parser::{parse_pattern, parse_template, MetaTemplate, Op},
22+
parser::{MetaTemplate, Op},
2323
tt_iter::TtIter,
2424
};
2525

@@ -275,8 +275,8 @@ impl Rule {
275275
.expect_subtree()
276276
.map_err(|()| ParseError::Expected("expected subtree".to_string()))?;
277277

278-
let lhs = MetaTemplate(parse_pattern(lhs)?);
279-
let rhs = MetaTemplate(parse_template(rhs)?);
278+
let lhs = MetaTemplate::parse_pattern(lhs)?;
279+
let rhs = MetaTemplate::parse_template(rhs)?;
280280

281281
Ok(crate::Rule { lhs, rhs })
282282
}

crates/mbe/src/parser.rs

Lines changed: 33 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3,75 +3,48 @@
33
44
use smallvec::SmallVec;
55
use syntax::SmolStr;
6-
use tt::Delimiter;
76

87
use crate::{tt_iter::TtIter, ParseError};
98

9+
/// Consider
10+
///
11+
/// ```
12+
/// macro_rules! an_macro {
13+
/// ($x:expr + $y:expr) => ($y * $x)
14+
/// }
15+
/// ```
16+
///
17+
/// Stuff to the left of `=>` is a [`MetaTemplate`] pattern (which is matched
18+
/// with input).
19+
///
20+
/// Stuff to the right is a [`MetaTemplate`] template which is used to produce
21+
/// output.
1022
#[derive(Clone, Debug, PartialEq, Eq)]
1123
pub(crate) struct MetaTemplate(pub(crate) Vec<Op>);
1224

13-
#[derive(Debug, Clone, Copy)]
14-
pub(crate) enum OpDelimited<'a> {
15-
Op(&'a Op),
16-
Open,
17-
Close,
18-
}
19-
20-
#[derive(Debug, Clone, Copy)]
21-
pub(crate) struct OpDelimitedIter<'a> {
22-
inner: &'a Vec<Op>,
23-
delimited: Option<&'a Delimiter>,
24-
idx: usize,
25-
}
26-
27-
impl<'a> OpDelimitedIter<'a> {
28-
pub(crate) fn is_eof(&self) -> bool {
29-
let len = self.inner.len() + if self.delimited.is_some() { 2 } else { 0 };
30-
self.idx >= len
31-
}
32-
33-
pub(crate) fn peek(&self) -> Option<OpDelimited<'a>> {
34-
match self.delimited {
35-
None => self.inner.get(self.idx).map(OpDelimited::Op),
36-
Some(_) => match self.idx {
37-
0 => Some(OpDelimited::Open),
38-
i if i == self.inner.len() + 1 => Some(OpDelimited::Close),
39-
i => self.inner.get(i - 1).map(OpDelimited::Op),
40-
},
41-
}
42-
}
43-
44-
pub(crate) fn reset(&self) -> Self {
45-
Self { inner: self.inner, idx: 0, delimited: self.delimited }
25+
impl MetaTemplate {
26+
pub(crate) fn parse_pattern(pattern: &tt::Subtree) -> Result<MetaTemplate, ParseError> {
27+
MetaTemplate::parse(pattern, Mode::Pattern)
4628
}
47-
}
48-
49-
impl<'a> Iterator for OpDelimitedIter<'a> {
50-
type Item = OpDelimited<'a>;
5129

52-
fn next(&mut self) -> Option<Self::Item> {
53-
let res = self.peek();
54-
self.idx += 1;
55-
res
30+
pub(crate) fn parse_template(template: &tt::Subtree) -> Result<MetaTemplate, ParseError> {
31+
MetaTemplate::parse(template, Mode::Template)
5632
}
5733

58-
fn size_hint(&self) -> (usize, Option<usize>) {
59-
let len = self.inner.len() + if self.delimited.is_some() { 2 } else { 0 };
60-
let remain = len.saturating_sub(self.idx);
61-
(remain, Some(remain))
62-
}
63-
}
64-
65-
impl<'a> MetaTemplate {
6634
pub(crate) fn iter(&self) -> impl Iterator<Item = &Op> {
6735
self.0.iter()
6836
}
6937

70-
pub(crate) fn iter_delimited(
71-
&'a self,
72-
delimited: Option<&'a Delimiter>,
73-
) -> OpDelimitedIter<'a> {
74-
OpDelimitedIter { inner: &self.0, idx: 0, delimited }
38+
fn parse(tt: &tt::Subtree, mode: Mode) -> Result<MetaTemplate, ParseError> {
39+
let mut src = TtIter::new(tt);
40+
41+
let mut res = Vec::new();
42+
while let Some(first) = src.next() {
43+
let op = next_op(first, &mut src, mode)?;
44+
res.push(op)
45+
}
46+
47+
Ok(MetaTemplate(res))
7548
}
7649
}
7750

@@ -80,7 +53,7 @@ pub(crate) enum Op {
8053
Var { name: SmolStr, kind: Option<SmolStr>, id: tt::TokenId },
8154
Repeat { tokens: MetaTemplate, kind: RepeatKind, separator: Option<Separator> },
8255
Leaf(tt::Leaf),
83-
Subtree { tokens: MetaTemplate, delimiter: Option<Delimiter> },
56+
Subtree { tokens: MetaTemplate, delimiter: Option<tt::Delimiter> },
8457
}
8558

8659
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -125,29 +98,12 @@ impl Separator {
12598
}
12699
}
127100

128-
pub(crate) fn parse_template(template: &tt::Subtree) -> Result<Vec<Op>, ParseError> {
129-
parse_inner(template, Mode::Template).into_iter().collect()
130-
}
131-
132-
pub(crate) fn parse_pattern(pattern: &tt::Subtree) -> Result<Vec<Op>, ParseError> {
133-
parse_inner(pattern, Mode::Pattern).into_iter().collect()
134-
}
135-
136101
#[derive(Clone, Copy)]
137102
enum Mode {
138103
Pattern,
139104
Template,
140105
}
141106

142-
fn parse_inner(tt: &tt::Subtree, mode: Mode) -> Vec<Result<Op, ParseError>> {
143-
let mut src = TtIter::new(tt);
144-
std::iter::from_fn(move || {
145-
let first = src.next()?;
146-
Some(next_op(first, &mut src, mode))
147-
})
148-
.collect()
149-
}
150-
151107
macro_rules! err {
152108
($($tt:tt)*) => {
153109
ParseError::UnexpectedToken(($($tt)*).to_string())
@@ -171,10 +127,8 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul
171127
match second {
172128
tt::TokenTree::Subtree(subtree) => {
173129
let (separator, kind) = parse_repeat(src)?;
174-
let tokens = parse_inner(subtree, mode)
175-
.into_iter()
176-
.collect::<Result<Vec<Op>, ParseError>>()?;
177-
Op::Repeat { tokens: MetaTemplate(tokens), separator, kind }
130+
let tokens = MetaTemplate::parse(subtree, mode)?;
131+
Op::Repeat { tokens, separator, kind }
178132
}
179133
tt::TokenTree::Leaf(leaf) => match leaf {
180134
tt::Leaf::Punct(_) => {
@@ -205,9 +159,8 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul
205159
}
206160
tt::TokenTree::Leaf(tt) => Op::Leaf(tt.clone()),
207161
tt::TokenTree::Subtree(subtree) => {
208-
let tokens =
209-
parse_inner(subtree, mode).into_iter().collect::<Result<Vec<Op>, ParseError>>()?;
210-
Op::Subtree { tokens: MetaTemplate(tokens), delimiter: subtree.delimiter }
162+
let tokens = MetaTemplate::parse(subtree, mode)?;
163+
Op::Subtree { tokens, delimiter: subtree.delimiter }
211164
}
212165
};
213166
Ok(res)

0 commit comments

Comments
 (0)