@@ -71,8 +71,8 @@ function peek_token(ps::ParseState, n=1; skip_newlines=nothing)
71
71
peek_token (ps. stream, n, skip_newlines= skip_nl)
72
72
end
73
73
74
- function peek_behind (ps:: ParseState , args... )
75
- peek_behind (ps. stream, args... )
74
+ function peek_behind (ps:: ParseState , args... ; kws ... )
75
+ peek_behind (ps. stream, args... ; kws ... )
76
76
end
77
77
78
78
function bump (ps:: ParseState , flags= EMPTY_FLAGS; skip_newlines= nothing , kws... )
@@ -1336,20 +1336,15 @@ function parse_identifier_or_interpolate(ps::ParseState)
1336
1336
end
1337
1337
end
1338
1338
1339
- # Emit an error if the call chain syntax is not a valid module reference
1340
- function emit_modref_error (ps, mark)
1341
- emit (ps, mark, K " error" , error= " not a valid module reference" )
1342
- end
1343
-
1344
- function finish_macroname (ps, mark, is_valid_modref, macro_name_position,
1339
+ function finish_macroname (ps, mark, valid_macroname, macro_name_position,
1345
1340
name_kind= nothing )
1346
- if is_valid_modref
1341
+ if valid_macroname
1347
1342
if isnothing (name_kind)
1348
1343
name_kind = macro_name_kind (peek_behind (ps, macro_name_position). kind)
1349
1344
end
1350
1345
reset_node! (ps, macro_name_position, kind = name_kind)
1351
1346
else
1352
- emit (ps, mark, K " error" , error= " not a valid module reference " )
1347
+ emit (ps, mark, K " error" , error= " not a valid macro name or macro module path " )
1353
1348
end
1354
1349
end
1355
1350
@@ -1367,14 +1362,13 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1367
1362
end
1368
1363
# source range of the @-prefixed part of a macro
1369
1364
macro_atname_range = nothing
1370
- kb = peek_behind (ps). kind
1371
1365
# $A.@x ==> (macrocall (. ($ A) (quote @x)))
1372
- is_valid_modref = kb in KSet ` Identifier . $`
1366
+ valid_macroname = peek_behind (ps, skip_trivia = false ) . kind in KSet ` Identifier . $`
1373
1367
# We record the last component of chains of dot-separated identifiers so we
1374
1368
# know which identifier was the macro name.
1375
1369
macro_name_position = position (ps) # points to same output span as peek_behind
1376
1370
while true
1377
- this_iter_valid_modref = false
1371
+ this_iter_valid_macroname = false
1378
1372
t = peek_token (ps)
1379
1373
k = kind (t)
1380
1374
if is_macrocall && (t. had_whitespace || is_closing_token (ps, k))
@@ -1384,7 +1378,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1384
1378
# @foo (x,y) ==> (macrocall @foo (tuple x y))
1385
1379
# a().@x y ==> (macrocall (error (. (call a) (quote x))) y)
1386
1380
# [@foo "x"] ==> (vect (macrocall @foo "x"))
1387
- finish_macroname (ps, mark, is_valid_modref , macro_name_position)
1381
+ finish_macroname (ps, mark, valid_macroname , macro_name_position)
1388
1382
with_space_sensitive (ps) do ps
1389
1383
# Space separated macro arguments
1390
1384
# A.@foo a b ==> (macrocall (. A (quote @foo)) a b)
@@ -1420,7 +1414,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1420
1414
elseif k == K " ("
1421
1415
if is_macrocall
1422
1416
# a().@x(y) ==> (macrocall (error (. (call a) (quote x))) y)
1423
- finish_macroname (ps, mark, is_valid_modref , macro_name_position)
1417
+ finish_macroname (ps, mark, valid_macroname , macro_name_position)
1424
1418
end
1425
1419
# f(a,b) ==> (call f a b)
1426
1420
# f (a) ==> (call f (error-t) a b)
@@ -1443,7 +1437,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1443
1437
elseif k == K " ["
1444
1438
if is_macrocall
1445
1439
# a().@x[1] ==> (macrocall (ref (error (. (call a) (quote x))) 1))
1446
- finish_macroname (ps, mark, is_valid_modref , macro_name_position)
1440
+ finish_macroname (ps, mark, valid_macroname , macro_name_position)
1447
1441
end
1448
1442
# a [i] ==> (ref a (error-t) i)
1449
1443
bump_disallowed_space (ps)
@@ -1479,7 +1473,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1479
1473
bump (ps)
1480
1474
emit (ps, emark, K " error" , TRIVIA_FLAG,
1481
1475
error= " the .' operator for transpose is discontinued" )
1482
- is_valid_modref = false
1476
+ valid_macroname = false
1483
1477
continue
1484
1478
end
1485
1479
if ! isnothing (macro_atname_range)
@@ -1529,7 +1523,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1529
1523
emit (ps, m, K " inert" )
1530
1524
emit (ps, mark, K " ." )
1531
1525
# A.$B.@x ==> (macrocall (. (. A (inert ($ B))) (quote @x)))
1532
- this_iter_valid_modref = true
1526
+ this_iter_valid_macroname = true
1533
1527
elseif k == K " @"
1534
1528
# A macro call after some prefix A has been consumed
1535
1529
# A.@x ==> (macrocall (. A (quote @x)))
@@ -1547,7 +1541,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1547
1541
macro_atname_range = (m, macro_name_position)
1548
1542
emit (ps, m, K " quote" )
1549
1543
emit (ps, mark, K " ." )
1550
- this_iter_valid_modref = true
1544
+ this_iter_valid_macroname = true
1551
1545
else
1552
1546
# Field/property syntax
1553
1547
# f.x.y ==> (. (. f (quote x)) (quote y))
@@ -1556,7 +1550,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1556
1550
macro_name_position = position (ps)
1557
1551
emit (ps, m, K " quote" )
1558
1552
emit (ps, mark, K " ." )
1559
- this_iter_valid_modref = true
1553
+ this_iter_valid_macroname = true
1560
1554
end
1561
1555
elseif k == K " '"
1562
1556
if ! is_suffixed (t)
@@ -1572,7 +1566,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1572
1566
# Type parameter curlies and macro calls
1573
1567
if is_macrocall
1574
1568
# a().@x{y} ==> (macrocall (error (. (call a) (quote x))) (braces y))
1575
- finish_macroname (ps, mark, is_valid_modref , macro_name_position)
1569
+ finish_macroname (ps, mark, valid_macroname , macro_name_position)
1576
1570
end
1577
1571
m = position (ps)
1578
1572
# S {a} ==> (curly S (error-t) a)
@@ -1590,7 +1584,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1590
1584
emit (ps, mark, K " curly" )
1591
1585
end
1592
1586
elseif k in KSet ` " """ \` \`\`\` ` &&
1593
- ! t. had_whitespace && is_valid_modref
1587
+ ! t. had_whitespace && valid_macroname
1594
1588
# Custom string and command literals
1595
1589
# x"str" ==> (macrocall @x_str "str")
1596
1590
# x`str` ==> (macrocall @x_cmd "str")
@@ -1600,7 +1594,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1600
1594
# Use a special token kind for string and cmd macro names so the
1601
1595
# names can be expanded later as necessary.
1602
1596
outk = is_string_delim (k) ? K " StringMacroName" : K " CmdMacroName"
1603
- finish_macroname (ps, mark, is_valid_modref , macro_name_position, outk)
1597
+ finish_macroname (ps, mark, valid_macroname , macro_name_position, outk)
1604
1598
parse_raw_string (ps)
1605
1599
t = peek_token (ps)
1606
1600
k = kind (t)
@@ -1619,7 +1613,7 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1619
1613
else
1620
1614
break
1621
1615
end
1622
- is_valid_modref &= this_iter_valid_modref
1616
+ valid_macroname &= this_iter_valid_macroname
1623
1617
end
1624
1618
end
1625
1619
@@ -2175,22 +2169,24 @@ function macro_name_kind(k)
2175
2169
end
2176
2170
2177
2171
# If remap_kind is false, the kind will be remapped by parse_call_chain after
2178
- # it discovers the macro name component of the module path.
2172
+ # it discovers which component of the macro's module path is the macro name .
2179
2173
#
2180
2174
# flisp: parse-macro-name
2181
- function parse_macro_name (ps:: ParseState ; remap_kind = false )
2175
+ function parse_macro_name (ps:: ParseState )
2182
2176
bump_disallowed_space (ps)
2183
- if peek (ps) == K " ."
2184
- # @. y ==> (macrocall (quote @__dot__) y)
2177
+ mark = position (ps)
2178
+ k = peek (ps)
2179
+ if k == K " ."
2180
+ # @. y ==> (macrocall @__dot__ y)
2185
2181
bump (ps)
2186
2182
else
2183
+ # @! x ==> (macrocall @! x)
2184
+ # @.. x ==> (macrocall @.. x)
2185
+ # @$ x ==> (macrocall @$ x)
2187
2186
with_space_sensitive (ps) do ps1
2188
2187
parse_atom (ps1, false )
2189
2188
end
2190
2189
end
2191
- if remap_kind
2192
- reset_node! (ps, position (ps), kind= macro_name_kind (peek_behind (ps). kind))
2193
- end
2194
2190
end
2195
2191
2196
2192
# Parse an identifier, interpolation of @-prefixed symbol
@@ -2202,7 +2198,8 @@ function parse_atsym(ps::ParseState)
2202
2198
# export @a ==> (export @a)
2203
2199
# export a, \n @b ==> (export a @b)
2204
2200
bump (ps, TRIVIA_FLAG)
2205
- parse_macro_name (ps, remap_kind= true )
2201
+ parse_macro_name (ps)
2202
+ reset_node! (ps, position (ps), kind= macro_name_kind (peek_behind (ps). kind))
2206
2203
else
2207
2204
# export a ==> (export a)
2208
2205
# export \n a ==> (export a)
@@ -3133,7 +3130,10 @@ function parse_atom(ps::ParseState, check_identifiers=true)
3133
3130
# Quoted syntactic operators allowed
3134
3131
# :+= ==> (quote +=)
3135
3132
# :.= ==> (quote .=)
3136
- bump (ps)
3133
+ # Remap the kind here to K"Identifier", as operators parsed in this
3134
+ # branch should be in "identifier-like" positions (I guess this is
3135
+ # correct? is it convenient?)
3136
+ bump (ps, remap_kind= K " Identifier" )
3137
3137
end
3138
3138
elseif is_keyword (leading_kind)
3139
3139
if leading_kind == K " var" && (t = peek_token (ps,2 );
0 commit comments