@@ -1302,10 +1302,10 @@ function parse_unary(ps::ParseState)
1302
1302
# +(a,b)(x)^2 ==> (call-i (call (call + a b) x) ^ 2)
1303
1303
if is_type_operator (op_t)
1304
1304
# <:(a,) ==> (<: a)
1305
- emit (ps, mark, op_k)
1305
+ emit (ps, mark, op_k, opts . delim_flags )
1306
1306
reset_node! (ps, op_pos, flags= TRIVIA_FLAG)
1307
1307
else
1308
- emit (ps, mark, K " call" )
1308
+ emit (ps, mark, K " call" , opts . delim_flags )
1309
1309
end
1310
1310
parse_call_chain (ps, mark)
1311
1311
parse_factor_with_initial_ex (ps, mark)
@@ -1552,13 +1552,14 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1552
1552
# f (a) ==> (call f (error-t) a)
1553
1553
bump_disallowed_space (ps)
1554
1554
bump (ps, TRIVIA_FLAG)
1555
- parse_call_arglist (ps, K " )" )
1555
+ opts = parse_call_arglist (ps, K " )" )
1556
1556
if peek (ps) == K " do"
1557
1557
# f(x) do y body end ==> (call f x (do (tuple y) (block body)))
1558
1558
parse_do (ps)
1559
1559
end
1560
1560
emit (ps, mark, is_macrocall ? K " macrocall" : K " call" ,
1561
- is_macrocall ? PARENS_FLAG : EMPTY_FLAGS)
1561
+ # TODO : Add PARENS_FLAG to all calls which use them?
1562
+ (is_macrocall ? PARENS_FLAG : EMPTY_FLAGS)| opts. delim_flags)
1562
1563
if is_macrocall
1563
1564
# @x(a, b) ==> (macrocall-p @x a b)
1564
1565
# A.@x(y) ==> (macrocall-p (. A @x) y)
@@ -1634,8 +1635,8 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1634
1635
# f. (x) ==> (dotcall f (error-t) x)
1635
1636
bump_disallowed_space (ps)
1636
1637
bump (ps, TRIVIA_FLAG)
1637
- parse_call_arglist (ps, K " )" )
1638
- emit (ps, mark, K " dotcall" )
1638
+ opts = parse_call_arglist (ps, K " )" )
1639
+ emit (ps, mark, K " dotcall" , opts . delim_flags )
1639
1640
elseif k == K " :"
1640
1641
# A.:+ ==> (. A (quote-: +))
1641
1642
# A.: + ==> (. A (error-t) (quote-: +))
@@ -1697,20 +1698,20 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1697
1698
# S {a} ==> (curly S (error-t) a)
1698
1699
bump_disallowed_space (ps)
1699
1700
bump (ps, TRIVIA_FLAG)
1700
- parse_call_arglist (ps, K " }" )
1701
+ opts = parse_call_arglist (ps, K " }" )
1701
1702
if is_macrocall
1702
1703
# @S{a,b} ==> (macrocall S (braces a b))
1703
1704
# A.@S{a} ==> (macrocall (. A @S) (braces a))
1704
1705
# @S{a}.b ==> (. (macrocall @S (braces a)) b)
1705
1706
fix_macro_name_kind! (ps, macro_name_position)
1706
- emit (ps, m, K " braces" )
1707
+ emit (ps, m, K " braces" , opts . delim_flags )
1707
1708
emit (ps, mark, K " macrocall" )
1708
1709
min_supported_version (v " 1.6" , ps, mark, " macro call without space before `{}`" )
1709
1710
is_macrocall = false
1710
1711
macro_atname_range = nothing
1711
1712
else
1712
1713
# S{a,b} ==> (curly S a b)
1713
- emit (ps, mark, K " curly" )
1714
+ emit (ps, mark, K " curly" , opts . delim_flags )
1714
1715
end
1715
1716
elseif k in KSet " \" \"\"\" ` ``` " &&
1716
1717
! preceding_whitespace (t) && maybe_strmac &&
@@ -2151,7 +2152,7 @@ function parse_function_signature(ps::ParseState, is_function::Bool)
2151
2152
# function (f(x),) end ==> (function (tuple-p (call f x)) (block))
2152
2153
ambiguous_parens = opts. maybe_grouping_parens &&
2153
2154
peek_behind (ps). kind in KSet " macrocall $"
2154
- emit (ps, mark, K " tuple" , PARENS_FLAG)
2155
+ emit (ps, mark, K " tuple" , PARENS_FLAG| opts . delim_flags )
2155
2156
if ambiguous_parens
2156
2157
# Got something like `(@f(x))`. Is it anon `(@f(x),)` or named sig `@f(x)` ??
2157
2158
emit (ps, mark, K " error" , error= " Ambiguous signature. Add a trailing comma if this is a 1-argument anonymous function; remove parentheses if this is a macro call acting as function signature." )
@@ -2716,16 +2717,21 @@ end
2716
2717
# surrounding brackets.
2717
2718
#
2718
2719
# flisp: parse-vect
2719
- function parse_vect (ps:: ParseState , closer)
2720
+ function parse_vect (ps:: ParseState , closer, prefix_trailing_comma )
2720
2721
# [x, y] ==> (vect x y)
2721
2722
# [x, y] ==> (vect x y)
2722
2723
# [x,y ; z] ==> (vect x y (parameters z))
2723
2724
# [x=1, y=2] ==> (vect (= x 1) (= y 2))
2724
2725
# [x=1, ; y=2] ==> (vect (= x 1) (parameters (= y 2)))
2725
- parse_brackets (ps, closer) do _, _, _, _
2726
- return (needs_parameters= true ,)
2726
+ opts = parse_brackets (ps, closer) do _, _, _, num_subexprs
2727
+ return (needs_parameters= true ,
2728
+ num_subexprs= num_subexprs)
2729
+ end
2730
+ delim_flags = opts. delim_flags
2731
+ if opts. num_subexprs == 0 && prefix_trailing_comma
2732
+ delim_flags |= TRAILING_COMMA_FLAG
2727
2733
end
2728
- return (K " vect" , EMPTY_FLAGS )
2734
+ return (K " vect" , delim_flags )
2729
2735
end
2730
2736
2731
2737
# Parse generators
@@ -2988,7 +2994,7 @@ function parse_cat(ps::ParseState, closer, end_is_symbol)
2988
2994
mark = position (ps)
2989
2995
if k == closer
2990
2996
# [] ==> (vect)
2991
- return parse_vect (ps, closer)
2997
+ return parse_vect (ps, closer, false )
2992
2998
elseif k == K " ;"
2993
2999
# v1.8: [;] ==> (ncat-1)
2994
3000
# v1.8: [;;] ==> (ncat-2)
@@ -3003,14 +3009,15 @@ function parse_cat(ps::ParseState, closer, end_is_symbol)
3003
3009
parse_eq_star (ps)
3004
3010
k = peek (ps, skip_newlines= true )
3005
3011
if k == K " ," || (is_closing_token (ps, k) && k != K " ;" )
3006
- if k == K " ,"
3012
+ prefix_trailing_comma = k == K " ,"
3013
+ if prefix_trailing_comma
3007
3014
# [x,] ==> (vect x)
3008
3015
bump (ps, TRIVIA_FLAG; skip_newlines = true )
3009
3016
end
3010
3017
# [x] ==> (vect x)
3011
3018
# [x \n ] ==> (vect x)
3012
3019
# [x ==> (vect x (error-t))
3013
- parse_vect (ps, closer)
3020
+ parse_vect (ps, closer, prefix_trailing_comma )
3014
3021
elseif k == K " for"
3015
3022
# [x for a in as] ==> (comprehension (generator x (iteration (in a as))))
3016
3023
# [x \n\n for a in as] ==> (comprehension (generator x (iteration (in a as))))
@@ -3087,7 +3094,7 @@ function parse_paren(ps::ParseState, check_identifiers=true)
3087
3094
# (; a=1; b=2) ==> (tuple-p (parameters (= a 1)) (parameters (= b 2)))
3088
3095
# (a; b; c,d) ==> (tuple-p a (parameters b) (parameters c d))
3089
3096
# (a=1, b=2; c=3) ==> (tuple-p (= a 1) (= b 2) (parameters (= c 3)))
3090
- emit (ps, mark, K " tuple" , PARENS_FLAG)
3097
+ emit (ps, mark, K " tuple" , PARENS_FLAG| opts . delim_flags )
3091
3098
elseif opts. is_block
3092
3099
# Blocks
3093
3100
# (;;) ==> (block-p)
@@ -3135,6 +3142,7 @@ function parse_brackets(after_parse::Function,
3135
3142
had_commas = false
3136
3143
had_splat = false
3137
3144
param_start = nothing
3145
+ trailing_comma = false
3138
3146
while true
3139
3147
k = peek (ps)
3140
3148
if k == closing_kind
@@ -3150,11 +3158,13 @@ function parse_brackets(after_parse::Function,
3150
3158
bump (ps, TRIVIA_FLAG)
3151
3159
bump_trivia (ps)
3152
3160
elseif is_closing_token (ps, k)
3161
+ trailing_comma = false
3153
3162
# Error; handled below in bump_closing_token
3154
3163
break
3155
3164
else
3156
3165
mark = position (ps)
3157
3166
parse_eq_star (ps)
3167
+ trailing_comma = false
3158
3168
num_subexprs += 1
3159
3169
if num_subexprs == 1
3160
3170
had_splat = peek_behind (ps). kind == K " ..."
@@ -3172,6 +3182,7 @@ function parse_brackets(after_parse::Function,
3172
3182
if k == K " ,"
3173
3183
had_commas = true
3174
3184
bump (ps, TRIVIA_FLAG)
3185
+ trailing_comma = true
3175
3186
elseif k == K " ;" || k == closing_kind
3176
3187
# Handled above
3177
3188
continue
@@ -3193,7 +3204,7 @@ function parse_brackets(after_parse::Function,
3193
3204
end
3194
3205
release_positions (ps. stream, params_positions)
3195
3206
bump_closing_token (ps, closing_kind, " or `,`" )
3196
- return opts
3207
+ return (; opts... , delim_flags = trailing_comma ? TRAILING_COMMA_FLAG : EMPTY_FLAGS)
3197
3208
end
3198
3209
3199
3210
_is_indentation (b:: UInt8 ) = (b == u8 " " || b == u8 "\t " )
@@ -3420,14 +3431,15 @@ end
3420
3431
function emit_braces (ps, mark, ckind, cflags)
3421
3432
if ckind == K " hcat"
3422
3433
# {x y} ==> (bracescat (row x y))
3423
- emit (ps, mark, K " row" , cflags)
3434
+ emit (ps, mark, K " row" , cflags & ~ TRAILING_COMMA_FLAG )
3424
3435
elseif ckind == K " ncat"
3425
3436
# {x ;;; y} ==> (bracescat (nrow-3 x y))
3426
- emit (ps, mark, K " nrow" , cflags)
3437
+ emit (ps, mark, K " nrow" , cflags & ~ TRAILING_COMMA_FLAG )
3427
3438
end
3428
3439
check_ncat_compat (ps, mark, ckind)
3429
3440
outk = ckind in KSet " vect comprehension" ? K " braces" : K " bracescat"
3430
- emit (ps, mark, outk)
3441
+ delim_flags = outk == K " braces" ? (cflags & TRAILING_COMMA_FLAG) : EMPTY_FLAGS
3442
+ emit (ps, mark, outk, delim_flags)
3431
3443
end
3432
3444
3433
3445
# parse numbers, identifiers, parenthesized expressions, lists, vectors, etc.
0 commit comments