3
3
4
4
use smallvec:: SmallVec ;
5
5
use syntax:: SmolStr ;
6
- use tt:: Delimiter ;
7
6
8
7
use crate :: { tt_iter:: TtIter , ParseError } ;
9
8
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.
10
22
#[ derive( Clone , Debug , PartialEq , Eq ) ]
11
23
pub ( crate ) struct MetaTemplate ( pub ( crate ) Vec < Op > ) ;
12
24
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 )
46
28
}
47
- }
48
-
49
- impl < ' a > Iterator for OpDelimitedIter < ' a > {
50
- type Item = OpDelimited < ' a > ;
51
29
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 )
56
32
}
57
33
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 {
66
34
pub ( crate ) fn iter ( & self ) -> impl Iterator < Item = & Op > {
67
35
self . 0 . iter ( )
68
36
}
69
37
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) )
75
48
}
76
49
}
77
50
@@ -80,7 +53,7 @@ pub(crate) enum Op {
80
53
Var { name : SmolStr , kind : Option < SmolStr > , id : tt:: TokenId } ,
81
54
Repeat { tokens : MetaTemplate , kind : RepeatKind , separator : Option < Separator > } ,
82
55
Leaf ( tt:: Leaf ) ,
83
- Subtree { tokens : MetaTemplate , delimiter : Option < Delimiter > } ,
56
+ Subtree { tokens : MetaTemplate , delimiter : Option < tt :: Delimiter > } ,
84
57
}
85
58
86
59
#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
@@ -125,29 +98,12 @@ impl Separator {
125
98
}
126
99
}
127
100
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
-
136
101
#[ derive( Clone , Copy ) ]
137
102
enum Mode {
138
103
Pattern ,
139
104
Template ,
140
105
}
141
106
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
-
151
107
macro_rules! err {
152
108
( $( $tt: tt) * ) => {
153
109
ParseError :: UnexpectedToken ( ( $( $tt) * ) . to_string( ) )
@@ -171,10 +127,8 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul
171
127
match second {
172
128
tt:: TokenTree :: Subtree ( subtree) => {
173
129
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 }
178
132
}
179
133
tt:: TokenTree :: Leaf ( leaf) => match leaf {
180
134
tt:: Leaf :: Punct ( _) => {
@@ -205,9 +159,8 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul
205
159
}
206
160
tt:: TokenTree :: Leaf ( tt) => Op :: Leaf ( tt. clone ( ) ) ,
207
161
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 }
211
164
}
212
165
} ;
213
166
Ok ( res)
0 commit comments