From caec84540f34cd4da680d3a3c99db0030603c5da Mon Sep 17 00:00:00 2001 From: c42f Date: Sun, 27 Nov 2022 17:04:49 +1000 Subject: [PATCH] Allow + prefix to be part of unsigned numeric literals So +0xff is a numeric literal, not `(call-pre + 0xff)` --- src/parser.jl | 10 ++++++---- src/value_parsing.jl | 6 ++++-- test/parser.jl | 8 ++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/parser.jl b/src/parser.jl index bc3877e7..aeaddedf 100644 --- a/src/parser.jl +++ b/src/parser.jl @@ -1157,9 +1157,12 @@ function parse_unary(ps::ParseState) parse_factor(ps) return end + t2 = peek_token(ps, 2) + k2 = kind(t2) if op_k in KSet"- +" && !is_decorated(op_t) - t2 = peek_token(ps, 2) - if !preceding_whitespace(t2) && kind(t2) in KSet"Integer Float Float32" + if !preceding_whitespace(t2) && (k2 in KSet"Integer Float Float32" || + (op_k == K"+" && k2 in KSet"BinInt HexInt OctInt")) + k3 = peek(ps, 3) if is_prec_power(k3) || k3 in KSet"[ {" # `[`, `{` (issue #18851) and `^` have higher precedence than @@ -1176,13 +1179,12 @@ function parse_unary(ps::ParseState) # +2.0 ==> 2.0 # -1.0f0 ==> -1.0f0 # -2*x ==> (call-i -2 * x) + # +0xff ==> 0xff bump_glue(ps, kind(t2), EMPTY_FLAGS, 2) end return end end - t2 = peek_token(ps, 2) - k2 = kind(t2) if is_closing_token(ps, k2) || k2 in KSet"NewlineWs =" if is_dotted(op_t) # Standalone dotted operators are parsed as (|.| op) diff --git a/src/value_parsing.jl b/src/value_parsing.jl index 042cca0a..f83bc891 100644 --- a/src/value_parsing.jl +++ b/src/value_parsing.jl @@ -20,7 +20,10 @@ function parse_int_literal(str::AbstractString) end function parse_uint_literal(str::AbstractString, k) - str = replace(replace(str, '_'=>""), '−'=>'-') + str = replace(str, '_'=>"") + if startswith(str, '+') + str = str[2:end] + end ndigits = length(str)-2 if k == K"HexInt" return ndigits <= 2 ? Base.parse(UInt8, str) : @@ -30,7 +33,6 @@ function parse_uint_literal(str::AbstractString, k) ndigits <= 32 ? Base.parse(UInt128, str) : Base.parse(BigInt, str) elseif k == K"BinInt" - str = replace(replace(str, '_'=>""), '−'=>'-') ndigits = length(str)-2 return ndigits <= 8 ? Base.parse(UInt8, str) : ndigits <= 16 ? Base.parse(UInt16, str) : diff --git a/test/parser.jl b/test/parser.jl index 82b3e144..c552f939 100644 --- a/test/parser.jl +++ b/test/parser.jl @@ -177,9 +177,17 @@ tests = [ "isa::T" => "(:: isa T)" "-2^x" => "(call-pre - (call-i 2 ^ x))" "-2[1, 3]" => "(call-pre - (ref 2 1 3))" + # signed literals "-2" => "-2" "+2.0" => "2.0" "-1.0f0" => "-1.0f0" + "-0xf.0p0" => "-15.0" + "+0b10010" => "0x12" + "+0o22" => "0x12" + "+0x12" => "0x12" + "-0b10010" => "(call-pre - 0x12)" + "-0o22" => "(call-pre - 0x12)" + "-0x12" => "(call-pre - 0x12)" # Standalone dotted operators are parsed as (|.| op) ".+" => "(. +)" ".+\n" => "(. +)"