@@ -1505,6 +1505,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
15051505 # 2(x) ==> (* 2 x)
15061506 return
15071507 end
1508+ is_macrocall_on_entry = is_macrocall
15081509 # source range of the @-prefixed part of a macro
15091510 macro_atname_range = nothing
15101511 # $A.@x ==> (macrocall (. ($ A) @x))
@@ -1533,7 +1534,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
15331534 # A.@var"#" a ==> (macrocall (. A (var @#)) a)
15341535 # @+x y ==> (macrocall @+ x y)
15351536 #
[email protected] ==> (macrocall (. A @.) x)
1536- fix_macro_name_kind! (ps, macro_name_position )
1537+ is_macrocall_on_entry && emit (ps, mark, K"macro_name" )
15371538 let ps = with_space_sensitive(ps)
15381539 # Space separated macro arguments
15391540 # A.@foo a b ==> (macrocall (. A @foo) a b)
@@ -1566,6 +1567,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
15661567 # f(a; b; c) ==> (call f a (parameters b) (parameters c))
15671568 # (a=1)() ==> (call (parens (= a 1)))
15681569 # f (a) ==> (call f (error-t) a)
1570+ is_macrocall_on_entry && emit(ps, mark, K"macro_name")
15691571 bump_disallowed_space(ps)
15701572 bump(ps, TRIVIA_FLAG)
15711573 opts = parse_call_arglist(ps, K")")
@@ -1580,11 +1582,13 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
15801582 # @x(a, b) ==> (macrocall-p @x a b)
15811583 # A.@x(y) ==> (macrocall-p (. A @x) y)
15821584 # A.@x(y).z ==> (. (macrocall-p (. A @x) y) z)
1583- fix_macro_name_kind!(ps, macro_name_position)
15841585 is_macrocall = false
1586+ # @f()() ==> (call (macrocall-p (macro_name f)))
1587+ is_macrocall_on_entry = false
15851588 macro_atname_range = nothing
15861589 end
15871590 elseif k == K"["
1591+ is_macrocall_on_entry && emit(ps, mark, K"macro_name")
15881592 m = position(ps)
15891593 # a [i] ==> (ref a (error-t) i)
15901594 bump_disallowed_space(ps)
@@ -1599,7 +1603,6 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
15991603 # @S[a].b ==> (. (macrocall @S (vect a)) b)
16001604 #v1.7: @S[a ;; b] ==> (macrocall @S (ncat-2 a b))
16011605 #v1.6: @S[a ;; b] ==> (macrocall @S (error (ncat-2 a b)))
1602- fix_macro_name_kind!(ps, macro_name_position)
16031606 emit(ps, m, ckind, cflags | set_numeric_flags(dim))
16041607 check_ncat_compat(ps, m, ckind)
16051608 emit(ps, mark, K"macrocall")
@@ -1643,12 +1646,18 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
16431646 emit_diagnostic(ps, macro_atname_range...,
16441647 error="`@` must appear on first or last macro name component")
16451648 bump(ps, TRIVIA_FLAG, error="Unexpected `.` after macro name")
1649+ # Recover by treating the `@` as if it had been on the wole thing
1650+ reset_node!(ps, macro_atname_range[2], kind=K"TOMBSTONE")
1651+ is_macrocall_on_entry = true
16461652 else
16471653 bump(ps, TRIVIA_FLAG)
16481654 end
16491655 k = peek(ps)
16501656 if k == K"("
16511657 if is_macrocall
1658+ is_macrocall_on_entry && emit(ps, mark, K"macro_name")
1659+ # Recover by pretending we do have the syntax
1660+ is_macrocall_on_entry = false
16521661 # @M.(x) ==> (macrocall (dotcall @M (error-t) x))
16531662 bump_invisible(ps, K"error", TRIVIA_FLAG)
16541663 emit_diagnostic(ps, mark,
@@ -1677,7 +1686,11 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
16771686 m = position(ps)
16781687 bump(ps, TRIVIA_FLAG)
16791688 parse_atom(ps)
1680- emit(ps, m, K"$")
1689+ if is_macrocall
1690+ emit(ps, m, K"error", error="invalid macro name")
1691+ else
1692+ emit(ps, m, K"$")
1693+ end
16811694 macro_name_position = position(ps)
16821695 emit(ps, mark, K".")
16831696 elseif k == K"@"
@@ -1690,11 +1703,12 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
16901703 bump(ps, TRIVIA_FLAG, error="repeated `@` in macro module path")
16911704 else
16921705 bump(ps, TRIVIA_FLAG)
1693- is_macrocall = true
16941706 end
16951707 parse_macro_name(ps)
16961708 macro_name_position = position(ps)
1709+ !is_macrocall && emit(ps, m, K"macro_name")
16971710 macro_atname_range = (m, position(ps))
1711+ is_macrocall = true
16981712 emit(ps, mark, K".")
16991713 elseif k == K"'"
17001714 # f.' => (dotcall-post f (error '))
@@ -1717,6 +1731,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
17171731 bump(ps, remap_kind=K"Identifier")
17181732 emit(ps, mark, K"call", POSTFIX_OP_FLAG)
17191733 elseif k == K"{"
1734+ is_macrocall_on_entry && emit(ps, mark, K"macro_name")
17201735 # Type parameter curlies and macro calls
17211736 m = position(ps)
17221737 # S {a} ==> (curly S (error-t) a)
@@ -1727,7 +1742,6 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
17271742 # @S{a,b} ==> (macrocall S (braces a b))
17281743 # A.@S{a} ==> (macrocall (. A @S) (braces a))
17291744 # @S{a}.b ==> (. (macrocall @S (braces a)) b)
1730- fix_macro_name_kind!(ps, macro_name_position)
17311745 emit(ps, m, K"braces", opts.delim_flags)
17321746 emit(ps, mark, K"macrocall")
17331747 min_supported_version(v"1.6", ps, mark, "macro call without space before `{}`")
@@ -1754,8 +1768,8 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
17541768 #
17551769 # Use a special token kind for string and cmd macro names so the
17561770 # names can be expanded later as necessary.
1757- outk = is_string_delim(k) ? K"StringMacroName " : K"CmdMacroName "
1758- fix_macro_name_kind! (ps, macro_name_position , outk)
1771+ outk = is_string_delim(k) ? K"macro_name_str " : K"macro_name_cmd "
1772+ emit (ps, mark , outk)
17591773 parse_string(ps, true)
17601774 t = peek_token(ps)
17611775 k = kind(t)
@@ -2039,7 +2053,7 @@ function parse_resword(ps::ParseState)
20392053 # export \n a ==> (export a)
20402054 # export \$a, \$(a*b) ==> (export (\$ a) (\$ (parens (call-i a * b))))
20412055 bump(ps, TRIVIA_FLAG)
2042- parse_comma_separated(ps, x->parse_atsym (x, false))
2056+ parse_comma_separated(ps, x->parse_import_atsym (x, false))
20432057 emit(ps, mark, word)
20442058 elseif word in KSet"import using"
20452059 parse_imports(ps)
@@ -2372,34 +2386,6 @@ function _is_valid_macro_name(peektok)
23722386 return !is_error(peektok.kind) && (peektok.is_leaf || peektok.kind == K"var")
23732387end
23742388
2375- function fix_macro_name_kind!(ps::ParseState, macro_name_position, name_kind=nothing)
2376- k = peek_behind(ps, macro_name_position).kind
2377- if k == K"var"
2378- macro_name_position = first_child_position(ps, macro_name_position)
2379- k = peek_behind(ps, macro_name_position).kind
2380- elseif k == K"parens"
2381- # @(A) x ==> (macrocall (parens @A) x)
2382- macro_name_position = first_child_position(ps, macro_name_position)
2383- if macro_name_position == NO_POSITION
2384- return
2385- end
2386- k = peek_behind(ps, macro_name_position).kind
2387- elseif k == K"error"
2388- # Error already reported in parse_macro_name
2389- return
2390- end
2391- if isnothing(name_kind)
2392- name_kind = _is_valid_macro_name(peek_behind(ps, macro_name_position)) ?
2393- K"MacroName" : K"error"
2394- if name_kind == K"error"
2395- # TODO: This isn't quite accurate
2396- emit_diagnostic(ps, macro_name_position, macro_name_position,
2397- error="invalid macro name")
2398- end
2399- end
2400- reset_node!(ps, macro_name_position, kind=name_kind)
2401- end
2402-
24032389# If remap_kind is false, the kind will be remapped by parse_call_chain after
24042390# it discovers which component of the macro's module path is the macro name.
24052391#
@@ -2425,15 +2411,16 @@ end
24252411# Parse an identifier, interpolation or @-prefixed symbol
24262412#
24272413# flisp: parse-atsym
2428- function parse_atsym (ps::ParseState, allow_quotes=true)
2414+ function parse_import_atsym (ps::ParseState, allow_quotes=true)
24292415 bump_trivia(ps)
24302416 if peek(ps) == K"@"
2417+ mark = position(ps)
24312418 # export @a ==> (export @a)
24322419 # export @var"'" ==> (export (var @'))
24332420 # export a, \n @b ==> (export a @b)
24342421 bump(ps, TRIVIA_FLAG)
24352422 parse_macro_name(ps)
2436- fix_macro_name_kind! (ps, position(ps) )
2423+ emit (ps, mark, K"macro_name" )
24372424 else
24382425 # export a ==> (export a)
24392426 # export \n a ==> (export a)
@@ -2538,7 +2525,7 @@ function parse_import(ps::ParseState, word, has_import_prefix)
25382525 # import A: x as y ==> (import (: (importpath A) (as (importpath x) y)))
25392526 # using A: x as y ==> (using (: (importpath A) (as (importpath x) y)))
25402527 bump(ps, TRIVIA_FLAG)
2541- parse_atsym (ps, false)
2528+ parse_import_atsym (ps, false)
25422529 emit(ps, mark, K"as")
25432530 if word == K"using" && !has_import_prefix
25442531 # using A as B ==> (using (error (as (importpath A) B)))
@@ -2589,7 +2576,7 @@ function parse_import_path(ps::ParseState)
25892576 end
25902577 # import @x ==> (import (importpath @x))
25912578 # import $A ==> (import (importpath ($ A)))
2592- parse_atsym (ps, false)
2579+ parse_import_atsym (ps, false)
25932580 while true
25942581 t = peek_token(ps)
25952582 k = kind(t)
@@ -2611,7 +2598,7 @@ function parse_import_path(ps::ParseState)
26112598 bump_disallowed_space(ps)
26122599 end
26132600 bump(ps, TRIVIA_FLAG)
2614- parse_atsym (ps)
2601+ parse_import_atsym (ps)
26152602 elseif k == K"..."
26162603 # Import the .. operator
26172604 # import A... ==> (import (importpath A ..))
0 commit comments