@@ -4,7 +4,9 @@ use std::ops::{Bound, Range};
44
55use crate :: bridge:: client:: Symbol ;
66use crate :: bridge:: fxhash:: FxHashMap ;
7- use crate :: bridge:: { DelimSpan , Diagnostic , ExpnGlobals , Group , Literal , Punct , TokenTree , server} ;
7+ use crate :: bridge:: {
8+ DelimSpan , Diagnostic , ExpnGlobals , Group , LitKind , Literal , Punct , TokenTree , server,
9+ } ;
810use crate :: { Delimiter , LEGAL_PUNCT_CHARS } ;
911
1012pub struct NoRustc ;
@@ -23,7 +25,7 @@ impl server::Span for NoRustc {
2325 }
2426
2527 fn byte_range ( & mut self , _: Self :: Span ) -> Range < usize > {
26- todo ! ( )
28+ 0 .. 0
2729 }
2830
2931 fn start ( & mut self , _: Self :: Span ) -> Self :: Span {
@@ -35,11 +37,11 @@ impl server::Span for NoRustc {
3537 }
3638
3739 fn line ( & mut self , _: Self :: Span ) -> usize {
38- todo ! ( )
40+ 1
3941 }
4042
4143 fn column ( & mut self , _: Self :: Span ) -> usize {
42- todo ! ( )
44+ 1
4345 }
4446
4547 fn file ( & mut self , _: Self :: Span ) -> String {
@@ -91,6 +93,82 @@ thread_local! {
9193 static TRACKED_ENV_VARS : RefCell <FxHashMap <String , Option <String >>> = RefCell :: new( FxHashMap :: default ( ) ) ;
9294}
9395
96+ fn parse_maybe_raw_str (
97+ mut s : & str ,
98+ raw_variant : fn ( u8 ) -> LitKind ,
99+ regular_variant : LitKind ,
100+ ) -> Result < Literal < Span , Symbol > , ( ) > {
101+ /// Returns a string containing exactly `num` '#' characters.
102+ /// Uses a 256-character source string literal which is always safe to
103+ /// index with a `u8` index.
104+ fn get_hashes_str ( num : u8 ) -> & ' static str {
105+ const HASHES : & str = "\
106+ ################################################################\
107+ ################################################################\
108+ ################################################################\
109+ ################################################################\
110+ ";
111+ const _: ( ) = assert ! ( HASHES . len( ) == 256 ) ;
112+ & HASHES [ ..num as usize ]
113+ }
114+ let mut hash_count = None ;
115+
116+ if s. starts_with ( 'r' ) {
117+ s = s. strip_prefix ( 'r' ) . unwrap ( ) ;
118+ let mut h = 0 ;
119+ for c in s. chars ( ) {
120+ if c == '#' {
121+ if h == u8:: MAX {
122+ return Err ( ( ) ) ;
123+ }
124+ h += 1 ;
125+ } else {
126+ break ;
127+ }
128+ }
129+ hash_count = Some ( h) ;
130+ let hashes = get_hashes_str ( h) ;
131+ s = s. strip_prefix ( hashes) . unwrap ( ) ;
132+ s = s. strip_suffix ( hashes) . ok_or ( ( ) ) ?;
133+ }
134+ let sym = parse_plain_str ( s) ?;
135+
136+ Ok ( make_literal (
137+ if let Some ( h) = hash_count { raw_variant ( h) } else { regular_variant } ,
138+ sym,
139+ None ,
140+ ) )
141+ }
142+
143+ fn parse_char ( s : & str ) -> Result < Literal < Span , Symbol > , ( ) > {
144+ if s. chars ( ) . count ( ) == 1 {
145+ Ok ( make_literal ( LitKind :: Char , Symbol :: new ( s) , None ) )
146+ } else {
147+ Err ( ( ) )
148+ }
149+ }
150+
151+ fn parse_plain_str ( mut s : & str ) -> Result < Symbol , ( ) > {
152+ s = s. strip_prefix ( "\" " ) . ok_or ( ( ) ) ?. strip_suffix ( '\"' ) . ok_or ( ( ) ) ?;
153+ Ok ( Symbol :: new ( s) )
154+ }
155+
156+ fn parse_numeral ( s : & str ) -> Result < Literal < Span , Symbol > , ( ) > {
157+ /*if s.ends_with("f16")
158+ || s.ends_with("f32")
159+ || s.ends_with("f64")
160+ || s.ends_with("f128")
161+ {
162+ Literal { kind: todo!(), symbol: todo!(), suffix: todo!(), span: Span };
163+ }
164+ todo!()*/
165+ todo ! ( )
166+ }
167+
168+ fn make_literal ( kind : LitKind , symbol : Symbol , suffix : Option < Symbol > ) -> Literal < Span , Symbol > {
169+ Literal { kind, symbol, suffix, span : Span }
170+ }
171+
94172impl server:: FreeFunctions for NoRustc {
95173 fn injected_env_var ( & mut self , var : & str ) -> Option < String > {
96174 TRACKED_ENV_VARS . with_borrow ( |vars| vars. get ( var) ?. clone ( ) )
@@ -108,16 +186,24 @@ impl server::FreeFunctions for NoRustc {
108186 let Some ( first) = chars. next ( ) else {
109187 return Err ( ( ) ) ;
110188 } ;
111- br"" ;
112- cr"" ;
189+ let rest = & s[ 1 ..] ;
113190
114191 match first {
115- 'b' => todo ! ( ) ,
116- 'c' => todo ! ( ) ,
117- 'r' => todo ! ( ) ,
118- '0' ..='9' | '-' => todo ! ( ) ,
119- '\'' => todo ! ( ) ,
120- '"' => todo ! ( ) ,
192+ 'b' => {
193+ if chars. next ( ) == Some ( '\'' ) {
194+ parse_char ( rest) . map ( |mut lit| {
195+ lit. kind = LitKind :: Byte ;
196+ lit
197+ } )
198+ } else {
199+ parse_maybe_raw_str ( rest, LitKind :: ByteStrRaw , LitKind :: ByteStr )
200+ }
201+ }
202+ 'c' => parse_maybe_raw_str ( rest, LitKind :: CStrRaw , LitKind :: CStr ) ,
203+ 'r' => parse_maybe_raw_str ( rest, LitKind :: StrRaw , LitKind :: Str ) ,
204+ '0' ..='9' | '-' => parse_numeral ( s) ,
205+ '\'' => parse_char ( s) ,
206+ '"' => Ok ( make_literal ( LitKind :: Str , parse_plain_str ( s) ?, None ) ) ,
121207 _ => Err ( ( ) ) ,
122208 }
123209 }
@@ -132,8 +218,8 @@ impl server::TokenStream for NoRustc {
132218 tokens. 0 . is_empty ( )
133219 }
134220
135- fn expand_expr ( & mut self , tokens : & Self :: TokenStream ) -> Result < Self :: TokenStream , ( ) > {
136- todo ! ( )
221+ fn expand_expr ( & mut self , _tokens : & Self :: TokenStream ) -> Result < Self :: TokenStream , ( ) > {
222+ todo ! ( "`expand_expr` is not yet supported in the standalone backend" )
137223 }
138224
139225 fn from_str ( & mut self , src : & str ) -> Self :: TokenStream {
@@ -171,7 +257,7 @@ impl server::TokenStream for NoRustc {
171257 } else if LEGAL_PUNCT_CHARS . contains ( & c) {
172258 unfinished_streams. last_mut ( ) . unwrap ( ) . 0 . push ( TokenTree :: Punct ( Punct {
173259 ch : c as u8 ,
174- joint : false , // TODO
260+ joint : todo ! ( ) ,
175261 span : Span ,
176262 } ) ) ;
177263 }
0 commit comments