@@ -1505,6 +1505,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1505
1505
# 2(x) ==> (* 2 x)
1506
1506
return
1507
1507
end
1508
+ is_macrocall_on_entry = is_macrocall
1508
1509
# source range of the @-prefixed part of a macro
1509
1510
macro_atname_range = nothing
1510
1511
# $A.@x ==> (macrocall (. ($ A) @x))
@@ -1533,7 +1534,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1533
1534
# A.@var"#" a ==> (macrocall (. A (var @#)) a)
1534
1535
# @+x y ==> (macrocall @+ x y)
1535
1536
# [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 " )
1537
1538
let ps = with_space_sensitive (ps)
1538
1539
# Space separated macro arguments
1539
1540
# A.@foo a b ==> (macrocall (. A @foo) a b)
@@ -1566,6 +1567,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1566
1567
# f(a; b; c) ==> (call f a (parameters b) (parameters c))
1567
1568
# (a=1)() ==> (call (parens (= a 1)))
1568
1569
# f (a) ==> (call f (error-t) a)
1570
+ is_macrocall_on_entry && emit (ps, mark, K " macro_name" )
1569
1571
bump_disallowed_space (ps)
1570
1572
bump (ps, TRIVIA_FLAG)
1571
1573
opts = parse_call_arglist (ps, K " )" )
@@ -1580,11 +1582,13 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1580
1582
# @x(a, b) ==> (macrocall-p @x a b)
1581
1583
# A.@x(y) ==> (macrocall-p (. A @x) y)
1582
1584
# A.@x(y).z ==> (. (macrocall-p (. A @x) y) z)
1583
- fix_macro_name_kind!(ps, macro_name_position)
1584
1585
is_macrocall = false
1586
+ # @f()() ==> (call (macrocall-p (macro_name f)))
1587
+ is_macrocall_on_entry = false
1585
1588
macro_atname_range = nothing
1586
1589
end
1587
1590
elseif k == K " ["
1591
+ is_macrocall_on_entry && emit (ps, mark, K " macro_name" )
1588
1592
m = position (ps)
1589
1593
# a [i] ==> (ref a (error-t) i)
1590
1594
bump_disallowed_space (ps)
@@ -1599,7 +1603,6 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1599
1603
# @S[a].b ==> (. (macrocall @S (vect a)) b)
1600
1604
# v1.7: @S[a ;; b] ==> (macrocall @S (ncat-2 a b))
1601
1605
# v1.6: @S[a ;; b] ==> (macrocall @S (error (ncat-2 a b)))
1602
- fix_macro_name_kind!(ps, macro_name_position)
1603
1606
emit (ps, m, ckind, cflags | set_numeric_flags (dim))
1604
1607
check_ncat_compat (ps, m, ckind)
1605
1608
emit (ps, mark, K " macrocall" )
@@ -1643,12 +1646,18 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1643
1646
emit_diagnostic (ps, macro_atname_range... ,
1644
1647
error= " `@` must appear on first or last macro name component" )
1645
1648
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
1646
1652
else
1647
1653
bump (ps, TRIVIA_FLAG)
1648
1654
end
1649
1655
k = peek (ps)
1650
1656
if k == K " ("
1651
1657
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
1652
1661
# @M.(x) ==> (macrocall (dotcall @M (error-t) x))
1653
1662
bump_invisible (ps, K " error" , TRIVIA_FLAG)
1654
1663
emit_diagnostic (ps, mark,
@@ -1677,7 +1686,11 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1677
1686
m = position (ps)
1678
1687
bump (ps, TRIVIA_FLAG)
1679
1688
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
1681
1694
macro_name_position = position (ps)
1682
1695
emit (ps, mark, K " ." )
1683
1696
elseif k == K " @"
@@ -1690,11 +1703,12 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1690
1703
bump (ps, TRIVIA_FLAG, error= " repeated `@` in macro module path" )
1691
1704
else
1692
1705
bump (ps, TRIVIA_FLAG)
1693
- is_macrocall = true
1694
1706
end
1695
1707
parse_macro_name (ps)
1696
1708
macro_name_position = position (ps)
1709
+ ! is_macrocall && emit (ps, m, K " macro_name" )
1697
1710
macro_atname_range = (m, position (ps))
1711
+ is_macrocall = true
1698
1712
emit (ps, mark, K " ." )
1699
1713
elseif k == K " '"
1700
1714
# f.' => (dotcall-post f (error '))
@@ -1717,6 +1731,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1717
1731
bump (ps, remap_kind= K " Identifier" )
1718
1732
emit (ps, mark, K " call" , POSTFIX_OP_FLAG)
1719
1733
elseif k == K " {"
1734
+ is_macrocall_on_entry && emit (ps, mark, K " macro_name" )
1720
1735
# Type parameter curlies and macro calls
1721
1736
m = position (ps)
1722
1737
# S {a} ==> (curly S (error-t) a)
@@ -1727,7 +1742,6 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1727
1742
# @S{a,b} ==> (macrocall S (braces a b))
1728
1743
# A.@S{a} ==> (macrocall (. A @S) (braces a))
1729
1744
# @S{a}.b ==> (. (macrocall @S (braces a)) b)
1730
- fix_macro_name_kind!(ps, macro_name_position)
1731
1745
emit (ps, m, K " braces" , opts. delim_flags)
1732
1746
emit (ps, mark, K " macrocall" )
1733
1747
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)
1754
1768
#
1755
1769
# Use a special token kind for string and cmd macro names so the
1756
1770
# 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)
1759
1773
parse_string (ps, true )
1760
1774
t = peek_token (ps)
1761
1775
k = kind (t)
@@ -2039,7 +2053,7 @@ function parse_resword(ps::ParseState)
2039
2053
# export \n a ==> (export a)
2040
2054
# export \$a, \$(a*b) ==> (export (\$ a) (\$ (parens (call-i a * b))))
2041
2055
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 ))
2043
2057
emit (ps, mark, word)
2044
2058
elseif word in KSet " import using"
2045
2059
parse_imports (ps)
@@ -2372,34 +2386,6 @@ function _is_valid_macro_name(peektok)
2372
2386
return ! is_error (peektok. kind) && (peektok. is_leaf || peektok. kind == K " var" )
2373
2387
end
2374
2388
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
-
2403
2389
# If remap_kind is false, the kind will be remapped by parse_call_chain after
2404
2390
# it discovers which component of the macro's module path is the macro name.
2405
2391
#
@@ -2425,15 +2411,16 @@ end
2425
2411
# Parse an identifier, interpolation or @-prefixed symbol
2426
2412
#
2427
2413
# flisp: parse-atsym
2428
- function parse_atsym (ps::ParseState, allow_quotes=true)
2414
+ function parse_import_atsym (ps:: ParseState , allow_quotes= true )
2429
2415
bump_trivia (ps)
2430
2416
if peek (ps) == K " @"
2417
+ mark = position (ps)
2431
2418
# export @a ==> (export @a)
2432
2419
# export @var"'" ==> (export (var @'))
2433
2420
# export a, \n @b ==> (export a @b)
2434
2421
bump (ps, TRIVIA_FLAG)
2435
2422
parse_macro_name (ps)
2436
- fix_macro_name_kind! (ps, position(ps) )
2423
+ emit (ps, mark, K " macro_name " )
2437
2424
else
2438
2425
# export a ==> (export a)
2439
2426
# export \n a ==> (export a)
@@ -2538,7 +2525,7 @@ function parse_import(ps::ParseState, word, has_import_prefix)
2538
2525
# import A: x as y ==> (import (: (importpath A) (as (importpath x) y)))
2539
2526
# using A: x as y ==> (using (: (importpath A) (as (importpath x) y)))
2540
2527
bump (ps, TRIVIA_FLAG)
2541
- parse_atsym (ps, false)
2528
+ parse_import_atsym (ps, false )
2542
2529
emit (ps, mark, K " as" )
2543
2530
if word == K " using" && ! has_import_prefix
2544
2531
# using A as B ==> (using (error (as (importpath A) B)))
@@ -2589,7 +2576,7 @@ function parse_import_path(ps::ParseState)
2589
2576
end
2590
2577
# import @x ==> (import (importpath @x))
2591
2578
# import $A ==> (import (importpath ($ A)))
2592
- parse_atsym (ps, false)
2579
+ parse_import_atsym (ps, false )
2593
2580
while true
2594
2581
t = peek_token (ps)
2595
2582
k = kind (t)
@@ -2611,7 +2598,7 @@ function parse_import_path(ps::ParseState)
2611
2598
bump_disallowed_space (ps)
2612
2599
end
2613
2600
bump (ps, TRIVIA_FLAG)
2614
- parse_atsym (ps)
2601
+ parse_import_atsym (ps)
2615
2602
elseif k == K " ..."
2616
2603
# Import the .. operator
2617
2604
# import A... ==> (import (importpath A ..))
0 commit comments