33use std:: cell:: RefCell ;
44use std:: ops:: { Bound , Range } ;
55
6- use crate :: Delimiter ;
6+ use crate :: { Delimiter , LEGAL_PUNCT_CHARS } ;
77use crate :: bridge:: client:: Symbol ;
88use crate :: bridge:: fxhash:: FxHashMap ;
9- use crate :: bridge:: { Diagnostic , ExpnGlobals , LitKind , Literal , TokenTree , server } ;
9+ use crate :: bridge:: { server , DelimSpan , Diagnostic , ExpnGlobals , Group , LitKind , Literal , Punct , TokenTree } ;
1010
1111pub struct NoRustc ;
1212
@@ -130,7 +130,22 @@ impl server::FreeFunctions for NoRustc {
130130 fn track_path ( & mut self , _path : & str ) { }
131131
132132 fn literal_from_str ( & mut self , s : & str ) -> Result < Literal < Self :: Span , Self :: Symbol > , ( ) > {
133- todo ! ( )
133+ let mut chars = s. chars ( ) ;
134+ let Some ( first) = chars. next ( ) else {
135+ return Err ( ( ) ) ;
136+ } ;
137+ br"" ;
138+ cr"" ;
139+
140+ match first {
141+ 'b' => todo ! ( ) ,
142+ 'c' => todo ! ( ) ,
143+ 'r' => todo ! ( ) ,
144+ '0' ..='9' | '-' => todo ! ( ) ,
145+ '\'' => todo ! ( ) ,
146+ '"' => todo ! ( ) ,
147+ _ => Err ( ( ) )
148+ }
134149 }
135150
136151 fn emit_diagnostic ( & mut self , diagnostic : Diagnostic < Self :: Span > ) {
@@ -148,10 +163,53 @@ impl server::TokenStream for NoRustc {
148163 }
149164
150165 fn from_str ( & mut self , src : & str ) -> Self :: TokenStream {
151- todo ! ( )
166+ /// Returns the delimiter, and whether it is the opening form.
167+ fn char_to_delim ( c : char ) -> Option < ( Delimiter , bool ) > {
168+ Some ( match c {
169+ '(' => ( Delimiter :: Parenthesis , true ) ,
170+ ')' => ( Delimiter :: Parenthesis , false ) ,
171+ '{' => ( Delimiter :: Brace , true ) ,
172+ '}' => ( Delimiter :: Brace , false ) ,
173+ '[' => ( Delimiter :: Bracket , true ) ,
174+ ']' => ( Delimiter :: Bracket , false ) ,
175+ _ => return None ,
176+ } )
177+ }
178+
179+ let mut unfinished_streams = vec ! [ TokenStream :: new( ) ] ;
180+ let mut unclosed_delimiters = Vec :: new ( ) ;
181+ let mut current_ident = String :: new ( ) ;
182+ for c in src. chars ( ) {
183+ if let Some ( ( delim, is_opening) ) = char_to_delim ( c) {
184+ if is_opening {
185+ unclosed_delimiters. push ( delim) ;
186+ unfinished_streams. push ( TokenStream :: new ( ) ) ;
187+ } else if unclosed_delimiters. pop ( ) == Some ( delim) {
188+ let group = TokenTree :: < _ , _ , Symbol > :: Group ( Group {
189+ delimiter : delim,
190+ stream : unfinished_streams. pop ( ) ,
191+ span : DelimSpan :: from_single ( Span :: DUMMY )
192+ } ) ;
193+ unfinished_streams. last_mut ( ) . unwrap ( ) . 0 . push ( group) ;
194+ } else {
195+ panic ! ( "cannot parse string into token stream" )
196+ }
197+ } else if LEGAL_PUNCT_CHARS . contains ( & c) {
198+ unfinished_streams. last_mut ( ) . unwrap ( ) . 0 . push ( TokenTree :: Punct ( Punct {
199+ ch : c as u8 ,
200+ joint : false , // TODO
201+ span : Span :: DUMMY ,
202+ } ) ) ;
203+ }
204+ match c {
205+ _ => todo ! ( ) ,
206+ }
207+ }
208+ unfinished_streams[ 0 ] . clone ( )
152209 }
153210
154211 fn to_string ( & mut self , tokens : & Self :: TokenStream ) -> String {
212+ /*
155213 /// Returns a string containing exactly `num` '#' characters.
156214 /// Uses a 256-character source string literal which is always safe to
157215 /// index with a `u8` index.
@@ -164,7 +222,7 @@ impl server::TokenStream for NoRustc {
164222 ";
165223 const _: () = assert!(HASHES.len() == 256);
166224 &HASHES[..num as usize]
167- }
225+ }*/
168226
169227 let mut s = String :: new ( ) ;
170228 let mut last = String :: new ( ) ;
@@ -200,13 +258,20 @@ impl server::TokenStream for NoRustc {
200258 }
201259 }
202260 TokenTree :: Literal ( lit) => {
203- let inner = if let Some ( suffix) = lit. suffix {
261+ let respanned = Literal {
262+ kind : lit. kind ,
263+ symbol : lit. symbol ,
264+ suffix : lit. suffix ,
265+ span : super :: client:: Span :: dummy ( ) ,
266+ } ;
267+ crate :: Literal ( respanned) . to_string ( )
268+ /*let inner = if let Some(suffix) = lit.suffix {
204269 format!("{}{suffix}", lit.symbol)
205270 } else {
206271 lit.symbol.to_string()
207272 };
208273 match lit.kind {
209- LitKind :: Byte => todo ! ( ) ,
274+ LitKind::Byte => format!("b'{inner}'" ),
210275 LitKind::ByteStr => format!("b\"{inner}\""),
211276 LitKind::ByteStrRaw(raw) => {
212277 format!("br{0}\"{inner}\"{0}", get_hashes_str(raw))
@@ -220,7 +285,7 @@ impl server::TokenStream for NoRustc {
220285 LitKind::Float | LitKind::Integer => inner,
221286 LitKind::Str => format!("\"{inner}\""),
222287 LitKind::StrRaw(raw) => format!("r{0}\"{inner}\"{0}", get_hashes_str(raw)),
223- }
288+ }*/
224289 }
225290 TokenTree :: Punct ( punct) => {
226291 let c = punct. ch as char ;
@@ -231,7 +296,7 @@ impl server::TokenStream for NoRustc {
231296 }
232297 } ;
233298
234- const NON_SEPARATABLE_TOKENS : & [ ( char , char ) ] = & [ ( ':' , ':' ) , ( '-' , '>' ) ] ;
299+ const NON_SEPARATABLE_TOKENS : & [ ( char , char ) ] = & [ ( ':' , ':' ) , ( '-' , '>' ) , ( '=' , '>' ) ] ;
235300
236301 for ( first, second) in NON_SEPARATABLE_TOKENS {
237302 if second_last == first. to_string ( ) && last == second. to_string ( ) && new_part != ":"
0 commit comments