Skip to content

Commit

Permalink
special case isoperator for ' with unicode suffix
Browse files Browse the repository at this point in the history
  • Loading branch information
simeonschaub committed Sep 12, 2020
1 parent 70a4071 commit 355a3da
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
29 changes: 26 additions & 3 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,8 @@ function isidentifier(s::AbstractString)
end
isidentifier(s::Symbol) = isidentifier(string(s))

is_op_suffix_char(c::AbstractChar) = ccall(:jl_op_suffix_char, Cint, (UInt32,), c) != 0

"""
isoperator(s::Symbol)
Expand All @@ -1139,7 +1141,9 @@ julia> Base.isoperator(:+), Base.isoperator(:f)
(true, false)
```
"""
isoperator(s::Union{Symbol,AbstractString}) = ccall(:jl_is_operator, Cint, (Cstring,), s) != 0
function isoperator(s::Union{Symbol,AbstractString})
return ccall(:jl_is_operator, Cint, (Cstring,), s) != 0 || ispostfixoperator(s)
end

"""
isunaryoperator(s::Symbol)
Expand All @@ -1166,7 +1170,26 @@ julia> Base.isbinaryoperator(:-), Base.isbinaryoperator(:√), Base.isbinaryoper
(true, false, false)
```
"""
isbinaryoperator(s::Symbol) = isoperator(s) && (!isunaryoperator(s) || is_unary_and_binary_operator(s))
function isbinaryoperator(s::Symbol)
return isoperator(s) && !ispostfixoperator(s) &&
(!isunaryoperator(s) || is_unary_and_binary_operator(s))
end

"""
ispostfixoperator(s::Union{Symbol,AbstractString})
Return `true` if the symbol can be used as a postfix operator, `false` otherwise.
# Examples
```jldoctest
julia> Base.ispostfixoperator(Symbol("'")), Base.ispostfixoperator(Symbol("'ᵀ")), Base.ispostfixoperator(:-)
(true, true, false)
```
"""
function ispostfixoperator(s::Union{Symbol,AbstractString})
s = String(s)
return startswith(s, '\'') && all(is_op_suffix_char, SubString(s, 2))
end

"""
operator_precedence(s::Symbol)
Expand Down Expand Up @@ -1589,7 +1612,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
elseif (head === Symbol("'") && nargs == 1) || (
# ' with unicode suffix is a call expression
head === :call && nargs == 2 && args[1] isa Symbol &&
occursin(r"^'[\p{Lm}]+$", string(args[1]))
ispostfixoperator(args[1]) && args[1] !== Symbol("'")
)
op, arg1 = head === Symbol("'") ? (head, args[1]) : (args[1], args[2])
if isa(arg1, Expr) || (isa(arg1, Symbol) && isoperator(arg1))
Expand Down
6 changes: 6 additions & 0 deletions test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2009,3 +2009,9 @@ end

@test sprint(show, :(a'ᵀ)) == ":(a'ᵀ)"
@test sprint(show, :((+)')) == ":((+)')"
for s in (Symbol("'"), Symbol("'⁻¹"))
@test Base.isoperator(s)
@test !Base.isunaryoperator(s)
@test !Base.isbinaryoperator(s)
@test Base.ispostfixoperator(s)
end

0 comments on commit 355a3da

Please sign in to comment.