33
44use smallvec:: SmallVec ;
55use syntax:: SmolStr ;
6- use tt:: Delimiter ;
76
87use 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 ) ]
1123pub ( 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 ) ]
137102enum 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-
151107macro_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