Skip to content

Commit 869fa26

Browse files
committed
wip: some parsing
1 parent 3a9bdad commit 869fa26

File tree

2 files changed

+103
-15
lines changed

2 files changed

+103
-15
lines changed

library/proc_macro/src/bridge/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ mod state {
202202
thread_local! {
203203
static BRIDGE_STATE: Cell<*const ()> = const { Cell::new(ptr::null()) };
204204
static STANDALONE: RefCell<Bridge<'static>> = RefCell::new(standalone_bridge());
205-
pub(super) static USE_STANDALONE: Cell<StandaloneLevel> = const { Cell::new(StandaloneLevel::FallbackOnly) };
205+
pub(super) static USE_STANDALONE: Cell<StandaloneLevel> = const { Cell::new(StandaloneLevel::Never) };
206206
}
207207

208208
fn standalone_bridge() -> Bridge<'static> {

library/proc_macro/src/bridge/standalone.rs

Lines changed: 102 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use std::ops::{Bound, Range};
44

55
use crate::bridge::client::Symbol;
66
use 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+
};
810
use crate::{Delimiter, LEGAL_PUNCT_CHARS};
911

1012
pub 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+
94164
impl 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

Comments
 (0)