@@ -315,8 +315,8 @@ function was_eventually_call(ps::ParseState)
315
315
b = peek_behind (stream, p)
316
316
if b. kind == K " call"
317
317
return true
318
- elseif b. kind == K " where" || ( b. kind == K ":: " &&
319
- has_flags (b. flags, INFIX_FLAG))
318
+ elseif b. kind == K " where" || b. kind == K "parens " ||
319
+ (b . kind == K " :: " && has_flags (b. flags, INFIX_FLAG))
320
320
p = first_child_position (ps, p)
321
321
else
322
322
return false
@@ -885,7 +885,7 @@ function parse_range(ps::ParseState)
885
885
if had_newline
886
886
# Error message for people coming from python
887
887
# 1:\n2 ==> (call-i 1 : (error))
888
- # (1:\n2) ==> (call-i 1 : 2)
888
+ # (1:\n2) ==> (parens ( call-i 1 : 2) )
889
889
emit_diagnostic (ps, whitespace= true ,
890
890
error= " line break after `:` in range expression" )
891
891
bump_invisible (ps, K " error" )
@@ -1021,7 +1021,7 @@ function parse_unary_subtype(ps::ParseState)
1021
1021
elseif k2 in KSet " { ("
1022
1022
# parse <:{T}(x::T) or <:(x::T) like other unary operators
1023
1023
# <:{T}(x::T) ==> (call (curly <: T) (:: x T))
1024
- # <:(x::T) ==> (<:-pre (:: x T))
1024
+ # <:(x::T) ==> (<:-pre (parens ( :: x T) ))
1025
1025
parse_where (ps, parse_juxtapose)
1026
1026
else
1027
1027
# <: x ==> (<:-pre x)
@@ -1108,9 +1108,9 @@ end
1108
1108
# Juxtoposition. Ugh! But so useful for units and Field identities like `im`
1109
1109
#
1110
1110
# 2x ==> (juxtapose 2 x)
1111
- # 2(x) ==> (juxtapose 2 x )
1112
- # (2)(3)x ==> (juxtapose 2 3 x)
1113
- # (x-1)y ==> (juxtapose (call-i x - 1) y)
1111
+ # 2(x) ==> (juxtapose 2 (parens x) )
1112
+ # (2)(3)x ==> (juxtapose (parens 2) (parens 3) x)
1113
+ # (x-1)y ==> (juxtapose (parens ( call-i x - 1) ) y)
1114
1114
# x'y ==> (juxtapose (call-post x ') y)
1115
1115
#
1116
1116
# flisp: parse-juxtapose
@@ -1239,9 +1239,9 @@ function parse_unary(ps::ParseState)
1239
1239
1240
1240
mark_before_paren = position (ps)
1241
1241
bump (ps, TRIVIA_FLAG) # (
1242
- initial_semi = peek (ps) == K " ; "
1242
+ _is_paren_call = peek (ps, skip_newlines = true ) in KSet " ; ) "
1243
1243
opts = parse_brackets (ps, K " )" ) do had_commas, had_splat, num_semis, num_subexprs
1244
- is_paren_call = had_commas || had_splat || initial_semi
1244
+ is_paren_call = had_commas || had_splat || _is_paren_call
1245
1245
return (needs_parameters= is_paren_call,
1246
1246
is_paren_call= is_paren_call,
1247
1247
is_block= ! is_paren_call && num_semis > 0 )
@@ -1263,6 +1263,7 @@ function parse_unary(ps::ParseState)
1263
1263
# +(a...) ==> (call + (... a))
1264
1264
# +(a;b,c) ==> (call + a (parameters b c))
1265
1265
# +(;a) ==> (call + (parameters a))
1266
+ # +() ==> (call +)
1266
1267
# Prefix calls have higher precedence than ^
1267
1268
# +(a,b)^2 ==> (call-i (call + a b) ^ 2)
1268
1269
# +(a,b)(x)^2 ==> (call-i (call (call + a b) x) ^ 2)
@@ -1292,21 +1293,23 @@ function parse_unary(ps::ParseState)
1292
1293
parse_factor_with_initial_ex (ps, mark)
1293
1294
else
1294
1295
# Unary function calls with brackets as grouping, not an arglist
1295
- # .+(a) ==> (dotcall-pre (. +) a )
1296
+ # .+(a) ==> (dotcall-pre (. +) (parens a) )
1296
1297
if opts. is_block
1297
1298
# +(a;b) ==> (call-pre + (block-p a b))
1298
1299
emit (ps, mark_before_paren, K " block" , PARENS_FLAG)
1300
+ else
1301
+ emit (ps, mark_before_paren, K " parens" )
1299
1302
end
1300
1303
# Not a prefix operator call but a block; `=` is not `kw`
1301
- # +(a=1) ==> (call-pre + (= a 1))
1304
+ # +(a=1) ==> (call-pre + (parens ( = a 1) ))
1302
1305
# Unary operators have lower precedence than ^
1303
- # +(a)^2 ==> (call-pre + (call-i a ^ 2))
1304
- # .+(a)^2 ==> (dotcall-pre + (call-i a ^ 2))
1305
- # +(a)(x,y)^2 ==> (call-pre + (call-i (call a x y) ^ 2))
1306
+ # +(a)^2 ==> (call-pre + (call-i (parens a) ^ 2))
1307
+ # .+(a)^2 ==> (dotcall-pre + (call-i (parens a) ^ 2))
1308
+ # +(a)(x,y)^2 ==> (call-pre + (call-i (call (parens a) x y) ^ 2))
1306
1309
parse_call_chain (ps, mark_before_paren)
1307
1310
parse_factor_with_initial_ex (ps, mark_before_paren)
1308
1311
if is_type_operator (op_t)
1309
- # <:(a) ==> (<:-pre a )
1312
+ # <:(a) ==> (<:-pre (parens a) )
1310
1313
emit (ps, mark, op_k, PREFIX_OP_FLAG)
1311
1314
reset_node! (ps, op_pos, flags= TRIVIA_FLAG)
1312
1315
else
@@ -1451,7 +1454,7 @@ function parse_identifier_or_interpolate(ps::ParseState)
1451
1454
mark = position (ps)
1452
1455
parse_unary_prefix (ps)
1453
1456
b = peek_behind (ps)
1454
- # export (x::T) ==> (export (error (::-i x T)))
1457
+ # export (x::T) ==> (export (error (parens ( ::-i x T) )))
1455
1458
# export outer ==> (export outer)
1456
1459
# export ($f) ==> (export ($ f))
1457
1460
ok = (b. is_leaf && (b. kind == K " Identifier" || is_operator (b. kind))) ||
@@ -1491,13 +1494,13 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1491
1494
k = kind (t)
1492
1495
if ! is_macrocall && ps. space_sensitive && preceding_whitespace (t) &&
1493
1496
k in KSet " ( [ { \" \"\"\" ` ```"
1494
- # [f (x)] ==> (hcat f x )
1497
+ # [f (x)] ==> (hcat f (parens x) )
1495
1498
# [f x] ==> (hcat f x)
1496
1499
break
1497
1500
elseif is_macrocall && (preceding_whitespace (t) || ! (k in KSet " ( [ { ' ." ))
1498
1501
# Macro calls with space-separated arguments
1499
1502
# @foo a b ==> (macrocall @foo a b)
1500
- # @foo (x) ==> (macrocall @foo x )
1503
+ # @foo (x) ==> (macrocall @foo (parens x) )
1501
1504
# @foo (x,y) ==> (macrocall @foo (tuple-p x y))
1502
1505
# [@foo x] ==> (vect (macrocall @foo x))
1503
1506
# [@foo] ==> (vect (macrocall @foo))
@@ -1537,8 +1540,8 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1537
1540
# f(a,b) ==> (call f a b)
1538
1541
# f(a=1; b=2) ==> (call f (= a 1) (parameters (= b 2)))
1539
1542
# f(a; b; c) ==> (call f a (parameters b) (parameters c))
1540
- # (a=1)() ==> (call (= a 1))
1541
- # f (a) ==> (call f (error-t) a b )
1543
+ # (a=1)() ==> (call (parens ( = a 1) ))
1544
+ # f (a) ==> (call f (error-t) a)
1542
1545
bump_disallowed_space (ps)
1543
1546
bump (ps, TRIVIA_FLAG)
1544
1547
parse_call_arglist (ps, K " )" )
@@ -1580,7 +1583,8 @@ function parse_call_chain(ps::ParseState, mark, is_macrocall=false)
1580
1583
else
1581
1584
# a[i] ==> (ref a i)
1582
1585
# a[i,j] ==> (ref a i j)
1583
- # (a=1)[] ==> (ref (= a 1))
1586
+ # (a=1)[] ==> (ref (parens (= a 1)))
1587
+ # a[end] ==> (ref a end)
1584
1588
# T[x y] ==> (typed_hcat T x y)
1585
1589
# T[x ; y] ==> (typed_vcat T x y)
1586
1590
# T[a b; c d] ==> (typed_vcat T (row a b) (row c d))
@@ -1905,7 +1909,7 @@ function parse_resword(ps::ParseState)
1905
1909
else
1906
1910
# Function/macro definition with no methods
1907
1911
# function f end ==> (function f)
1908
- # (function f \n end) ==> (function f)
1912
+ # (function f \n end) ==> (parens ( function f) )
1909
1913
# function f \n\n end ==> (function f)
1910
1914
# function $f end ==> (function ($ f))
1911
1915
# macro f end ==> (macro f)
@@ -2007,7 +2011,7 @@ function parse_resword(ps::ParseState)
2007
2011
# export a, \n @b ==> (export a @b)
2008
2012
# export +, == ==> (export + ==)
2009
2013
# export \n a ==> (export a)
2010
- # export \$a, \$(a*b) ==> (export (\$ a) (\$ (call-i a * b)))
2014
+ # export \$a, \$(a*b) ==> (export (\$ a) (\$ (parens ( call-i a * b) )))
2011
2015
bump (ps, TRIVIA_FLAG)
2012
2016
parse_comma_separated (ps, parse_atsym)
2013
2017
emit (ps, mark, K " export" )
@@ -2105,10 +2109,10 @@ function parse_function_signature(ps::ParseState, is_function::Bool)
2105
2109
emit (ps, mark, K " error" , error= " Invalid macro name" )
2106
2110
else
2107
2111
# macro f() end ==> (macro (call f) (block))
2108
- # macro (:)(ex) end ==> (macro (call : ex) (block))
2109
- # macro (type)(ex) end ==> (macro (call type ex) (block))
2112
+ # macro (:)(ex) end ==> (macro (call (parens :) ex) (block))
2113
+ # macro (type)(ex) end ==> (macro (call (parens type) ex) (block))
2110
2114
# macro $f() end ==> (macro (call ($ f)) (block))
2111
- # macro ($f)() end ==> (macro (call ($ f)) (block))
2115
+ # macro ($f)() end ==> (macro (call (parens ( $ f) )) (block))
2112
2116
end
2113
2117
else
2114
2118
if peek (ps) == K " ("
@@ -2145,10 +2149,11 @@ function parse_function_signature(ps::ParseState, is_function::Bool)
2145
2149
# function ()(x) end ==> (function (call (tuple-p) x) (block))
2146
2150
emit (ps, mark, K " tuple" , PARENS_FLAG)
2147
2151
else
2148
- # function (A).f() end ==> (function (call (. A (quote f))) (block))
2149
- # function (:)() end ==> (function (call :) (block))
2150
- # function (x::T)() end ==> (function (call (::-i x T)) (block))
2151
- # function (::T)() end ==> (function (call (::-pre T)) (block))
2152
+ # function (A).f() end ==> (function (call (. (parens A) (quote f))) (block))
2153
+ # function (:)() end ==> (function (call (parens :)) (block))
2154
+ # function (x::T)() end ==> (function (call (parens (::-i x T))) (block))
2155
+ # function (::T)() end ==> (function (call (parens (::-pre T))) (block))
2156
+ emit (ps, mark, K " parens" , PARENS_FLAG)
2152
2157
end
2153
2158
else
2154
2159
parse_unary_prefix (ps)
@@ -2163,8 +2168,7 @@ function parse_function_signature(ps::ParseState, is_function::Bool)
2163
2168
# function type() end ==> (function (call type) (block))
2164
2169
# function \n f() end ==> (function (call f) (block))
2165
2170
# function $f() end ==> (function (call ($ f)) (block))
2166
- # function (:)() end ==> (function (call :) (block))
2167
- # function (::Type{T})(x) end ==> (function (call (::-pre (curly Type T)) x) (block))
2171
+ # function (::Type{T})(x) end ==> (function (call (parens (::-pre (curly Type T))) x) (block))
2168
2172
end
2169
2173
end
2170
2174
end
@@ -2205,8 +2209,8 @@ function parse_function_signature(ps::ParseState, is_function::Bool)
2205
2209
# function (f() where T) end ==> (function (where (call f) T) (block))
2206
2210
# function (f()) where T end ==> (function (where (call f) T) (block))
2207
2211
# function (f() where T) where U end ==> (function (where (where (call f) T) U) (block))
2208
- # function (f()::S) end ==> (function (::-i (call f) S) (block))
2209
- # function ((f()::S) where T) end ==> (function (where (::-i (call f) S) T) (block))
2212
+ # function (f()::S) end ==> (function (parens ( ::-i (call f) S) ) (block))
2213
+ # function ((f()::S) where T) end ==> (function (where (parens ( ::-i (call f) S) ) T) (block))
2210
2214
#
2211
2215
# TODO : Warn for use of parens? The precedence of `::` and
2212
2216
# `where` don't work inside parens so this is a bit of a syntax
@@ -2401,7 +2405,7 @@ function parse_atsym(ps::ParseState)
2401
2405
else
2402
2406
# export a ==> (export a)
2403
2407
# export \n a ==> (export a)
2404
- # export $a, $(a*b) ==> (export ($ a) ($ (call * a b)))
2408
+ # export $a, $(a*b) ==> (export ($ a) (parens ( $ (call * a b) )))
2405
2409
parse_identifier_or_interpolate (ps)
2406
2410
end
2407
2411
end
@@ -2706,7 +2710,7 @@ end
2706
2710
function parse_generator (ps:: ParseState , mark, flatten= false )
2707
2711
t = peek_token (ps)
2708
2712
if ! preceding_whitespace (t)
2709
- # [(x)for x in xs] ==> (comprehension (generator x (error) (= x xs)))
2713
+ # [(x)for x in xs] ==> (comprehension (generator (parens x) (error) (= x xs)))
2710
2714
bump_invisible (ps, K " error" , TRIVIA_FLAG,
2711
2715
error= " Expected space before `for` in generator" )
2712
2716
end
@@ -2715,21 +2719,21 @@ function parse_generator(ps::ParseState, mark, flatten=false)
2715
2719
filter_mark = position (ps)
2716
2720
parse_comma_separated (ps, parse_iteration_spec)
2717
2721
if peek (ps) == K " if"
2718
- # (a for x in xs if cond) ==> (generator a (filter (= x xs) cond))
2722
+ # (a for x in xs if cond) ==> (parens ( generator a (filter (= x xs) cond) ))
2719
2723
bump (ps, TRIVIA_FLAG)
2720
2724
parse_cond (ps)
2721
2725
emit (ps, filter_mark, K " filter" )
2722
2726
end
2723
2727
t = peek_token (ps)
2724
2728
if kind (t) == K " for"
2725
- # (xy for x in xs for y in ys) ==> (flatten xy (= x xs) (= y ys))
2726
- # (xy for x in xs for y in ys for z in zs) ==> (flatten xy (= x xs) (= y ys) (= z zs))
2729
+ # (xy for x in xs for y in ys) ==> (parens ( flatten xy (= x xs) (= y ys) ))
2730
+ # (xy for x in xs for y in ys for z in zs) ==> (parens ( flatten xy (= x xs) (= y ys) (= z zs) ))
2727
2731
parse_generator (ps, mark, true )
2728
2732
if ! flatten
2729
2733
emit (ps, mark, K " flatten" )
2730
2734
end
2731
2735
elseif ! flatten
2732
- # (x for a in as) ==> (generator x (= a as))
2736
+ # (x for a in as) ==> (parens ( generator x (= a as) ))
2733
2737
emit (ps, mark, K " generator" )
2734
2738
end
2735
2739
end
@@ -3071,10 +3075,11 @@ function parse_paren(ps::ParseState, check_identifiers=true)
3071
3075
emit (ps, mark, K " block" , PARENS_FLAG)
3072
3076
else
3073
3077
# Parentheses used for grouping
3074
- # (a * b) ==> (call-i * a b)
3075
- # (a=1) ==> (= a 1)
3076
- # (x) ==> x
3077
- # (a...) ==> (... a)
3078
+ # (a * b) ==> (parens (call-i * a b))
3079
+ # (a=1) ==> (parens (= a 1))
3080
+ # (x) ==> (parens x)
3081
+ # (a...) ==> (parens (... a))
3082
+ emit (ps, mark, K " parens" )
3078
3083
end
3079
3084
end
3080
3085
end
@@ -3144,8 +3149,8 @@ function parse_brackets(after_parse::Function,
3144
3149
continue
3145
3150
elseif k == K " for"
3146
3151
# Generator syntax
3147
- # (x for a in as) ==> (generator x (= a as))
3148
- # (x \n\n for a in as) ==> (generator x (= a as))
3152
+ # (x for a in as) ==> (parens ( generator x (= a as) ))
3153
+ # (x \n\n for a in as) ==> (parens ( generator x (= a as) ))
3149
3154
parse_generator (ps, mark)
3150
3155
else
3151
3156
# Error - recovery done when consuming closing_kind
@@ -3203,8 +3208,8 @@ function parse_string(ps::ParseState, raw::Bool)
3203
3208
bump (ps, TRIVIA_FLAG)
3204
3209
k = peek (ps)
3205
3210
if k == K " ("
3206
- # "a $(x + y) b" ==> (string "a " (call-i x + y) " b")
3207
- # "hi$("ho")" ==> (string "hi" (string "ho"))
3211
+ # "a $(x + y) b" ==> (string "a " (parens ( call-i x + y) ) " b")
3212
+ # "hi$("ho")" ==> (string "hi" (parens ( string "ho") ))
3208
3213
parse_atom (ps)
3209
3214
elseif k == K " var"
3210
3215
# var identifiers disabled in strings
@@ -3346,7 +3351,7 @@ function parse_string(ps::ParseState, raw::Bool)
3346
3351
end
3347
3352
# String interpolations
3348
3353
# "$x$y$z" ==> (string x y z)
3349
- # "$(x)" ==> (string x )
3354
+ # "$(x)" ==> (string (parens x) )
3350
3355
# "$x" ==> (string x)
3351
3356
# """$x""" ==> (string-s x)
3352
3357
#
@@ -3440,7 +3445,7 @@ function parse_atom(ps::ParseState, check_identifiers=true)
3440
3445
# Being inside quote makes keywords into identifiers at the
3441
3446
# first level of nesting
3442
3447
# :end ==> (quote end)
3443
- # :(end) ==> (quote (error (end )))
3448
+ # :(end) ==> (quote (parens (error-t )))
3444
3449
# Being inside quote makes end non-special again (issue #27690)
3445
3450
# a[:(end)] ==> (ref a (quote (error-t end)))
3446
3451
parse_atom (ParseState (ps, end_symbol= false ), false )
0 commit comments