diff --git a/pastey-test-suite/tests/test_expr.rs b/pastey-test-suite/tests/test_expr.rs index f5a3417..37ac835 100644 --- a/pastey-test-suite/tests/test_expr.rs +++ b/pastey-test-suite/tests/test_expr.rs @@ -59,6 +59,33 @@ fn test_literal_suffix() { assert_eq!(literal!(32), 1); } +#[test] +fn test_float_literal() { + let x: f32 = paste!([<0.0 f32>]); + assert_eq!(x, 0.0f32); + + let y: f64 = paste!([<1.5 f64>]); + assert_eq!(y, 1.5f64); + + macro_rules! typed_float { + ($ty:tt) => { + paste!([<1.0 $ty>]) + }; + } + + let _: f32 = typed_float!(f32); + let _: f64 = typed_float!(f64); +} + +#[test] +fn test_negative_float_literal() { + let x: f32 = paste!([< -1.5 f32>]); + assert_eq!(x, -1.5f32); + + let y: f64 = paste!([<-0.5 f64>]); + assert_eq!(y, -0.5f64); +} + #[test] fn test_underscore() { paste! { diff --git a/src/lib.rs b/src/lib.rs index fb8e62c..e6552e6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -251,7 +251,12 @@ fn parse_bracket_as_segments(input: TokenStream, scope: Span) -> Result Result Result Result { return Ok(tokens); } + if pasted.starts_with('-') { + let rest = &pasted[1..]; + if rest.starts_with(|ch: char| ch.is_ascii_digit()) { + let mut minus = TokenTree::Punct(Punct::new('-', Spacing::Alone)); + minus.set_span(span); + tokens.extend(iter::once(minus)); + let literal = match panic::catch_unwind(|| Literal::from_str(rest)) { + Ok(Ok(mut literal)) => { + literal.set_span(span); + TokenTree::Literal(literal) + } + Ok(Err(LexError { .. })) | Err(_) => { + return Err(Error::new( + span, + &format!("`{:?}` is not a valid literal", pasted), + )); + } + }; + tokens.extend(iter::once(literal)); + return Ok(tokens); + } + } + if pasted.starts_with('\'') { let mut apostrophe = TokenTree::Punct(Punct::new('\'', Spacing::Joint)); apostrophe.set_span(span); diff --git a/src/segment.rs b/src/segment.rs index 99804a1..1ee849e 100644 --- a/src/segment.rs +++ b/src/segment.rs @@ -136,6 +136,10 @@ pub(crate) fn parse(tokens: &mut Peekable) -> Result segments.push(Segment::String(LitStr { + value: "-".to_owned(), + span: punct.span(), + })), _ => return Err(Error::new(punct.span(), "unexpected punct")), }, TokenTree::Group(group) => {