@@ -934,8 +934,8 @@ function operator_associativity(s::Symbol)
934934 return :left
935935end
936936
937- is_expr (ex , head:: Symbol ) = ( isa (ex, Expr) && (ex. head == head) )
938- is_expr (ex , head:: Symbol , n:: Int ) = is_expr (ex, head) && length (ex. args) == n
937+ is_expr (@nospecialize (ex) , head:: Symbol ) = isa (ex, Expr) && (ex. head === head)
938+ is_expr (@nospecialize (ex) , head:: Symbol , n:: Int ) = is_expr (ex, head) && length (ex. args) == n
939939
940940is_quoted (ex) = false
941941is_quoted (ex:: QuoteNode ) = true
@@ -991,7 +991,8 @@ function show_block(io::IO, head, arg, block, i::Int, quote_level::Int)
991991end
992992
993993# show an indented list
994- function show_list (io:: IO , items, sep, indent:: Int , prec:: Int = 0 , quote_level:: Int = 0 , enclose_operators:: Bool = false )
994+ function show_list (io:: IO , items, sep, indent:: Int , prec:: Int = 0 , quote_level:: Int = 0 , enclose_operators:: Bool = false ,
995+ kw:: Bool = false )
995996 n = length (items)
996997 n == 0 && return
997998 indent += indent_width
@@ -1004,20 +1005,27 @@ function show_list(io::IO, items, sep, indent::Int, prec::Int=0, quote_level::In
10041005 (item isa Real && item < 0 ))) ||
10051006 (enclose_operators && item isa Symbol && isoperator (item))
10061007 parens && print (io, ' (' )
1007- show_unquoted (io, item, indent, parens ? 0 : prec, quote_level)
1008+ if kw && is_expr (item, :kw , 2 )
1009+ show_unquoted (io, Expr (:(= ), item. args[1 ], item. args[2 ]), indent, parens ? 0 : prec, quote_level)
1010+ elseif kw && is_expr (item, :(= ), 2 )
1011+ show_unquoted_expr_fallback (io, item, indent, quote_level)
1012+ else
1013+ show_unquoted (io, item, indent, parens ? 0 : prec, quote_level)
1014+ end
10081015 parens && print (io, ' )' )
10091016 first = false
10101017 end
10111018end
10121019# show an indented list inside the parens (op, cl)
1013- function show_enclosed_list (io:: IO , op, items, sep, cl, indent, prec= 0 , quote_level= 0 , encl_ops= false )
1020+ function show_enclosed_list (io:: IO , op, items, sep, cl, indent, prec= 0 , quote_level= 0 , encl_ops= false , kw :: Bool = false )
10141021 print (io, op)
1015- show_list (io, items, sep, indent, prec, quote_level, encl_ops)
1022+ show_list (io, items, sep, indent, prec, quote_level, encl_ops, kw )
10161023 print (io, cl)
10171024end
10181025
10191026# show a normal (non-operator) function call, e.g. f(x, y) or A[z]
1020- function show_call (io:: IO , head, func, func_args, indent, quote_level)
1027+ # kw: `=` expressions are parsed with head `kw` in this context
1028+ function show_call (io:: IO , head, func, func_args, indent, quote_level, kw:: Bool )
10211029 op, cl = expr_calls[head]
10221030 if (isa (func, Symbol) && func != = :(:) && ! (head === :. && isoperator (func))) ||
10231031 (isa (func, Expr) && (func. head === :. || func. head === :curly || func. head === :macroname )) ||
@@ -1033,12 +1041,12 @@ function show_call(io::IO, head, func, func_args, indent, quote_level)
10331041 end
10341042 if ! isempty (func_args) && isa (func_args[1 ], Expr) && func_args[1 ]. head === :parameters
10351043 print (io, op)
1036- show_list (io, func_args[2 : end ], " , " , indent, 0 , quote_level)
1044+ show_list (io, func_args[2 : end ], " , " , indent, 0 , quote_level, false , kw )
10371045 print (io, " ; " )
1038- show_list (io, func_args[1 ]. args, " , " , indent, 0 , quote_level)
1046+ show_list (io, func_args[1 ]. args, " , " , indent, 0 , quote_level, false , kw )
10391047 print (io, cl)
10401048 else
1041- show_enclosed_list (io, op, func_args, " , " , cl, indent, 0 , quote_level)
1049+ show_enclosed_list (io, op, func_args, " , " , cl, indent, 0 , quote_level, false , kw )
10421050 end
10431051end
10441052
@@ -1147,7 +1155,7 @@ function show_generator(io, ex, indent, quote_level)
11471155end
11481156
11491157function valid_import_path (@nospecialize ex)
1150- return Meta . isexpr (ex, :(.)) && length ((ex:: Expr ). args) > 0 && all (a-> isa (a,Symbol), (ex:: Expr ). args)
1158+ return is_expr (ex, :(.)) && length ((ex:: Expr ). args) > 0 && all (a-> isa (a,Symbol), (ex:: Expr ). args)
11511159end
11521160
11531161function show_import_path (io:: IO , ex, quote_level)
@@ -1194,6 +1202,22 @@ end
11941202# as an ordinary symbol, which is true in indexing expressions.
11951203const beginsym = gensym (:beginsym )
11961204
1205+ function show_unquoted_expr_fallback (io:: IO , ex:: Expr , indent:: Int , quote_level:: Int )
1206+ print (io, " \$ (Expr(" )
1207+ show (io, ex. head)
1208+ for arg in ex. args
1209+ print (io, " , " )
1210+ if isa (arg, Expr)
1211+ print (io, " :(" )
1212+ show_unquoted (io, arg, indent, 0 , quote_level+ 1 )
1213+ print (io, " )" )
1214+ else
1215+ show (io, arg)
1216+ end
1217+ end
1218+ print (io, " ))" )
1219+ end
1220+
11971221# TODO : implement interpolated strings
11981222function show_unquoted (io:: IO , ex:: Expr , indent:: Int , prec:: Int , quote_level:: Int = 0 )
11991223 head, args, nargs = ex. head, ex. args, length (ex. args)
@@ -1204,7 +1228,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
12041228 item = args[1 ]
12051229 # field
12061230 field = unquoted (args[2 ])
1207- parens = ! is_quoted (item) && ! (item isa Symbol && isidentifier (item)) && ! Meta . isexpr (item, :(.))
1231+ parens = ! is_quoted (item) && ! (item isa Symbol && isidentifier (item)) && ! is_expr (item, :(.))
12081232 parens && print (io, ' (' )
12091233 show_unquoted (io, item, indent, 0 , quote_level)
12101234 parens && print (io, ' )' )
@@ -1231,8 +1255,27 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
12311255 show_list (io, args, head_, indent, func_prec, quote_level, true )
12321256 end
12331257
1234- # list (i.e. "(1, 2, 3)" or "[1, 2, 3]")
1235- elseif haskey (expr_parens, head) || # :tuple/:vcat
1258+ elseif head === :tuple
1259+ print (io, " (" )
1260+ if nargs > 0 && is_expr (args[1 ], :parameters )
1261+ if nargs == 1 && isempty (args[1 ]. args)
1262+ # TODO : for now avoid printing (;)
1263+ show_unquoted_expr_fallback (io, args[1 ], indent, quote_level)
1264+ print (io, ' ,' )
1265+ else
1266+ show_list (io, args[2 : end ], " , " , indent, 0 , quote_level)
1267+ nargs == 2 && print (io, ' ,' )
1268+ print (io, " ; " )
1269+ show_list (io, args[1 ]. args, " , " , indent, 0 , quote_level, false , true )
1270+ end
1271+ else
1272+ show_list (io, args, " , " , indent, 0 , quote_level)
1273+ nargs == 1 && print (io, ' ,' )
1274+ end
1275+ print (io, " )" )
1276+
1277+ # list-like forms, e.g. "[1, 2, 3]"
1278+ elseif haskey (expr_parens, head) || # :vcat etc.
12361279 head === :typed_vcat || head === :typed_hcat
12371280 # print the type and defer to the untyped case
12381281 if head === :typed_vcat || head === :typed_hcat
@@ -1255,12 +1298,8 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
12551298 end
12561299 head != = :row && print (io, op)
12571300 show_list (io, args, sep, indent, 0 , quote_level)
1258- if nargs == 1
1259- if head === :tuple
1260- print (io, ' ,' )
1261- elseif head === :vcat
1262- print (io, ' ;' )
1263- end
1301+ if nargs == 1 && head === :vcat
1302+ print (io, ' ;' )
12641303 end
12651304 head != = :row && print (io, cl)
12661305
@@ -1274,8 +1313,12 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
12741313 end
12751314 func_args = args[2 : end ]
12761315
1316+ # :kw exprs are only parsed inside parenthesized calls
1317+ if any (a-> is_expr (a, :kw ), func_args)
1318+ show_call (io, head, func, func_args, indent, quote_level, true )
1319+
12771320 # scalar multiplication (i.e. "100x")
1278- if (func === :* &&
1321+ elseif (func === :* &&
12791322 length (func_args)== 2 && isa (func_args[1 ], Real) && isa (func_args[2 ], Symbol))
12801323 if func_prec <= prec
12811324 show_enclosed_list (io, ' (' , func_args, " " , ' )' , indent, func_prec, quote_level)
@@ -1313,12 +1356,12 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
13131356 print (io, " )" )
13141357 show_enclosed_list (io, op, func_args, " , " , cl, indent, 0 , quote_level)
13151358 else
1316- show_call (io, head, func, func_args, indent, quote_level)
1359+ show_call (io, head, func, func_args, indent, quote_level, true )
13171360 end
13181361
13191362 # normal function (i.e. "f(x,y)")
13201363 else
1321- show_call (io, head, func, func_args, indent, quote_level)
1364+ show_call (io, head, func, func_args, indent, quote_level, true )
13221365 end
13231366
13241367 # new expr
@@ -1328,7 +1371,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
13281371 # other call-like expressions ("A[1,2]", "T{X,Y}", "f.(X,Y)")
13291372 elseif haskey (expr_calls, head) && nargs >= 1 # :ref/:curly/:calldecl/:(.)
13301373 funcargslike = head === :(.) ? args[2 ]. args : args[2 : end ]
1331- show_call (head == :ref ? IOContext (io, beginsym=> true ) : io, head, args[1 ], funcargslike, indent, quote_level)
1374+ show_call (head == :ref ? IOContext (io, beginsym=> true ) : io, head, args[1 ], funcargslike, indent, quote_level, head != = :curly )
13321375
13331376 # comprehensions
13341377 elseif head === :typed_comprehension && nargs == 2
@@ -1386,7 +1429,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
13861429
13871430 # block with argument
13881431 elseif head in (:for ,:while ,:function ,:macro ,:if ,:elseif ,:let ) && nargs== 2
1389- if Meta . isexpr (args[2 ], :block )
1432+ if is_expr (args[2 ], :block )
13901433 show_block (IOContext (io, beginsym=> false ), head, args[1 ], args[2 ], indent, quote_level)
13911434 else
13921435 show_block (IOContext (io, beginsym=> false ), head, args[1 ], Expr (:block , args[2 ]), indent, quote_level)
@@ -1478,7 +1521,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
14781521 # prec=-1 and hide the line number argument from the argument list
14791522 mname = allow_macroname (args[1 ])
14801523 if prec >= 0
1481- show_call (io, :call , mname, args[3 : end ], indent, quote_level)
1524+ show_call (io, :call , mname, args[3 : end ], indent, quote_level, false )
14821525 else
14831526 show_args = Vector {Any} (undef, nargs - 1 )
14841527 show_args[1 ] = mname
@@ -1552,7 +1595,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
15521595
15531596 elseif head === :quote && nargs == 1 && isa (args[1 ], Symbol)
15541597 show_unquoted_quote_expr (IOContext (io, beginsym=> false ), args[1 ]:: Symbol , indent, 0 , quote_level+ 1 )
1555- elseif head === :quote && nargs == 1 && Meta . isexpr (args[1 ], :block )
1598+ elseif head === :quote && nargs == 1 && is_expr (args[1 ], :block )
15561599 show_block (IOContext (io, beginsym=> false ), " quote" , Expr (:quote , args[1 ]. args... ), indent,
15571600 quote_level+ 1 )
15581601 print (io, " end" )
@@ -1576,11 +1619,6 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
15761619 elseif head === :null
15771620 print (io, " nothing" )
15781621
1579- elseif head === :kw && nargs == 2
1580- show_unquoted (io, args[1 ], indent+ indent_width, 0 , quote_level)
1581- print (io, ' =' )
1582- show_unquoted (io, args[2 ], indent+ indent_width, 0 , quote_level)
1583-
15841622 elseif head === :string
15851623 print (io, ' "' )
15861624 for x in args
@@ -1642,7 +1680,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
16421680
16431681 elseif (head === :import || head === :using ) &&
16441682 ((nargs == 1 && (valid_import_path (args[1 ]) ||
1645- (Meta . isexpr (args[1 ], :(:)) &&
1683+ (is_expr (args[1 ], :(:)) &&
16461684 length ((args[1 ]:: Expr ). args) > 1 &&
16471685 all (valid_import_path, (args[1 ]:: Expr ). args)))) ||
16481686 all (valid_import_path, args))
@@ -1667,19 +1705,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In
16671705 unhandled = true
16681706 end
16691707 if unhandled
1670- print (io, " \$ (Expr(" )
1671- show (io, ex. head)
1672- for arg in args
1673- print (io, " , " )
1674- if isa (arg, Expr)
1675- print (io, " :(" )
1676- show_unquoted (io, arg, indent, 0 , quote_level+ 1 )
1677- print (io, " )" )
1678- else
1679- show (io, arg)
1680- end
1681- end
1682- print (io, " ))" )
1708+ show_unquoted_expr_fallback (io, ex, indent, quote_level)
16831709 end
16841710 nothing
16851711end
0 commit comments