|
1 | 1 | # This file is a part of Julia. License is MIT: https://julialang.org/license
|
2 | 2 |
|
3 | 3 | using .Compiler: has_typevar
|
| 4 | +using .Meta: isidentifier, isoperator, isunaryoperator, isbinaryoperator, ispostfixoperator, |
| 5 | + is_id_start_char, is_id_char, _isoperator, is_syntactic_operator, is_valid_identifier |
4 | 6 |
|
5 | 7 | function show(io::IO, ::MIME"text/plain", u::UndefInitializer)
|
6 | 8 | show(io, u)
|
@@ -1542,104 +1544,6 @@ const expr_parens = Dict(:tuple=>('(',')'), :vcat=>('[',']'),
|
1542 | 1544 | :ncat =>('[',']'), :nrow =>('[',']'),
|
1543 | 1545 | :braces=>('{','}'), :bracescat=>('{','}'))
|
1544 | 1546 |
|
1545 |
| -## AST decoding helpers ## |
1546 |
| - |
1547 |
| -is_id_start_char(c::AbstractChar) = ccall(:jl_id_start_char, Cint, (UInt32,), c) != 0 |
1548 |
| -is_id_char(c::AbstractChar) = ccall(:jl_id_char, Cint, (UInt32,), c) != 0 |
1549 |
| - |
1550 |
| -""" |
1551 |
| - isidentifier(s) -> Bool |
1552 |
| -
|
1553 |
| -Return whether the symbol or string `s` contains characters that are parsed as |
1554 |
| -a valid ordinary identifier (not a binary/unary operator) in Julia code; |
1555 |
| -see also [`Base.isoperator`](@ref). |
1556 |
| -
|
1557 |
| -Internally Julia allows any sequence of characters in a `Symbol` (except `\\0`s), |
1558 |
| -and macros automatically use variable names containing `#` in order to avoid |
1559 |
| -naming collision with the surrounding code. In order for the parser to |
1560 |
| -recognize a variable, it uses a limited set of characters (greatly extended by |
1561 |
| -Unicode). `isidentifier()` makes it possible to query the parser directly |
1562 |
| -whether a symbol contains valid characters. |
1563 |
| -
|
1564 |
| -# Examples |
1565 |
| -```jldoctest |
1566 |
| -julia> Meta.isidentifier(:x), Meta.isidentifier("1x") |
1567 |
| -(true, false) |
1568 |
| -``` |
1569 |
| -""" |
1570 |
| -function isidentifier(s::AbstractString) |
1571 |
| - x = Iterators.peel(s) |
1572 |
| - isnothing(x) && return false |
1573 |
| - (s == "true" || s == "false") && return false |
1574 |
| - c, rest = x |
1575 |
| - is_id_start_char(c) || return false |
1576 |
| - return all(is_id_char, rest) |
1577 |
| -end |
1578 |
| -isidentifier(s::Symbol) = isidentifier(string(s)) |
1579 |
| - |
1580 |
| -is_op_suffix_char(c::AbstractChar) = ccall(:jl_op_suffix_char, Cint, (UInt32,), c) != 0 |
1581 |
| - |
1582 |
| -_isoperator(s) = ccall(:jl_is_operator, Cint, (Cstring,), s) != 0 |
1583 |
| - |
1584 |
| -""" |
1585 |
| - isoperator(s::Symbol) |
1586 |
| -
|
1587 |
| -Return `true` if the symbol can be used as an operator, `false` otherwise. |
1588 |
| -
|
1589 |
| -# Examples |
1590 |
| -```jldoctest |
1591 |
| -julia> Meta.isoperator(:+), Meta.isoperator(:f) |
1592 |
| -(true, false) |
1593 |
| -``` |
1594 |
| -""" |
1595 |
| -isoperator(s::Union{Symbol,AbstractString}) = _isoperator(s) || ispostfixoperator(s) |
1596 |
| - |
1597 |
| -""" |
1598 |
| - isunaryoperator(s::Symbol) |
1599 |
| -
|
1600 |
| -Return `true` if the symbol can be used as a unary (prefix) operator, `false` otherwise. |
1601 |
| -
|
1602 |
| -# Examples |
1603 |
| -```jldoctest |
1604 |
| -julia> Meta.isunaryoperator(:-), Meta.isunaryoperator(:√), Meta.isunaryoperator(:f) |
1605 |
| -(true, true, false) |
1606 |
| -``` |
1607 |
| -""" |
1608 |
| -isunaryoperator(s::Symbol) = ccall(:jl_is_unary_operator, Cint, (Cstring,), s) != 0 |
1609 |
| -is_unary_and_binary_operator(s::Symbol) = ccall(:jl_is_unary_and_binary_operator, Cint, (Cstring,), s) != 0 |
1610 |
| -is_syntactic_operator(s::Symbol) = ccall(:jl_is_syntactic_operator, Cint, (Cstring,), s) != 0 |
1611 |
| - |
1612 |
| -""" |
1613 |
| - isbinaryoperator(s::Symbol) |
1614 |
| -
|
1615 |
| -Return `true` if the symbol can be used as a binary (infix) operator, `false` otherwise. |
1616 |
| -
|
1617 |
| -# Examples |
1618 |
| -```jldoctest |
1619 |
| -julia> Meta.isbinaryoperator(:-), Meta.isbinaryoperator(:√), Meta.isbinaryoperator(:f) |
1620 |
| -(true, false, false) |
1621 |
| -``` |
1622 |
| -""" |
1623 |
| -function isbinaryoperator(s::Symbol) |
1624 |
| - return _isoperator(s) && (!isunaryoperator(s) || is_unary_and_binary_operator(s)) && |
1625 |
| - s !== Symbol("'") |
1626 |
| -end |
1627 |
| - |
1628 |
| -""" |
1629 |
| - ispostfixoperator(s::Union{Symbol,AbstractString}) |
1630 |
| -
|
1631 |
| -Return `true` if the symbol can be used as a postfix operator, `false` otherwise. |
1632 |
| -
|
1633 |
| -# Examples |
1634 |
| -```jldoctest |
1635 |
| -julia> Meta.ispostfixoperator(Symbol("'")), Meta.ispostfixoperator(Symbol("'ᵀ")), Meta.ispostfixoperator(:-) |
1636 |
| -(true, true, false) |
1637 |
| -``` |
1638 |
| -""" |
1639 |
| -function ispostfixoperator(s::Union{Symbol,AbstractString}) |
1640 |
| - s = String(s)::String |
1641 |
| - return startswith(s, '\'') && all(is_op_suffix_char, SubString(s, 2)) |
1642 |
| -end |
1643 | 1547 |
|
1644 | 1548 | """
|
1645 | 1549 | operator_precedence(s::Symbol)
|
@@ -1778,19 +1682,6 @@ function show_enclosed_list(io::IO, op, items, sep, cl, indent, prec=0, quote_le
|
1778 | 1682 | print(io, cl)
|
1779 | 1683 | end
|
1780 | 1684 |
|
1781 |
| -const keyword_syms = Set([ |
1782 |
| - :baremodule, :begin, :break, :catch, :const, :continue, :do, :else, :elseif, |
1783 |
| - :end, :export, :var"false", :finally, :for, :function, :global, :if, :import, |
1784 |
| - :let, :local, :macro, :module, :public, :quote, :return, :struct, :var"true", |
1785 |
| - :try, :using, :while ]) |
1786 |
| - |
1787 |
| -function is_valid_identifier(sym) |
1788 |
| - return (isidentifier(sym) && !(sym in keyword_syms)) || |
1789 |
| - (_isoperator(sym) && |
1790 |
| - !(sym in (Symbol("'"), :(::), :?)) && |
1791 |
| - !is_syntactic_operator(sym) |
1792 |
| - ) |
1793 |
| -end |
1794 | 1685 |
|
1795 | 1686 | # show a normal (non-operator) function call, e.g. f(x, y) or A[z]
|
1796 | 1687 | # kw: `=` expressions are parsed with head `kw` in this context
|
|
0 commit comments