Skip to content

Commit b0a2837

Browse files
authored
Parse function (:*=(f))() end syntax compatibly (#309)
Slightly modify the anonymous function arg list disambiguation rules so that the function signature in this syntax parses as (call (call (quote *=) f)) The package NiLang uses this, so we'd like to keep it working.
1 parent 8a47045 commit b0a2837

File tree

3 files changed

+17
-15
lines changed

3 files changed

+17
-15
lines changed

src/parser.jl

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,6 +2064,7 @@ end
20642064
function parse_function_signature(ps::ParseState, is_function::Bool)
20652065
is_anon_func = false
20662066
parsed_call = false
2067+
needs_parse_call = true
20672068

20682069
mark = position(ps)
20692070
if !is_function
@@ -2082,29 +2083,28 @@ function parse_function_signature(ps::ParseState, is_function::Bool)
20822083
end
20832084
else
20842085
if peek(ps) != K"("
2086+
# function f() end ==> (function (call f))
20852087
parse_unary_prefix(ps)
20862088
else
2087-
# When an initial parenthesis is present, we might either have
2088-
# * the function name in parens, followed by (args...)
2089-
# * an anonymous function argument list in parens
2090-
# * the whole function declaration in parens
2091-
#
2092-
# This should somewhat parse as in parse_paren() (this is what
2093-
# the flisp parser does), but that results in weird parsing of
2094-
# keyword parameters. So we peek at a following `(` instead to
2095-
# distinguish the cases here.
2089+
# When an initial parenthesis is present, we need to distinguish
2090+
# between
2091+
# * The function name in parens, followed by (args...)
2092+
# * An anonymous function argument list in parens
2093+
# * The whole function declaration, in parens
20962094
bump(ps, TRIVIA_FLAG)
20972095
is_empty_tuple = peek(ps, skip_newlines=true) == K")"
20982096
opts = parse_brackets(ps, K")") do _, _, _, _
20992097
_parsed_call = was_eventually_call(ps)
2100-
t2 = peek_token(ps, 2)
2101-
_is_anon_func = kind(t2) KSet"( ." && !_parsed_call
2098+
_needs_parse_call = peek(ps, 2) KSet"( ."
2099+
_is_anon_func = !_needs_parse_call && !_parsed_call
21022100
return (needs_parameters = _is_anon_func,
21032101
is_anon_func = _is_anon_func,
2104-
parsed_call = _parsed_call)
2102+
parsed_call = _parsed_call,
2103+
needs_parse_call = _needs_parse_call)
21052104
end
21062105
is_anon_func = opts.is_anon_func
21072106
parsed_call = opts.parsed_call
2107+
needs_parse_call = opts.needs_parse_call
21082108
if is_anon_func
21092109
# function (x) body end ==> (function (tuple-p x) (block body))
21102110
# function (x::f()) end ==> (function (tuple-p (::-i x (call f))) (block))
@@ -2122,6 +2122,7 @@ function parse_function_signature(ps::ParseState, is_function::Bool)
21222122
# function (:)() end ==> (function (call (parens :)) (block))
21232123
# function (x::T)() end ==> (function (call (parens (::-i x T))) (block))
21242124
# function (::T)() end ==> (function (call (parens (::-pre T))) (block))
2125+
# function (:*=(f))() end ==> (function (call (parens (call (quote-: *=) f))) (block))
21252126
emit(ps, mark, K"parens", PARENS_FLAG)
21262127
end
21272128
end
@@ -2142,7 +2143,7 @@ function parse_function_signature(ps::ParseState, is_function::Bool)
21422143
if peek(ps, skip_newlines=true) == K"end" && !is_anon_func && !parsed_call
21432144
return false
21442145
end
2145-
if !is_anon_func && !parsed_call
2146+
if needs_parse_call
21462147
# Parse function argument list
21472148
# function f(x,y) end ==> (function (call f x y) (block))
21482149
# function f{T}() end ==> (function (call (curly f T)) (block))

test/parser.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ tests = [
568568
"function (::g(x))() end" => "(function (call (parens (::-pre (call g x)))) (block))"
569569
"function (f::T{g(i)})() end" => "(function (call (parens (::-i f (curly T (call g i))))) (block))"
570570
"function (::T)() end" => "(function (call (parens (::-pre T))) (block))"
571+
"function (:*=(f))() end" => "(function (call (parens (call (quote-: *=) f))) (block))"
571572
"function begin() end" => "(function (call (error begin)) (block))"
572573
"function f() end" => "(function (call f) (block))"
573574
"function type() end" => "(function (call type) (block))"

tools/check_all_packages.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ using JuliaSyntax, Logging, TerminalLoggers, ProgressLogging, Serialization
88
include("../test/test_utils.jl")
99
include("../test/fuzz_test.jl")
1010

11-
srcpath = isempty(ARGS) ? joinpath(@__DIR__, "pkgs") : ARGS[1]
12-
source_paths = find_source_in_path(srcpath)
11+
srcpaths = isempty(ARGS) ? [joinpath(@__DIR__, "pkgs")] : abspath.(ARGS)
12+
source_paths = vcat(find_source_in_path.(srcpaths)...)
1313

1414
file_count = length(source_paths)
1515

0 commit comments

Comments
 (0)