@@ -1302,10 +1302,10 @@ function parse_unary(ps::ParseState)
13021302 # +(a,b)(x)^2 ==> (call-i (call (call + a b) x) ^ 2)
13031303 if is_type_operator (op_t)
13041304 # <:(a,) ==> (<: a)
1305- emit (ps, mark, op_k)
1305+ emit (ps, mark, op_k, opts . delim_flags )
13061306 reset_node! (ps, op_pos, flags= TRIVIA_FLAG)
13071307 else
1308- emit (ps, mark, K " call" )
1308+ emit (ps, mark, K " call" , opts . delim_flags )
13091309 end
13101310 parse_call_chain (ps, mark)
13111311 parse_factor_with_initial_ex (ps, mark)
@@ -1552,13 +1552,14 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
15521552 # f (a) ==> (call f (error-t) a)
15531553 bump_disallowed_space (ps)
15541554 bump (ps, TRIVIA_FLAG)
1555- parse_call_arglist (ps, K " )" )
1555+ opts = parse_call_arglist (ps, K " )" )
15561556 if peek (ps) == K " do"
15571557 # f(x) do y body end ==> (call f x (do (tuple y) (block body)))
15581558 parse_do (ps)
15591559 end
15601560 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)
15621563 if is_macrocall
15631564 # @x(a, b) ==> (macrocall-p @x a b)
15641565 # A.@x(y) ==> (macrocall-p (. A @x) y)
@@ -1634,8 +1635,8 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
16341635 # f. (x) ==> (dotcall f (error-t) x)
16351636 bump_disallowed_space (ps)
16361637 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 )
16391640 elseif k == K " :"
16401641 # A.:+ ==> (. A (quote-: +))
16411642 # A.: + ==> (. A (error-t) (quote-: +))
@@ -1697,20 +1698,20 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
16971698 # S {a} ==> (curly S (error-t) a)
16981699 bump_disallowed_space (ps)
16991700 bump (ps, TRIVIA_FLAG)
1700- parse_call_arglist (ps, K " }" )
1701+ opts = parse_call_arglist (ps, K " }" )
17011702 if is_macrocall
17021703 # @S{a,b} ==> (macrocall S (braces a b))
17031704 # A.@S{a} ==> (macrocall (. A @S) (braces a))
17041705 # @S{a}.b ==> (. (macrocall @S (braces a)) b)
17051706 fix_macro_name_kind! (ps, macro_name_position)
1706- emit (ps, m, K " braces" )
1707+ emit (ps, m, K " braces" , opts . delim_flags )
17071708 emit (ps, mark, K " macrocall" )
17081709 min_supported_version (v " 1.6" , ps, mark, " macro call without space before `{}`" )
17091710 is_macrocall = false
17101711 macro_atname_range = nothing
17111712 else
17121713 # S{a,b} ==> (curly S a b)
1713- emit (ps, mark, K " curly" )
1714+ emit (ps, mark, K " curly" , opts . delim_flags )
17141715 end
17151716 elseif k in KSet " \" \"\"\" ` ``` " &&
17161717 ! preceding_whitespace (t) && maybe_strmac &&
@@ -2151,7 +2152,7 @@ function parse_function_signature(ps::ParseState, is_function::Bool)
21512152 # function (f(x),) end ==> (function (tuple-p (call f x)) (block))
21522153 ambiguous_parens = opts. maybe_grouping_parens &&
21532154 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 )
21552156 if ambiguous_parens
21562157 # Got something like `(@f(x))`. Is it anon `(@f(x),)` or named sig `@f(x)` ??
21572158 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
27162717# surrounding brackets.
27172718#
27182719# flisp: parse-vect
2719- function parse_vect (ps:: ParseState , closer)
2720+ function parse_vect (ps:: ParseState , closer, prefix_trailing_comma )
27202721 # [x, y] ==> (vect x y)
27212722 # [x, y] ==> (vect x y)
27222723 # [x,y ; z] ==> (vect x y (parameters z))
27232724 # [x=1, y=2] ==> (vect (= x 1) (= y 2))
27242725 # [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
27272733 end
2728- return (K " vect" , EMPTY_FLAGS )
2734+ return (K " vect" , delim_flags )
27292735end
27302736
27312737# Parse generators
@@ -2988,7 +2994,7 @@ function parse_cat(ps::ParseState, closer, end_is_symbol)
29882994 mark = position (ps)
29892995 if k == closer
29902996 # [] ==> (vect)
2991- return parse_vect (ps, closer)
2997+ return parse_vect (ps, closer, false )
29922998 elseif k == K " ;"
29932999 # v1.8: [;] ==> (ncat-1)
29943000 # v1.8: [;;] ==> (ncat-2)
@@ -3003,14 +3009,15 @@ function parse_cat(ps::ParseState, closer, end_is_symbol)
30033009 parse_eq_star (ps)
30043010 k = peek (ps, skip_newlines= true )
30053011 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
30073014 # [x,] ==> (vect x)
30083015 bump (ps, TRIVIA_FLAG; skip_newlines = true )
30093016 end
30103017 # [x] ==> (vect x)
30113018 # [x \n ] ==> (vect x)
30123019 # [x ==> (vect x (error-t))
3013- parse_vect (ps, closer)
3020+ parse_vect (ps, closer, prefix_trailing_comma )
30143021 elseif k == K " for"
30153022 # [x for a in as] ==> (comprehension (generator x (iteration (in a as))))
30163023 # [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)
30873094 # (; a=1; b=2) ==> (tuple-p (parameters (= a 1)) (parameters (= b 2)))
30883095 # (a; b; c,d) ==> (tuple-p a (parameters b) (parameters c d))
30893096 # (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 )
30913098 elseif opts. is_block
30923099 # Blocks
30933100 # (;;) ==> (block-p)
@@ -3135,6 +3142,7 @@ function parse_brackets(after_parse::Function,
31353142 had_commas = false
31363143 had_splat = false
31373144 param_start = nothing
3145+ trailing_comma = false
31383146 while true
31393147 k = peek (ps)
31403148 if k == closing_kind
@@ -3150,11 +3158,13 @@ function parse_brackets(after_parse::Function,
31503158 bump (ps, TRIVIA_FLAG)
31513159 bump_trivia (ps)
31523160 elseif is_closing_token (ps, k)
3161+ trailing_comma = false
31533162 # Error; handled below in bump_closing_token
31543163 break
31553164 else
31563165 mark = position (ps)
31573166 parse_eq_star (ps)
3167+ trailing_comma = false
31583168 num_subexprs += 1
31593169 if num_subexprs == 1
31603170 had_splat = peek_behind (ps). kind == K " ..."
@@ -3172,6 +3182,7 @@ function parse_brackets(after_parse::Function,
31723182 if k == K " ,"
31733183 had_commas = true
31743184 bump (ps, TRIVIA_FLAG)
3185+ trailing_comma = true
31753186 elseif k == K " ;" || k == closing_kind
31763187 # Handled above
31773188 continue
@@ -3193,7 +3204,7 @@ function parse_brackets(after_parse::Function,
31933204 end
31943205 release_positions (ps. stream, params_positions)
31953206 bump_closing_token (ps, closing_kind, " or `,`" )
3196- return opts
3207+ return (; opts... , delim_flags = trailing_comma ? TRAILING_COMMA_FLAG : EMPTY_FLAGS)
31973208end
31983209
31993210_is_indentation (b:: UInt8 ) = (b == u8 " " || b == u8 "\t " )
@@ -3420,14 +3431,15 @@ end
34203431function emit_braces (ps, mark, ckind, cflags)
34213432 if ckind == K " hcat"
34223433 # {x y} ==> (bracescat (row x y))
3423- emit (ps, mark, K " row" , cflags)
3434+ emit (ps, mark, K " row" , cflags & ~ TRAILING_COMMA_FLAG )
34243435 elseif ckind == K " ncat"
34253436 # {x ;;; y} ==> (bracescat (nrow-3 x y))
3426- emit (ps, mark, K " nrow" , cflags)
3437+ emit (ps, mark, K " nrow" , cflags & ~ TRAILING_COMMA_FLAG )
34273438 end
34283439 check_ncat_compat (ps, mark, ckind)
34293440 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)
34313443end
34323444
34333445# parse numbers, identifiers, parenthesized expressions, lists, vectors, etc.
0 commit comments