@@ -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,74 @@ 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+ todo ! ( )
158+ }
159+
160+ fn make_literal ( kind : LitKind , symbol : Symbol , suffix : Option < Symbol > ) -> Literal < Span , Symbol > {
161+ Literal { kind, symbol, suffix, span : Span }
162+ }
163+
94164impl server:: FreeFunctions for NoRustc {
95165 fn injected_env_var ( & mut self , var : & str ) -> Option < String > {
96166 TRACKED_ENV_VARS . with_borrow ( |vars| vars. get ( var) ?. clone ( ) )
@@ -108,16 +178,34 @@ impl server::FreeFunctions for NoRustc {
108178 let Some ( first) = chars. next ( ) else {
109179 return Err ( ( ) ) ;
110180 } ;
111- br"" ;
112- cr"" ;
181+ let rest = & s[ 1 ..] ;
113182
114183 match first {
115- 'b' => todo ! ( ) ,
116- 'c' => todo ! ( ) ,
117- 'r' => todo ! ( ) ,
118- '0' ..='9' | '-' => todo ! ( ) ,
119- '\'' => todo ! ( ) ,
120- '"' => todo ! ( ) ,
184+ 'b' => {
185+ if chars. next ( ) == Some ( '\'' ) {
186+ parse_char ( rest) . map ( |mut lit| {
187+ lit. kind = LitKind :: Byte ;
188+ lit
189+ } )
190+ } else {
191+ parse_maybe_raw_str ( rest, LitKind :: ByteStrRaw , LitKind :: ByteStr )
192+ }
193+ }
194+ 'c' => parse_maybe_raw_str ( rest, LitKind :: CStrRaw , LitKind :: CStr ) ,
195+ 'r' => parse_maybe_raw_str ( rest, LitKind :: StrRaw , LitKind :: Str ) ,
196+ '0' ..='9' | '-' => {
197+ /*if s.ends_with("f16")
198+ || s.ends_with("f32")
199+ || s.ends_with("f64")
200+ || s.ends_with("f128")
201+ {
202+ Literal { kind: todo!(), symbol: todo!(), suffix: todo!(), span: Span };
203+ }
204+ todo!()*/
205+ parse_numeral ( s)
206+ }
207+ '\'' => parse_char ( s) ,
208+ '"' => Ok ( make_literal ( LitKind :: Str , parse_plain_str ( s) ?, None ) ) ,
121209 _ => Err ( ( ) ) ,
122210 }
123211 }
@@ -132,8 +220,8 @@ impl server::TokenStream for NoRustc {
132220 tokens. 0 . is_empty ( )
133221 }
134222
135- fn expand_expr ( & mut self , tokens : & Self :: TokenStream ) -> Result < Self :: TokenStream , ( ) > {
136- todo ! ( )
223+ fn expand_expr ( & mut self , _tokens : & Self :: TokenStream ) -> Result < Self :: TokenStream , ( ) > {
224+ todo ! ( "`expand_expr` is not yet supported in the standalone backend" )
137225 }
138226
139227 fn from_str ( & mut self , src : & str ) -> Self :: TokenStream {
0 commit comments