Skip to content

Commit 99e84eb

Browse files
committed
wip: more parsing
1 parent 12e628e commit 99e84eb

File tree

1 file changed

+80
-31
lines changed

1 file changed

+80
-31
lines changed

library/proc_macro/src/bridge/standalone.rs

Lines changed: 80 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
#![warn(warnings)]
22
use std::cell::{Cell, RefCell};
3-
use std::ops::{Bound, Range};
3+
use std::ops::{Bound, Range, RangeBounds};
44

55
use crate::bridge::client::Symbol;
66
use crate::bridge::fxhash::FxHashMap;
77
use crate::bridge::{
8-
DelimSpan, Diagnostic, ExpnGlobals, Group, LitKind, Literal, Punct, TokenTree, server,
8+
self, DelimSpan, Diagnostic, ExpnGlobals, Group, LitKind, Punct, TokenTree, server,
99
};
1010
use crate::{Delimiter, LEGAL_PUNCT_CHARS};
1111

12+
type Result<T> = std::result::Result<T, ()>;
13+
type Literal = bridge::Literal<Span, Symbol>;
14+
1215
pub struct NoRustc;
1316

1417
impl server::Span for NoRustc {
@@ -97,7 +100,7 @@ fn parse_maybe_raw_str(
97100
mut s: &str,
98101
raw_variant: fn(u8) -> LitKind,
99102
regular_variant: LitKind,
100-
) -> Result<Literal<Span, Symbol>, ()> {
103+
) -> Result<Literal> {
101104
/// Returns a string containing exactly `num` '#' characters.
102105
/// Uses a 256-character source string literal which is always safe to
103106
/// index with a `u8` index.
@@ -133,40 +136,86 @@ fn parse_maybe_raw_str(
133136
}
134137
let sym = parse_plain_str(s)?;
135138

136-
Ok(make_literal(
137-
if let Some(h) = hash_count { raw_variant(h) } else { regular_variant },
138-
sym,
139-
None,
140-
))
139+
Ok(make_literal(if let Some(h) = hash_count { raw_variant(h) } else { regular_variant }, sym))
141140
}
142141

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-
}
142+
fn parse_char(s: &str) -> Result<Literal> {
143+
if s.chars().count() == 1 { Ok(make_literal(LitKind::Char, Symbol::new(s))) } else { Err(()) }
149144
}
150145

151-
fn parse_plain_str(mut s: &str) -> Result<Symbol, ()> {
146+
fn parse_plain_str(mut s: &str) -> Result<Symbol> {
152147
s = s.strip_prefix("\"").ok_or(())?.strip_suffix('\"').ok_or(())?;
153148
Ok(Symbol::new(s))
154149
}
155150

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")
151+
const INT_SUFFIXES: &[&str] =
152+
&["u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "u128", "i128"];
153+
const FLOAT_SUFFIXES: &[&str] = &["f16", "f32", "f64", "f128"];
154+
155+
fn parse_numeral(mut s: &str) -> Result<Literal> {
156+
for suffix in INT_SUFFIXES {
157+
if s.ends_with(suffix) {
158+
return parse_integer(s);
159+
}
160+
}
161+
let is_negative = s.starts_with('-');
162+
let non_negative = s.strip_prefix('-').unwrap();
163+
if non_negative.starts_with("0b")
164+
|| non_negative.starts_with("0o")
165+
|| non_negative.starts_with("0x")
161166
{
162-
Literal { kind: todo!(), symbol: todo!(), suffix: todo!(), span: Span };
167+
return parse_integer(s);
168+
}
169+
let (s, suffix) = strip_number_suffix(s, FLOAT_SUFFIXES);
170+
171+
Ok(Literal { kind: LitKind::Float, symbol: todo!(), suffix, span: Span })
172+
}
173+
174+
fn parse_integer(mut s: &str) -> Result<Literal> {
175+
let is_negative = s.starts_with('-');
176+
s = s.strip_prefix('-').unwrap();
177+
178+
let (s, valid_chars) = if let Some(s) = s.strip_prefix("0b") {
179+
(s, '0'..='1')
180+
} else if let Some(s) = s.strip_prefix("0o") {
181+
(s, '0'..='7')
182+
} else if let Some(s) = s.strip_prefix("0x") {
183+
(s, '0'..='F')
184+
} else {
185+
(s, '0'..='9')
186+
};
187+
188+
let (s, suffix) = strip_number_suffix(s, INT_SUFFIXES);
189+
190+
let mut any_found = false;
191+
for c in s.chars() {
192+
if c == '_' {
193+
continue;
194+
}
195+
if valid_chars.contains(&c) {
196+
any_found = true;
197+
continue;
198+
}
199+
return Err(());
200+
}
201+
if !any_found {
202+
return Err(());
203+
}
204+
205+
Ok(Literal { kind: LitKind::Integer, symbol: Symbol::new(s), suffix, span: Span })
206+
}
207+
208+
fn strip_number_suffix<'a>(s: &'a str, suffixes: &[&str]) -> (&'a str, Option<Symbol>) {
209+
for suf in suffixes {
210+
if let Some(new_s) = s.strip_suffix(suf) {
211+
return (new_s, Some(Symbol::new(suf)));
212+
}
163213
}
164-
todo!()*/
165-
todo!()
214+
(s, None)
166215
}
167216

168-
fn make_literal(kind: LitKind, symbol: Symbol, suffix: Option<Symbol>) -> Literal<Span, Symbol> {
169-
Literal { kind, symbol, suffix, span: Span }
217+
fn make_literal(kind: LitKind, symbol: Symbol) -> Literal {
218+
Literal { kind, symbol, suffix: None, span: Span }
170219
}
171220

172221
impl server::FreeFunctions for NoRustc {
@@ -181,7 +230,7 @@ impl server::FreeFunctions for NoRustc {
181230

182231
fn track_path(&mut self, _path: &str) {}
183232

184-
fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span, Self::Symbol>, ()> {
233+
fn literal_from_str(&mut self, s: &str) -> Result<Literal> {
185234
let mut chars = s.chars();
186235
let Some(first) = chars.next() else {
187236
return Err(());
@@ -203,7 +252,7 @@ impl server::FreeFunctions for NoRustc {
203252
'r' => parse_maybe_raw_str(rest, LitKind::StrRaw, LitKind::Str),
204253
'0'..='9' | '-' => parse_numeral(s),
205254
'\'' => parse_char(s),
206-
'"' => Ok(make_literal(LitKind::Str, parse_plain_str(s)?, None)),
255+
'"' => Ok(make_literal(LitKind::Str, parse_plain_str(s)?)),
207256
_ => Err(()),
208257
}
209258
}
@@ -218,7 +267,7 @@ impl server::TokenStream for NoRustc {
218267
tokens.0.is_empty()
219268
}
220269

221-
fn expand_expr(&mut self, _tokens: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
270+
fn expand_expr(&mut self, _tokens: &Self::TokenStream) -> Result<Self::TokenStream> {
222271
todo!("`expand_expr` is not yet supported in the standalone backend")
223272
}
224273

@@ -318,7 +367,7 @@ impl server::TokenStream for NoRustc {
318367
}
319368
}
320369
TokenTree::Literal(lit) => {
321-
let respanned = Literal {
370+
let respanned = bridge::Literal {
322371
kind: lit.kind,
323372
symbol: lit.symbol,
324373
suffix: lit.suffix,
@@ -419,7 +468,7 @@ pub struct FreeFunctions;
419468
#[derive(Clone, Default)]
420469
pub struct TokenStream(Vec<TokenTree<TokenStream, Span, Symbol>>);
421470
impl TokenStream {
422-
pub fn new() -> Self {
471+
fn new() -> Self {
423472
Self(Vec::new())
424473
}
425474
}
@@ -449,7 +498,7 @@ impl server::Server for NoRustc {
449498
}
450499

451500
impl server::Symbol for NoRustc {
452-
fn normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol, ()> {
501+
fn normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol> {
453502
todo!()
454503
}
455504
}

0 commit comments

Comments
 (0)