diff --git a/base/parse.jl b/base/parse.jl index da6bfe7d40933..4309094e9fa1d 100644 --- a/base/parse.jl +++ b/base/parse.jl @@ -38,38 +38,16 @@ julia> parse(Complex{Float64}, "3.2e-1 + 4.5im") parse(T::Type, str; base = Int) parse(::Type{Union{}}, slurp...; kwargs...) = error("cannot parse a value as Union{}") -@noinline function _invalid_base(base) - throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $base")) -end - -@noinline _invalid_digit(base, char) = throw(ArgumentError("invalid base $base digit $(repr(char))")) - -function parse_char(::Type{T}, c::AbstractChar, base::Integer, throw::Bool) where T - a::UInt8 = (base <= 36 ? 10 : 36) - (2 <= base <= 62) || _invalid_base(base) - base = base % UInt8 - cp = codepoint(c) - cp = cp > 0x7a ? 0xff : cp % UInt8 - d = UInt8('0') ≤ cp ≤ UInt8('9') ? cp - UInt8('0') : - UInt8('A') ≤ cp ≤ UInt8('Z') ? cp - UInt8('A') + UInt8(10) : - UInt8('a') ≤ cp ≤ UInt8('z') ? cp - UInt8('a') + a : - 0xff - d < base || (throw ? _invalid_digit(base, c) : return nothing) - convert(T, d)::T -end - -function parse(::Type{T}, c::AbstractChar; base::Integer=10) where {T <: Integer} - @inline parse_char(T, c, base, true) +function parse(::Type{T}, c::AbstractChar; base::Integer = 10) where T<:Integer + a::Int = (base <= 36 ? 10 : 36) + 2 <= base <= 62 || throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $base")) + d = '0' <= c <= '9' ? c-'0' : + 'A' <= c <= 'Z' ? c-'A'+10 : + 'a' <= c <= 'z' ? c-'a'+a : throw(ArgumentError("invalid digit: $(repr(c))")) + d < base || throw(ArgumentError("invalid base $base digit $(repr(c))")) + convert(T, d) end -function tryparse(::Type{T}, c::AbstractChar; base::Integer=10) where {T <: Integer} - @inline parse_char(T, c, base, false) -end - -# For consistency with parse(t, AbstractString), support a `base` argument only when T<:Integer -parse(::Type{T}, c::AbstractChar) where T = @inline parse_char(T, c, 10, true) -tryparse(::Type{T}, c::AbstractChar) where T = @inline parse_char(T, c, 10, false) - function parseint_iterate(s::AbstractString, startpos::Int, endpos::Int) (0 < startpos <= endpos) || (return Char(0), 0, 0) j = startpos @@ -138,7 +116,8 @@ function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos:: return nothing end if !(2 <= base <= 62) - raise ? _invalid_base(base) : return nothing + raise && throw(ArgumentError(LazyString("invalid base: base must be 2 ≤ base ≤ 62, got ", base))) + return nothing end if i == 0 raise && throw(ArgumentError("premature end of integer: $(repr(SubString(s,startpos,endpos)))")) @@ -257,7 +236,7 @@ end if 2 <= base <= 62 return base end - _invalid_base(base) + throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $base")) end """ diff --git a/base/public.jl b/base/public.jl index 2aad8e7c1e401..3329af875a835 100644 --- a/base/public.jl +++ b/base/public.jl @@ -2,7 +2,6 @@ public # Modules - Cartesian, Checked, Filesystem, Order, diff --git a/test/parse.jl b/test/parse.jl index 0bb549caf4973..e2b94a45cc446 100644 --- a/test/parse.jl +++ b/test/parse.jl @@ -29,13 +29,6 @@ @test parse(Int, 'a', base=16) == 10 @test_throws ArgumentError parse(Int, 'a') @test_throws ArgumentError parse(Int,typemax(Char)) - - @test tryparse(Int, '8') === 8 - @test tryparse(Int, 'a') === nothing - @test tryparse(Int, 'a'; base=11) === 10 - @test tryparse(Int32, 'a'; base=11) === Int32(10) - @test tryparse(UInt8, 'f'; base=16) === 0x0f - @test tryparse(UInt8, 'f'; base=15) === nothing end # Issue 29451