@@ -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