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:: TokenTree :: 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 ( ) ;
59
- if let Some ( tt:: TokenTree :: Leaf ( tt:: Leaf :: Ident ( ident) ) ) = next. token_tree ( ) {
60
- let res_cursor = next. bump ( ) ;
61
- let text = SmolStr :: new ( "'" . to_string ( ) + & ident. to_string ( ) ) ;
62
-
63
- return Some ( ( res_cursor, text) ) ;
41
+ let next = cursor. bump ( ) ;
42
+ if let Some ( tt:: buffer:: TokenTreeRef :: Leaf ( tt:: Leaf :: Ident ( ident) , _) ) =
43
+ next. token_tree ( )
44
+ {
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 ;
64
52
} else {
65
53
panic ! ( "Next token must be ident : {:#?}" , next. token_tree( ) ) ;
66
54
}
67
55
}
68
56
}
69
57
70
- None
71
- }
72
-
73
- if pos < self . cached . borrow ( ) . len ( ) {
74
- return Ref :: map ( self . cached . borrow ( ) , |c| & c[ pos] ) ;
75
- }
76
-
77
- {
78
- let mut cached = self . cached . borrow_mut ( ) ;
79
- while pos >= cached. len ( ) {
80
- let cursor = self . cached_cursor . get ( ) ;
81
- if cursor. eof ( ) {
82
- cached. push ( None ) ;
83
- continue ;
58
+ current = match tt {
59
+ Some ( tt:: buffer:: TokenTreeRef :: Leaf ( leaf, _) ) => {
60
+ cached. push ( convert_leaf ( & leaf) ) ;
61
+ cursor. bump ( )
84
62
}
85
-
86
- if let Some ( ( curr, text) ) = is_lifetime ( cursor) {
87
- cached. push ( Some ( TtToken {
88
- kind : LIFETIME_IDENT ,
89
- is_joint_to_next : false ,
90
- text,
91
- } ) ) ;
92
- self . cached_cursor . set ( curr) ;
93
- continue ;
63
+ Some ( tt:: buffer:: TokenTreeRef :: Subtree ( subtree, _) ) => {
64
+ cached. push ( convert_delim ( subtree. delimiter_kind ( ) , false ) ) ;
65
+ cursor. subtree ( ) . unwrap ( )
94
66
}
95
-
96
- match cursor. token_tree ( ) {
97
- Some ( tt:: TokenTree :: Leaf ( leaf) ) => {
98
- cached. push ( Some ( convert_leaf ( & leaf) ) ) ;
99
- self . cached_cursor . set ( cursor. bump ( ) ) ;
100
- }
101
- Some ( tt:: TokenTree :: Subtree ( subtree) ) => {
102
- self . cached_cursor . set ( cursor. subtree ( ) . unwrap ( ) ) ;
103
- cached. push ( Some ( convert_delim ( subtree. delimiter_kind ( ) , false ) ) ) ;
104
- }
105
- None => {
106
- if let Some ( subtree) = cursor. end ( ) {
107
- cached. push ( Some ( convert_delim ( subtree. delimiter_kind ( ) , true ) ) ) ;
108
- self . cached_cursor . set ( cursor. bump ( ) ) ;
109
- }
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 ;
110
73
}
111
74
}
112
- }
75
+ } ;
113
76
}
114
77
115
- 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
+ }
116
91
}
117
92
}
118
93
119
- impl < ' a > TokenSource for SubtreeTokenSource < ' a > {
94
+ impl < ' a > TokenSource for SubtreeTokenSource {
120
95
fn current ( & self ) -> Token {
121
96
self . curr . 0
122
97
}
123
98
124
99
/// Lookahead n token
125
100
fn lookahead_nth ( & self , n : usize ) -> Token {
126
- self . mk_token ( self . curr . 1 + n)
101
+ self . token ( self . curr . 1 + n)
127
102
}
128
103
129
104
/// bump cursor to next token
130
105
fn bump ( & mut self ) {
131
106
if self . current ( ) . kind == EOF {
132
107
return ;
133
108
}
134
-
135
- 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 ) ;
136
110
}
137
111
138
112
/// Is the current token a specified keyword?
139
113
fn is_keyword ( & self , kw : & str ) -> bool {
140
- match * self . get ( self . curr . 1 ) {
114
+ match self . cached . get ( self . curr . 1 ) {
141
115
Some ( ref t) => t. text == * kw,
142
116
_ => false ,
143
117
}
@@ -155,7 +129,7 @@ fn convert_delim(d: Option<tt::DelimiterKind>, closing: bool) -> TtToken {
155
129
let idx = closing as usize ;
156
130
let kind = kinds[ idx] ;
157
131
let text = if !texts. is_empty ( ) { & texts[ idx..texts. len ( ) - ( 1 - idx) ] } else { "" } ;
158
- 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) }
159
133
}
160
134
161
135
fn convert_literal ( l : & tt:: Literal ) -> TtToken {
@@ -169,7 +143,7 @@ fn convert_literal(l: &tt::Literal) -> TtToken {
169
143
} )
170
144
. unwrap_or_else ( || panic ! ( "Fail to convert given literal {:#?}" , & l) ) ;
171
145
172
- 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 ( ) }
173
147
}
174
148
175
149
fn convert_ident ( ident : & tt:: Ident ) -> TtToken {
@@ -180,7 +154,7 @@ fn convert_ident(ident: &tt::Ident) -> TtToken {
180
154
_ => SyntaxKind :: from_keyword ( ident. text . as_str ( ) ) . unwrap_or ( IDENT ) ,
181
155
} ;
182
156
183
- 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 ( ) }
184
158
}
185
159
186
160
fn convert_punct ( p : tt:: Punct ) -> TtToken {
@@ -194,7 +168,7 @@ fn convert_punct(p: tt::Punct) -> TtToken {
194
168
let s: & str = p. char . encode_utf8 ( & mut buf) ;
195
169
SmolStr :: new ( s)
196
170
} ;
197
- 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 }
198
172
}
199
173
200
174
fn convert_leaf ( leaf : & tt:: Leaf ) -> TtToken {
@@ -208,6 +182,7 @@ fn convert_leaf(leaf: &tt::Leaf) -> TtToken {
208
182
#[ cfg( test) ]
209
183
mod tests {
210
184
use super :: { convert_literal, TtToken } ;
185
+ use parser:: Token ;
211
186
use syntax:: { SmolStr , SyntaxKind } ;
212
187
213
188
#[ test]
@@ -218,8 +193,7 @@ mod tests {
218
193
text: SmolStr :: new( "-42.0" )
219
194
} ) ,
220
195
TtToken {
221
- kind: SyntaxKind :: FLOAT_NUMBER ,
222
- is_joint_to_next: false ,
196
+ tt: Token { kind: SyntaxKind :: FLOAT_NUMBER , is_jointed_to_next: false } ,
223
197
text: SmolStr :: new( "-42.0" )
224
198
}
225
199
) ;
0 commit comments