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.rs | 68 |
1 files changed, 37 insertions, 31 deletions
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs index 7a143e7466..00ba35377a 100644 --- a/crates/mbe/src/parser.rs +++ b/crates/mbe/src/parser.rs @@ -3,8 +3,9 @@ use smallvec::{smallvec, SmallVec}; use syntax::SmolStr; +use tt::Span; -use crate::{tt, tt_iter::TtIter, ParseError}; +use crate::{tt_iter::TtIter, ParseError}; /// Consider /// @@ -20,22 +21,22 @@ use crate::{tt, tt_iter::TtIter, ParseError}; /// 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) Box<[Op]>); +pub(crate) struct MetaTemplate<S>(pub(crate) Box<[Op<S>]>); -impl MetaTemplate { - pub(crate) fn parse_pattern(pattern: &tt::Subtree) -> Result<MetaTemplate, ParseError> { +impl<S: Span> MetaTemplate<S> { + pub(crate) fn parse_pattern(pattern: &tt::Subtree<S>) -> Result<Self, ParseError> { MetaTemplate::parse(pattern, Mode::Pattern) } - pub(crate) fn parse_template(template: &tt::Subtree) -> Result<MetaTemplate, ParseError> { + pub(crate) fn parse_template(template: &tt::Subtree<S>) -> Result<Self, ParseError> { MetaTemplate::parse(template, Mode::Template) } - pub(crate) fn iter(&self) -> impl Iterator<Item = &Op> { + pub(crate) fn iter(&self) -> impl Iterator<Item = &Op<S>> { self.0.iter() } - fn parse(tt: &tt::Subtree, mode: Mode) -> Result<MetaTemplate, ParseError> { + fn parse(tt: &tt::Subtree<S>, mode: Mode) -> Result<Self, ParseError> { let mut src = TtIter::new(tt); let mut res = Vec::new(); @@ -49,16 +50,16 @@ impl MetaTemplate { } #[derive(Clone, Debug, PartialEq, Eq)] -pub(crate) enum Op { - Var { name: SmolStr, kind: Option<MetaVarKind>, id: tt::TokenId }, - Ignore { name: SmolStr, id: tt::TokenId }, +pub(crate) enum Op<S> { + Var { name: SmolStr, kind: Option<MetaVarKind>, id: S }, + Ignore { name: SmolStr, id: S }, Index { depth: usize }, Count { name: SmolStr, depth: Option<usize> }, - Repeat { tokens: MetaTemplate, kind: RepeatKind, separator: Option<Separator> }, - Subtree { tokens: MetaTemplate, delimiter: tt::Delimiter }, - Literal(tt::Literal), - Punct(SmallVec<[tt::Punct; 3]>), - Ident(tt::Ident), + Repeat { tokens: MetaTemplate<S>, kind: RepeatKind, separator: Option<Separator<S>> }, + Subtree { tokens: MetaTemplate<S>, delimiter: tt::Delimiter<S> }, + Literal(tt::Literal<S>), + Punct(SmallVec<[tt::Punct<S>; 3]>), + Ident(tt::Ident<S>), } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -87,15 +88,15 @@ pub(crate) enum MetaVarKind { } #[derive(Clone, Debug, Eq)] -pub(crate) enum Separator { - Literal(tt::Literal), - Ident(tt::Ident), - Puncts(SmallVec<[tt::Punct; 3]>), +pub(crate) enum Separator<S> { + Literal(tt::Literal<S>), + Ident(tt::Ident<S>), + Puncts(SmallVec<[tt::Punct<S>; 3]>), } // Note that when we compare a Separator, we just care about its textual value. -impl PartialEq for Separator { - fn eq(&self, other: &Separator) -> bool { +impl<S> PartialEq for Separator<S> { + fn eq(&self, other: &Separator<S>) -> bool { use Separator::*; match (self, other) { @@ -117,11 +118,11 @@ enum Mode { Template, } -fn next_op( - first_peeked: &tt::TokenTree, - src: &mut TtIter<'_>, +fn next_op<S: Span>( + first_peeked: &tt::TokenTree<S>, + src: &mut TtIter<'_, S>, mode: Mode, -) -> Result<Op, ParseError> { +) -> Result<Op<S>, ParseError> { let res = match first_peeked { tt::TokenTree::Leaf(tt::Leaf::Punct(p @ tt::Punct { char: '$', .. })) => { src.next().expect("first token already peeked"); @@ -212,7 +213,10 @@ fn next_op( Ok(res) } -fn eat_fragment_kind(src: &mut TtIter<'_>, mode: Mode) -> Result<Option<MetaVarKind>, ParseError> { +fn eat_fragment_kind<S: Span>( + src: &mut TtIter<'_, S>, + mode: Mode, +) -> Result<Option<MetaVarKind>, ParseError> { if let Mode::Pattern = mode { src.expect_char(':').map_err(|()| ParseError::unexpected("missing fragment specifier"))?; let ident = src @@ -240,11 +244,13 @@ fn eat_fragment_kind(src: &mut TtIter<'_>, mode: Mode) -> Result<Option<MetaVarK Ok(None) } -fn is_boolean_literal(lit: &tt::Literal) -> bool { +fn is_boolean_literal<S>(lit: &tt::Literal<S>) -> bool { matches!(lit.text.as_str(), "true" | "false") } -fn parse_repeat(src: &mut TtIter<'_>) -> Result<(Option<Separator>, RepeatKind), ParseError> { +fn parse_repeat<S: Span>( + src: &mut TtIter<'_, S>, +) -> Result<(Option<Separator<S>>, RepeatKind), ParseError> { let mut separator = Separator::Puncts(SmallVec::new()); for tt in src { let tt = match tt { @@ -281,7 +287,7 @@ fn parse_repeat(src: &mut TtIter<'_>) -> Result<(Option<Separator>, RepeatKind), Err(ParseError::InvalidRepeat) } -fn parse_metavar_expr(src: &mut TtIter<'_>) -> Result<Op, ()> { +fn parse_metavar_expr<S: Span>(src: &mut TtIter<'_, S>) -> Result<Op<S>, ()> { let func = src.expect_ident()?; let args = src.expect_subtree()?; @@ -314,7 +320,7 @@ fn parse_metavar_expr(src: &mut TtIter<'_>) -> Result<Op, ()> { Ok(op) } -fn parse_depth(src: &mut TtIter<'_>) -> Result<usize, ()> { +fn parse_depth<S: Span>(src: &mut TtIter<'_, S>) -> Result<usize, ()> { if src.len() == 0 { Ok(0) } else if let tt::Leaf::Literal(lit) = src.expect_literal()? { @@ -325,7 +331,7 @@ fn parse_depth(src: &mut TtIter<'_>) -> Result<usize, ()> { } } -fn try_eat_comma(src: &mut TtIter<'_>) -> bool { +fn try_eat_comma<S: Span>(src: &mut TtIter<'_, S>) -> bool { if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: ',', .. }))) = src.peek_n(0) { let _ = src.next(); return true; |