Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/mbe/src/parser.rs')
-rw-r--r--crates/mbe/src/parser.rs45
1 files changed, 31 insertions, 14 deletions
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs
index 0cce4146fb..f0a9dd4a51 100644
--- a/crates/mbe/src/parser.rs
+++ b/crates/mbe/src/parser.rs
@@ -6,12 +6,38 @@ use syntax::SmolStr;
use crate::{tt_iter::TtIter, ParseError};
-pub(crate) fn parse_template(template: &tt::Subtree) -> Result<Vec<Op>, ParseError> {
- parse_inner(template, Mode::Template).into_iter().collect()
-}
+/// Consider
+///
+/// ```
+/// macro_rules! an_macro {
+/// ($x:expr + $y:expr) => ($y * $x)
+/// }
+/// ```
+///
+/// Stuff to the left of `=>` is a [`MetaTemplate`] pattern (which is matched
+/// with input).
+///
+/// Stuff to the right is a [`MetaTemplate`] template which is used to produce
+/// output.
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub(crate) struct MetaTemplate(pub(crate) Vec<Op>);
+
+impl MetaTemplate {
+ pub(crate) fn parse_pattern(pattern: &tt::Subtree) -> Result<MetaTemplate, ParseError> {
+ let ops =
+ parse_inner(pattern, Mode::Pattern).into_iter().collect::<Result<_, ParseError>>()?;
+ Ok(MetaTemplate(ops))
+ }
+
+ pub(crate) fn parse_template(template: &tt::Subtree) -> Result<MetaTemplate, ParseError> {
+ let ops =
+ parse_inner(template, Mode::Template).into_iter().collect::<Result<_, ParseError>>()?;
+ Ok(MetaTemplate(ops))
+ }
-pub(crate) fn parse_pattern(pattern: &tt::Subtree) -> Result<Vec<Op>, ParseError> {
- parse_inner(pattern, Mode::Pattern).into_iter().collect()
+ pub(crate) fn iter(&self) -> impl Iterator<Item = &Op> {
+ self.0.iter()
+ }
}
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -36,15 +62,6 @@ pub(crate) enum Separator {
Puncts(SmallVec<[tt::Punct; 3]>),
}
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub(crate) struct MetaTemplate(pub(crate) Vec<Op>);
-
-impl MetaTemplate {
- pub(crate) fn iter(&self) -> impl Iterator<Item = &Op> {
- self.0.iter()
- }
-}
-
// Note that when we compare a Separator, we just care about its textual value.
impl PartialEq for Separator {
fn eq(&self, other: &Separator) -> bool {