1
1
//! FIXME: write short doc here
2
2
3
3
use parser:: { Token , TokenSource } ;
4
- use std:: cell:: { Cell , Ref , RefCell } ;
5
4
use syntax:: { lex_single_syntax_kind, SmolStr , SyntaxKind , SyntaxKind :: * , T } ;
6
- use tt:: buffer:: { Cursor , TokenBuffer } ;
5
+ use tt:: buffer:: TokenBuffer ;
7
6
8
7
#[ derive( Debug , Clone , Eq , PartialEq ) ]
9
8
struct TtToken {
10
- kind : SyntaxKind ,
11
- is_joint_to_next : bool ,
9
+ tt : Token ,
12
10
text : SmolStr ,
13
11
}
14
12
15
- pub ( crate ) struct SubtreeTokenSource < ' a > {
16
- cached_cursor : Cell < Cursor < ' a > > ,
17
- cached : RefCell < Vec < Option < TtToken > > > ,
13
+ pub ( crate ) struct SubtreeTokenSource {
14
+ cached : Vec < TtToken > ,
18
15
curr : ( Token , usize ) ,
19
16
}
20
17
21
- impl < ' a > SubtreeTokenSource < ' a > {
18
+ impl < ' a > SubtreeTokenSource {
22
19
// Helper function used in test
23
20
#[ cfg( test) ]
24
21
pub ( crate ) fn text ( & self ) -> SmolStr {
25
- match * self . get ( self . curr . 1 ) {
22
+ match self . cached . get ( self . curr . 1 ) {
26
23
Some ( ref tt) => tt. text . clone ( ) ,
27
24
_ => SmolStr :: new ( "" ) ,
28
25
}
29
26
}
30
27
}
31
28
32
- impl < ' a > SubtreeTokenSource < ' a > {
33
- pub ( crate ) fn new ( buffer : & ' a TokenBuffer ) -> SubtreeTokenSource < ' a > {
34
- let cursor = buffer. begin ( ) ;
29
+ impl < ' a > SubtreeTokenSource {
30
+ pub ( crate ) fn new ( buffer : & TokenBuffer ) -> SubtreeTokenSource {
31
+ let mut current = buffer. begin ( ) ;
32
+ let mut cached = Vec :: with_capacity ( 100 ) ;
35
33
36
- let mut res = SubtreeTokenSource {
37
- curr : ( Token { kind : EOF , is_jointed_to_next : false } , 0 ) ,
38
- cached_cursor : Cell :: new ( cursor) ,
39
- cached : RefCell :: new ( Vec :: with_capacity ( 10 ) ) ,
40
- } ;
41
- res. curr = ( res. mk_token ( 0 ) , 0 ) ;
42
- res
43
- }
34
+ while !current. eof ( ) {
35
+ let cursor = current;
36
+ let tt = cursor. token_tree ( ) ;
44
37
45
- fn mk_token ( & self , pos : usize ) -> Token {
46
- match * self . get ( pos) {
47
- Some ( ref tt) => Token { kind : tt. kind , is_jointed_to_next : tt. is_joint_to_next } ,
48
- None => Token { kind : EOF , is_jointed_to_next : false } ,
49
- }
50
- }
51
-
52
- fn get ( & self , pos : usize ) -> Ref < Option < TtToken > > {
53
- fn is_lifetime ( c : Cursor ) -> Option < ( Cursor , SmolStr ) > {
54
- let tkn = c. token_tree ( ) ;
55
-
56
- if let Some ( tt:: buffer:: TokenTreeRef :: Leaf ( tt:: Leaf :: Punct ( punct) , _) ) = tkn {
38
+ // Check if it is lifetime
39
+ if let Some ( tt:: buffer:: TokenTreeRef :: Leaf ( tt:: Leaf :: Punct ( punct) , _) ) = tt {
57
40
if punct. char == '\'' {
58
- let next = c . bump ( ) ;
41
+ let next = cursor . bump ( ) ;
59
42
if let Some ( tt:: buffer:: TokenTreeRef :: Leaf ( tt:: Leaf :: Ident ( ident) , _) ) =
60
43
next. token_tree ( )
61
44
{
62
- let res_cursor = next. bump ( ) ;
63
- let text = SmolStr :: new ( "'" . to_string ( ) + & ident. to_string ( ) ) ;
64
-
65
- return Some ( ( res_cursor, text) ) ;
45
+ let text = SmolStr :: new ( "'" . to_string ( ) + & ident. text ) ;
46
+ cached. push ( TtToken {
47
+ tt : Token { kind : LIFETIME_IDENT , is_jointed_to_next : false } ,
48
+ text,
49
+ } ) ;
50
+ current = next. bump ( ) ;
51
+ continue ;
66
52
} else {
67
53
panic ! ( "Next token must be ident : {:#?}" , next. token_tree( ) ) ;
68
54
}
69
55
}
70
56
}
71
57
72
- None
73
- }
74
-
75
- if pos < self . cached . borrow ( ) . len ( ) {
76
- return Ref :: map ( self . cached . borrow ( ) , |c| & c[ pos] ) ;
77
- }
78
-
79
- {
80
- let mut cached = self . cached . borrow_mut ( ) ;
81
- while pos >= cached. len ( ) {
82
- let cursor = self . cached_cursor . get ( ) ;
83
- if cursor. eof ( ) {
84
- cached. push ( None ) ;
85
- continue ;
58
+ current = match tt {
59
+ Some ( tt:: buffer:: TokenTreeRef :: Leaf ( leaf, _) ) => {
60
+ cached. push ( convert_leaf ( & leaf) ) ;
61
+ cursor. bump ( )
86
62
}
87
-
88
- if let Some ( ( curr, text) ) = is_lifetime ( cursor) {
89
- cached. push ( Some ( TtToken {
90
- kind : LIFETIME_IDENT ,
91
- is_joint_to_next : false ,
92
- text,
93
- } ) ) ;
94
- self . cached_cursor . set ( curr) ;
95
- continue ;
63
+ Some ( tt:: buffer:: TokenTreeRef :: Subtree ( subtree, _) ) => {
64
+ cached. push ( convert_delim ( subtree. delimiter_kind ( ) , false ) ) ;
65
+ cursor. subtree ( ) . unwrap ( )
96
66
}
97
-
98
- match cursor. token_tree ( ) {
99
- Some ( tt:: buffer:: TokenTreeRef :: Leaf ( leaf, _) ) => {
100
- cached. push ( Some ( convert_leaf ( & leaf) ) ) ;
101
- self . cached_cursor . set ( cursor. bump ( ) ) ;
102
- }
103
- Some ( tt:: buffer:: TokenTreeRef :: Subtree ( subtree, _) ) => {
104
- self . cached_cursor . set ( cursor. subtree ( ) . unwrap ( ) ) ;
105
- cached. push ( Some ( convert_delim ( subtree. delimiter_kind ( ) , false ) ) ) ;
106
- }
107
- None => {
108
- if let Some ( subtree) = cursor. end ( ) {
109
- cached. push ( Some ( convert_delim ( subtree. delimiter_kind ( ) , true ) ) ) ;
110
- self . cached_cursor . set ( cursor. bump ( ) ) ;
111
- }
67
+ None => {
68
+ if let Some ( subtree) = cursor. end ( ) {
69
+ cached. push ( convert_delim ( subtree. delimiter_kind ( ) , true ) ) ;
70
+ cursor. bump ( )
71
+ } else {
72
+ continue ;
112
73
}
113
74
}
114
- }
75
+ } ;
115
76
}
116
77
117
- Ref :: map ( self . cached . borrow ( ) , |c| & c[ pos] )
78
+ let mut res = SubtreeTokenSource {
79
+ curr : ( Token { kind : EOF , is_jointed_to_next : false } , 0 ) ,
80
+ cached,
81
+ } ;
82
+ res. curr = ( res. token ( 0 ) , 0 ) ;
83
+ res
84
+ }
85
+
86
+ fn token ( & self , pos : usize ) -> Token {
87
+ match self . cached . get ( pos) {
88
+ Some ( it) => it. tt ,
89
+ None => Token { kind : EOF , is_jointed_to_next : false } ,
90
+ }
118
91
}
119
92
}
120
93
121
- impl < ' a > TokenSource for SubtreeTokenSource < ' a > {
94
+ impl < ' a > TokenSource for SubtreeTokenSource {
122
95
fn current ( & self ) -> Token {
123
96
self . curr . 0
124
97
}
125
98
126
99
/// Lookahead n token
127
100
fn lookahead_nth ( & self , n : usize ) -> Token {
128
- self . mk_token ( self . curr . 1 + n)
101
+ self . token ( self . curr . 1 + n)
129
102
}
130
103
131
104
/// bump cursor to next token
132
105
fn bump ( & mut self ) {
133
106
if self . current ( ) . kind == EOF {
134
107
return ;
135
108
}
136
-
137
- self . curr = ( self . mk_token ( self . curr . 1 + 1 ) , self . curr . 1 + 1 ) ;
109
+ self . curr = ( self . token ( self . curr . 1 + 1 ) , self . curr . 1 + 1 ) ;
138
110
}
139
111
140
112
/// Is the current token a specified keyword?
141
113
fn is_keyword ( & self , kw : & str ) -> bool {
142
- match * self . get ( self . curr . 1 ) {
114
+ match self . cached . get ( self . curr . 1 ) {
143
115
Some ( ref t) => t. text == * kw,
144
116
_ => false ,
145
117
}
@@ -157,7 +129,7 @@ fn convert_delim(d: Option<tt::DelimiterKind>, closing: bool) -> TtToken {
157
129
let idx = closing as usize ;
158
130
let kind = kinds[ idx] ;
159
131
let text = if !texts. is_empty ( ) { & texts[ idx..texts. len ( ) - ( 1 - idx) ] } else { "" } ;
160
- TtToken { kind, is_joint_to_next : false , text : SmolStr :: new ( text) }
132
+ TtToken { tt : Token { kind, is_jointed_to_next : false } , text : SmolStr :: new ( text) }
161
133
}
162
134
163
135
fn convert_literal ( l : & tt:: Literal ) -> TtToken {
@@ -171,7 +143,7 @@ fn convert_literal(l: &tt::Literal) -> TtToken {
171
143
} )
172
144
. unwrap_or_else ( || panic ! ( "Fail to convert given literal {:#?}" , & l) ) ;
173
145
174
- TtToken { kind, is_joint_to_next : false , text : l. text . clone ( ) }
146
+ TtToken { tt : Token { kind, is_jointed_to_next : false } , text : l. text . clone ( ) }
175
147
}
176
148
177
149
fn convert_ident ( ident : & tt:: Ident ) -> TtToken {
@@ -182,7 +154,7 @@ fn convert_ident(ident: &tt::Ident) -> TtToken {
182
154
_ => SyntaxKind :: from_keyword ( ident. text . as_str ( ) ) . unwrap_or ( IDENT ) ,
183
155
} ;
184
156
185
- TtToken { kind, is_joint_to_next : false , text : ident. text . clone ( ) }
157
+ TtToken { tt : Token { kind, is_jointed_to_next : false } , text : ident. text . clone ( ) }
186
158
}
187
159
188
160
fn convert_punct ( p : tt:: Punct ) -> TtToken {
@@ -196,7 +168,7 @@ fn convert_punct(p: tt::Punct) -> TtToken {
196
168
let s: & str = p. char . encode_utf8 ( & mut buf) ;
197
169
SmolStr :: new ( s)
198
170
} ;
199
- TtToken { kind, is_joint_to_next : p. spacing == tt:: Spacing :: Joint , text }
171
+ TtToken { tt : Token { kind, is_jointed_to_next : p. spacing == tt:: Spacing :: Joint } , text }
200
172
}
201
173
202
174
fn convert_leaf ( leaf : & tt:: Leaf ) -> TtToken {
@@ -210,6 +182,7 @@ fn convert_leaf(leaf: &tt::Leaf) -> TtToken {
210
182
#[ cfg( test) ]
211
183
mod tests {
212
184
use super :: { convert_literal, TtToken } ;
185
+ use parser:: Token ;
213
186
use syntax:: { SmolStr , SyntaxKind } ;
214
187
215
188
#[ test]
@@ -220,8 +193,7 @@ mod tests {
220
193
text: SmolStr :: new( "-42.0" )
221
194
} ) ,
222
195
TtToken {
223
- kind: SyntaxKind :: FLOAT_NUMBER ,
224
- is_joint_to_next: false ,
196
+ tt: Token { kind: SyntaxKind :: FLOAT_NUMBER , is_jointed_to_next: false } ,
225
197
text: SmolStr :: new( "-42.0" )
226
198
}
227
199
) ;
0 commit comments