diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs index 7d8f97c775..233ca08dc1 100644 --- a/crates/mbe/src/expander/matcher.rs +++ b/crates/mbe/src/expander/matcher.rs @@ -63,7 +63,7 @@ use std::rc::Rc; use crate::{ expander::{Binding, Bindings, Fragment}, - parser::{Op, OpDelimited, OpDelimitedIter, RepeatKind, Separator}, + parser::{Op, RepeatKind, Separator}, tt_iter::TtIter, ExpandError, MetaTemplate, }; @@ -750,6 +750,64 @@ fn collect_vars(buf: &mut Vec, pattern: &MetaTemplate) { } } +impl MetaTemplate { + fn iter_delimited<'a>(&'a self, delimited: Option<&'a tt::Delimiter>) -> OpDelimitedIter<'a> { + OpDelimitedIter { inner: &self.0, idx: 0, delimited } + } +} + +#[derive(Debug, Clone, Copy)] +enum OpDelimited<'a> { + Op(&'a Op), + Open, + Close, +} + +#[derive(Debug, Clone, Copy)] +struct OpDelimitedIter<'a> { + inner: &'a Vec, + delimited: Option<&'a tt::Delimiter>, + idx: usize, +} + +impl<'a> OpDelimitedIter<'a> { + fn is_eof(&self) -> bool { + let len = self.inner.len() + if self.delimited.is_some() { 2 } else { 0 }; + self.idx >= len + } + + fn peek(&self) -> Option> { + match self.delimited { + None => self.inner.get(self.idx).map(OpDelimited::Op), + Some(_) => match self.idx { + 0 => Some(OpDelimited::Open), + i if i == self.inner.len() + 1 => Some(OpDelimited::Close), + i => self.inner.get(i - 1).map(OpDelimited::Op), + }, + } + } + + fn reset(&self) -> Self { + Self { inner: self.inner, idx: 0, delimited: self.delimited } + } +} + +impl<'a> Iterator for OpDelimitedIter<'a> { + type Item = OpDelimited<'a>; + + fn next(&mut self) -> Option { + let res = self.peek(); + self.idx += 1; + res + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.inner.len() + if self.delimited.is_some() { 2 } else { 0 }; + let remain = len.saturating_sub(self.idx); + (remain, Some(remain)) + } +} + impl<'a> TtIter<'a> { fn expect_separator(&mut self, separator: &Separator, idx: usize) -> bool { let mut fork = self.clone(); diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs index deed884d2d..0cce4146fb 100644 --- a/crates/mbe/src/parser.rs +++ b/crates/mbe/src/parser.rs @@ -3,76 +3,15 @@ use smallvec::SmallVec; use syntax::SmolStr; -use tt::Delimiter; use crate::{tt_iter::TtIter, ParseError}; -#[derive(Clone, Debug, PartialEq, Eq)] -pub(crate) struct MetaTemplate(pub(crate) Vec); - -#[derive(Debug, Clone, Copy)] -pub(crate) enum OpDelimited<'a> { - Op(&'a Op), - Open, - Close, +pub(crate) fn parse_template(template: &tt::Subtree) -> Result, ParseError> { + parse_inner(template, Mode::Template).into_iter().collect() } -#[derive(Debug, Clone, Copy)] -pub(crate) struct OpDelimitedIter<'a> { - inner: &'a Vec, - delimited: Option<&'a Delimiter>, - idx: usize, -} - -impl<'a> OpDelimitedIter<'a> { - pub(crate) fn is_eof(&self) -> bool { - let len = self.inner.len() + if self.delimited.is_some() { 2 } else { 0 }; - self.idx >= len - } - - pub(crate) fn peek(&self) -> Option> { - match self.delimited { - None => self.inner.get(self.idx).map(OpDelimited::Op), - Some(_) => match self.idx { - 0 => Some(OpDelimited::Open), - i if i == self.inner.len() + 1 => Some(OpDelimited::Close), - i => self.inner.get(i - 1).map(OpDelimited::Op), - }, - } - } - - pub(crate) fn reset(&self) -> Self { - Self { inner: self.inner, idx: 0, delimited: self.delimited } - } -} - -impl<'a> Iterator for OpDelimitedIter<'a> { - type Item = OpDelimited<'a>; - - fn next(&mut self) -> Option { - let res = self.peek(); - self.idx += 1; - res - } - - fn size_hint(&self) -> (usize, Option) { - let len = self.inner.len() + if self.delimited.is_some() { 2 } else { 0 }; - let remain = len.saturating_sub(self.idx); - (remain, Some(remain)) - } -} - -impl<'a> MetaTemplate { - pub(crate) fn iter(&self) -> impl Iterator { - self.0.iter() - } - - pub(crate) fn iter_delimited( - &'a self, - delimited: Option<&'a Delimiter>, - ) -> OpDelimitedIter<'a> { - OpDelimitedIter { inner: &self.0, idx: 0, delimited } - } +pub(crate) fn parse_pattern(pattern: &tt::Subtree) -> Result, ParseError> { + parse_inner(pattern, Mode::Pattern).into_iter().collect() } #[derive(Clone, Debug, PartialEq, Eq)] @@ -80,7 +19,7 @@ pub(crate) enum Op { Var { name: SmolStr, kind: Option, id: tt::TokenId }, Repeat { tokens: MetaTemplate, kind: RepeatKind, separator: Option }, Leaf(tt::Leaf), - Subtree { tokens: MetaTemplate, delimiter: Option }, + Subtree { tokens: MetaTemplate, delimiter: Option }, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -97,6 +36,15 @@ pub(crate) enum Separator { Puncts(SmallVec<[tt::Punct; 3]>), } +#[derive(Clone, Debug, PartialEq, Eq)] +pub(crate) struct MetaTemplate(pub(crate) Vec); + +impl MetaTemplate { + pub(crate) fn iter(&self) -> impl Iterator { + 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 { @@ -125,14 +73,6 @@ impl Separator { } } -pub(crate) fn parse_template(template: &tt::Subtree) -> Result, ParseError> { - parse_inner(template, Mode::Template).into_iter().collect() -} - -pub(crate) fn parse_pattern(pattern: &tt::Subtree) -> Result, ParseError> { - parse_inner(pattern, Mode::Pattern).into_iter().collect() -} - #[derive(Clone, Copy)] enum Mode { Pattern,