@@ -814,8 +814,7 @@ function expand_generator(ctx, ex)
814814 outervars_by_key = Dict {NameKey,typeof(ex)} ()
815815 for iterspecs in ex[2 : end - 1 ]
816816 for iterspec in children (iterspecs)
817- lhs = iterspec[1 ]
818- foreach_lhs_var (lhs) do var
817+ foreach_lhs_name (iterspec[1 ]) do var
819818 @assert kind (var) == K " Identifier" # Todo: K"BindingId"?
820819 outervars_by_key[NameKey (var)] = var
821820 end
@@ -1170,15 +1169,13 @@ function expand_unionall_def(ctx, srcref, lhs, rhs, is_const=true)
11701169 throw (LoweringError (lhs, " empty type parameter list in type alias" ))
11711170 end
11721171 name = lhs[1 ]
1173- rr = ssavar (ctx, srcref)
11741172 expand_forms_2 (
11751173 ctx,
1176- @ast ctx srcref [
1177- K " block"
1178- [K " =" rr [K " where" rhs lhs[2 : end ]. .. ]]
1179- [is_const ? K " constdecl" : K " assign_const_if_global" name rr]
1174+ @ast ctx srcref [K " block"
1175+ rr := [K " where" rhs lhs[2 : end ]. .. ]
1176+ [is_const ? K " constdecl" : K " assign_or_constdecl_if_global" name rr]
11801177 [K " latestworld_if_toplevel" ]
1181- rr
1178+ [ K " removable " rr]
11821179 ]
11831180 )
11841181end
@@ -1229,10 +1226,8 @@ function expand_assignment(ctx, ex, is_const=false)
12291226 )
12301227 elseif is_identifier_like (lhs)
12311228 if is_const
1232- rr = ssavar (ctx, rhs)
1233- @ast ctx ex [
1234- K " block"
1235- sink_assignment (ctx, ex, rr, expand_forms_2 (ctx, rhs))
1229+ @ast ctx ex [K " block"
1230+ rr := expand_forms_2 (ctx, rhs)
12361231 [K " constdecl" lhs rr]
12371232 [K " latestworld" ]
12381233 [K " removable" rr]
@@ -1276,11 +1271,10 @@ function expand_assignment(ctx, ex, is_const=false)
12761271 x = lhs[1 ]
12771272 T = lhs[2 ]
12781273 res = if is_const
1279- expand_forms_2 (ctx, @ast ctx ex [
1280- K " const"
1274+ expand_forms_2 (ctx, @ast ctx ex [K " const"
12811275 [K " ="
1282- lhs[1 ]
1283- convert_for_type_decl (ctx, ex, rhs, T, true )
1276+ lhs[1 ]
1277+ convert_for_type_decl (ctx, ex, rhs, T, true )
12841278 ]])
12851279 elseif is_identifier_like (x)
12861280 # Identifer in lhs[1] is a variable type declaration, eg
@@ -1467,7 +1461,7 @@ function expand_let(ctx, ex)
14671461 ]
14681462 elseif kind (lhs) == K " tuple"
14691463 lhs_locals = SyntaxList (ctx)
1470- foreach_lhs_var (lhs) do var
1464+ foreach_lhs_name (lhs) do var
14711465 push! (lhs_locals, @ast ctx var [K " local" var])
14721466 push! (lhs_locals, @ast ctx var [K " always_defined" var])
14731467 end
@@ -1904,23 +1898,6 @@ end
19041898# -------------------------------------------------------------------------------
19051899# Expand for loops
19061900
1907- # Extract the variable names assigned to from a "fancy assignment left hand
1908- # side" such as nested tuple destructuring.
1909- function foreach_lhs_var (f:: Function , ex)
1910- k = kind (ex)
1911- if k == K " Identifier" || k == K " BindingId"
1912- f (ex)
1913- elseif k == K " ::" && numchildren (ex) == 2
1914- foreach_lhs_var (f, ex[1 ])
1915- elseif k == K " tuple" || k == K " parameters"
1916- for e in children (ex)
1917- foreach_lhs_var (f, e)
1918- end
1919- end
1920- # k == K"Placeholder" ignored, along with everything else - we assume
1921- # validation is done elsewhere.
1922- end
1923-
19241901function expand_for (ctx, ex)
19251902 iterspecs = ex[1 ]
19261903
@@ -1936,7 +1913,7 @@ function expand_for(ctx, ex)
19361913 @chk kind (iterspec) == K " in"
19371914 lhs = iterspec[1 ]
19381915 if kind (lhs) != K " outer"
1939- foreach_lhs_var (lhs) do var
1916+ foreach_lhs_name (lhs) do var
19401917 push! (copied_vars, @ast ctx var [K " =" var var])
19411918 end
19421919 end
@@ -1953,7 +1930,7 @@ function expand_for(ctx, ex)
19531930 if outer
19541931 lhs = lhs[1 ]
19551932 end
1956- foreach_lhs_var (lhs) do var
1933+ foreach_lhs_name (lhs) do var
19571934 if outer
19581935 push! (lhs_outer_defs, @ast ctx var var)
19591936 else
@@ -2108,17 +2085,14 @@ end
21082085# (x::T, (y::U, z))
21092086# strip out stmts = (local x) (decl x T) (local x) (decl y U) (local z)
21102087# and return (x, (y, z))
2111- function strip_decls! (ctx, stmts, declkind, declkind2, declmeta, ex)
2088+ function strip_decls! (ctx, stmts, declkind, declmeta, ex)
21122089 k = kind (ex)
21132090 if k == K " Identifier"
21142091 if ! isnothing (declmeta)
21152092 push! (stmts, makenode (ctx, ex, declkind, ex; meta= declmeta))
21162093 else
21172094 push! (stmts, makenode (ctx, ex, declkind, ex))
21182095 end
2119- if ! isnothing (declkind2)
2120- push! (stmts, makenode (ctx, ex, declkind2, ex))
2121- end
21222096 ex
21232097 elseif k == K " Placeholder"
21242098 ex
@@ -2127,90 +2101,75 @@ function strip_decls!(ctx, stmts, declkind, declkind2, declmeta, ex)
21272101 name = ex[1 ]
21282102 @chk kind (name) == K " Identifier"
21292103 push! (stmts, makenode (ctx, ex, K " decl" , name, ex[2 ]))
2130- strip_decls! (ctx, stmts, declkind, declkind2, declmeta, ex[1 ])
2104+ strip_decls! (ctx, stmts, declkind, declmeta, ex[1 ])
21312105 elseif k == K " tuple" || k == K " parameters"
21322106 cs = SyntaxList (ctx)
21332107 for e in children (ex)
2134- push! (cs, strip_decls! (ctx, stmts, declkind, declkind2, declmeta, e))
2108+ push! (cs, strip_decls! (ctx, stmts, declkind, declmeta, e))
21352109 end
21362110 makenode (ctx, ex, k, cs)
2111+ else
2112+ throw (LoweringError (ex, " invalid kind $k in $declkind declaration" ))
21372113 end
21382114end
21392115
2116+ # Separate decls and assignments (which require re-expansion)
21402117# local x, (y=2), z ==> local x; local z; y = 2
2141- # Note there are differences from lisp (evaluation order?)
2142- function expand_decls (ctx, ex)
2118+ function expand_decls (ctx, ex, is_const= false )
21432119 declkind = kind (ex)
2120+ @assert declkind in KSet " local global"
21442121 declmeta = get (ex, :meta , nothing )
2145- if numchildren (ex) == 1 && kind (ex[1 ]) ∈ KSet " const global local"
2146- declkind2 = kind (ex[1 ])
2147- bindings = children (ex[1 ])
2148- else
2149- declkind2 = nothing
2150- bindings = children (ex)
2151- end
2122+ bindings = children (ex)
21522123 stmts = SyntaxList (ctx)
21532124 for binding in bindings
21542125 kb = kind (binding)
21552126 if is_prec_assignment (kb)
21562127 @chk numchildren (binding) == 2
2157- lhs = strip_decls! (ctx, stmts, declkind, declkind2, declmeta, binding[1 ])
2158- push! (stmts, @ast ctx binding [kb lhs binding[2 ]])
2159- elseif is_sym_decl (binding)
2160- if declkind == K " const" || declkind2 == K " const"
2161- throw (LoweringError (ex, " expected assignment after `const`" ))
2162- end
2163- strip_decls! (ctx, stmts, declkind, declkind2, declmeta, binding)
2128+ lhs = strip_decls! (ctx, stmts, declkind, declmeta, binding[1 ])
2129+ push! (stmts, expand_assignment (ctx, @ast ctx binding [kb lhs binding[2 ]]))
2130+ elseif is_sym_decl (binding) && ! is_const
2131+ strip_decls! (ctx, stmts, declkind, declmeta, binding)
21642132 else
21652133 throw (LoweringError (ex, " invalid syntax in variable declaration" ))
21662134 end
21672135 end
21682136 makenode (ctx, ex, K " block" , stmts)
21692137end
21702138
2171- # Return all the names that will be bound by the assignment LHS, including
2172- # curlies and calls.
2173- function lhs_bound_names ( ex)
2139+ # Iterate over the variable names assigned to from a "fancy assignment left hand
2140+ # side" such as nested tuple destructuring, curlies, and calls.
2141+ function foreach_lhs_name (f :: Function , ex)
21742142 k = kind (ex)
21752143 if k == K " Placeholder"
2176- []
2144+ # Ignored
21772145 elseif is_identifier_like (ex)
2178- [ex]
2179- elseif k in KSet " call curly where :: "
2180- lhs_bound_names ( ex[1 ])
2146+ f (ex)
2147+ elseif (k === K " :: " && numchildren (ex) === 2 ) || k in KSet " call curly where"
2148+ foreach_lhs_name (f, ex[1 ])
21812149 elseif k in KSet " tuple parameters"
2182- vcat ( map (lhs_bound_names, children (ex)) ... )
2183- else
2184- []
2150+ for c in children (ex)
2151+ foreach_lhs_name (f, c)
2152+ end
21852153 end
2154+ return nothing
21862155end
21872156
21882157function expand_const_decl (ctx, ex)
2189- function check_assignment (asgn)
2190- @chk (kind (asgn) == K " =" ) (ex, " expected assignment after `const`" )
2191- end
2192-
21932158 k = kind (ex[1 ])
2194- if numchildren (ex) == 2
2195- @ast ctx ex [
2196- K " constdecl"
2197- ex[1 ]
2198- expand_forms_2 (ctx, ex[2 ])
2199- ]
2200- elseif k == K " global"
2159+ if k == K " global"
22012160 asgn = ex[1 ][1 ]
2202- check_assignment (asgn)
2203- globals = map (lhs_bound_names (asgn[1 ])) do x
2204- @ast ctx ex [K " global" x]
2161+ @chk (kind (asgn) == K " =" ) (ex, " expected assignment after `const`" )
2162+ globals = SyntaxList (ctx)
2163+ foreach_lhs_name (asgn[1 ]) do x
2164+ push! (globals, @ast ctx ex [K " global" x])
22052165 end
2206- @ast ctx ex [
2207- K " block"
2166+ @ast ctx ex [K " block"
22082167 globals...
2209- expand_assignment (ctx, ex[ 1 ] , true )
2168+ expand_assignment (ctx, asgn , true )
22102169 ]
22112170 elseif k == K " ="
22122171 if numchildren (ex[1 ]) >= 1 && kind (ex[1 ][1 ]) == K " tuple"
2213- throw ( LoweringError ( ex[1 ][1 ], " unsupported `const` tuple" ) )
2172+ TODO ( ex[1 ][1 ], " `const` tuple assignment desugaring " )
22142173 end
22152174 expand_assignment (ctx, ex[1 ], true )
22162175 elseif k == K " local"
@@ -4403,8 +4362,11 @@ function expand_forms_2(ctx::DesugaringContext, ex::SyntaxTree, docs=nothing)
44034362 if numchildren (ex) == 1 && kind (ex[1 ]) == K " Identifier"
44044363 # Don't recurse when already simplified - `local x`, etc
44054364 ex
4365+ elseif k == K " global" && kind (ex[1 ]) == K " const"
4366+ # Normalize `global const` to `const global`
4367+ expand_const_decl (ctx, @ast ctx ex [K " const" [K " global" ex[1 ][1 ]]])
44064368 else
4407- expand_forms_2 (ctx, expand_decls (ctx, ex) )
4369+ expand_decls (ctx, ex)
44084370 end
44094371 elseif k == K " where"
44104372 expand_forms_2 (ctx, expand_wheres (ctx, ex))
0 commit comments