@@ -1165,16 +1165,21 @@ end
11651165# Expand assignments
11661166
11671167# Expand UnionAll definitions, eg `X{T} = Y{T,T}`
1168- function expand_unionall_def (ctx, srcref, lhs, rhs)
1168+ function expand_unionall_def (ctx, srcref, lhs, rhs, is_const = true )
11691169 if numchildren (lhs) <= 1
11701170 throw (LoweringError (lhs, " empty type parameter list in type alias" ))
11711171 end
11721172 name = lhs[1 ]
1173- @ast ctx srcref [K " block"
1174- [K " const_if_global" name]
1175- unionall_type := expand_forms_2 (ctx, [K " where" rhs lhs[2 : end ]. .. ])
1176- expand_forms_2 (ctx, [K " =" name unionall_type])
1177- ]
1173+ rr = ssavar (ctx, srcref)
1174+ expand_forms_2 (
1175+ 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]
1180+ rr
1181+ ]
1182+ )
11781183end
11791184
11801185# Expand general assignment syntax, including
@@ -1184,13 +1189,13 @@ end
11841189# * Assignments to array elements
11851190# * Destructuring
11861191# * Typed variable declarations
1187- function expand_assignment (ctx, ex)
1192+ function expand_assignment (ctx, ex, is_const = false )
11881193 @chk numchildren (ex) == 2
11891194 lhs = ex[1 ]
11901195 rhs = ex[2 ]
11911196 kl = kind (lhs)
11921197 if kl == K " curly"
1193- expand_unionall_def (ctx, ex, lhs, rhs)
1198+ expand_unionall_def (ctx, ex, lhs, rhs, is_const )
11941199 elseif kind (rhs) == K " ="
11951200 # Expand chains of assignments
11961201 # a = b = c ==> b=c; a=c
@@ -1207,7 +1212,9 @@ function expand_assignment(ctx, ex)
12071212 tmp_rhs = ssavar (ctx, rhs, " rhs" )
12081213 rr = tmp_rhs
12091214 end
1210- for i in 1 : length (stmts)
1215+ # In const a = b = c, only a is const
1216+ stmts[1 ] = @ast ctx ex [(is_const ? K " constdecl" : K " =" ) stmts[1 ] rr]
1217+ for i in 2 : length (stmts)
12111218 stmts[i] = @ast ctx ex [K " =" stmts[i] rr]
12121219 end
12131220 if ! isnothing (tmp_rhs)
@@ -1220,9 +1227,20 @@ function expand_assignment(ctx, ex)
12201227 ]
12211228 )
12221229 elseif is_identifier_like (lhs)
1223- sink_assignment (ctx, ex, lhs, expand_forms_2 (ctx, rhs))
1230+ if is_const
1231+ rr = ssavar (ctx, rhs)
1232+ @ast ctx ex [
1233+ K " block"
1234+ sink_assignment (ctx, ex, rr, expand_forms_2 (ctx, rhs))
1235+ [K " constdecl" lhs rr]
1236+ [K " removable" rr]
1237+ ]
1238+ else
1239+ sink_assignment (ctx, ex, lhs, expand_forms_2 (ctx, rhs))
1240+ end
12241241 elseif kl == K " ."
12251242 # a.b = rhs ==> setproperty!(a, :b, rhs)
1243+ @chk ! is_const (ex, " cannot declare `.` form const" )
12261244 @chk numchildren (lhs) == 2
12271245 a = lhs[1 ]
12281246 b = lhs[2 ]
@@ -1250,16 +1268,24 @@ function expand_assignment(ctx, ex)
12501268 end
12511269 elseif kl == K " ref"
12521270 # a[i1, i2] = rhs
1271+ @chk ! is_const (ex, " cannot declare ref form const" )
12531272 expand_forms_2 (ctx, expand_setindex (ctx, ex))
12541273 elseif kl == K " ::" && numchildren (lhs) == 2
12551274 x = lhs[1 ]
12561275 T = lhs[2 ]
1257- res = if is_identifier_like (x)
1276+ res = if is_const
1277+ expand_forms_2 (ctx, @ast ctx ex [
1278+ K " const"
1279+ [K " ="
1280+ lhs[1 ]
1281+ convert_for_type_decl (ctx, ex, rhs, T, true )
1282+ ]])
1283+ elseif is_identifier_like (x)
12581284 # Identifer in lhs[1] is a variable type declaration, eg
12591285 # x::T = rhs
12601286 @ast ctx ex [K " block"
12611287 [K " decl" lhs[1 ] lhs[2 ]]
1262- [K " =" lhs[1 ] rhs]
1288+ is_const ? [ K " const " [ K " = " lhs[ 1 ] rhs]] : [K " =" lhs[1 ] rhs]
12631289 ]
12641290 else
12651291 # Otherwise just a type assertion, eg
@@ -1271,6 +1297,7 @@ function expand_assignment(ctx, ex)
12711297 # needs to be detected somewhere but won't be detected here. Maybe
12721298 # it shows that remove_argument_side_effects() is not the ideal
12731299 # solution here?
1300+ # TODO : handle underscore?
12741301 @ast ctx ex [K " block"
12751302 stmts...
12761303 [K " ::" l1 lhs[2 ]]
@@ -2097,9 +2124,8 @@ function strip_decls!(ctx, stmts, declkind, declkind2, declmeta, ex)
20972124 end
20982125end
20992126
2100- # local x, (y=2), z ==> local x; local y; y = 2; local z
2101- # const x = 1 ==> const x; x = 1
2102- # global x::T = 1 ==> (block (global x) (decl x T) (x = 1))
2127+ # local x, (y=2), z ==> local x; local z; y = 2
2128+ # Note there are differences from lisp (evaluation order?)
21032129function expand_decls (ctx, ex)
21042130 declkind = kind (ex)
21052131 declmeta = get (ex, :meta , nothing )
@@ -2129,6 +2155,58 @@ function expand_decls(ctx, ex)
21292155 makenode (ctx, ex, K " block" , stmts)
21302156end
21312157
2158+ # Return all the names that will be bound by the assignment LHS, including
2159+ # curlies and calls.
2160+ function lhs_bound_names (ex)
2161+ k = kind (ex)
2162+ if k == K " Placeholder"
2163+ []
2164+ elseif is_identifier_like (ex)
2165+ [ex]
2166+ elseif k in KSet " call curly where ::"
2167+ lhs_bound_names (ex[1 ])
2168+ elseif k in KSet " tuple parameters"
2169+ vcat (map (lhs_bound_names, children (ex))... )
2170+ else
2171+ []
2172+ end
2173+ end
2174+
2175+ function expand_const_decl (ctx, ex)
2176+ function check_assignment (asgn)
2177+ @chk (kind (asgn) == K " =" ) (ex, " expected assignment after `const`" )
2178+ end
2179+
2180+ k = kind (ex[1 ])
2181+ if numchildren (ex) == 2
2182+ @ast ctx ex [
2183+ K " constdecl"
2184+ ex[1 ]
2185+ expand_forms_2 (ctx, ex[2 ])
2186+ ]
2187+ elseif k == K " global"
2188+ asgn = ex[1 ][1 ]
2189+ check_assignment (asgn)
2190+ globals = map (lhs_bound_names (asgn[1 ])) do x
2191+ @ast ctx ex [K " global" x]
2192+ end
2193+ @ast ctx ex [
2194+ K " block"
2195+ globals...
2196+ expand_assignment (ctx, ex[1 ], true )
2197+ ]
2198+ elseif k == K " ="
2199+ if numchildren (ex[1 ]) >= 1 && kind (ex[1 ][1 ]) == K " tuple"
2200+ throw (LoweringError (ex[1 ][1 ], " unsupported `const` tuple" ))
2201+ end
2202+ expand_assignment (ctx, ex[1 ], true )
2203+ elseif k == K " local"
2204+ throw (LoweringError (ex, " unsupported `const local` declaration" ))
2205+ else
2206+ throw (LoweringError (ex, " expected assignment after `const`" ))
2207+ end
2208+ end
2209+
21322210# -------------------------------------------------------------------------------
21332211# Expansion of function definitions
21342212
@@ -3318,14 +3396,13 @@ function expand_abstract_or_primitive_type(ctx, ex)
33183396 ]
33193397 [K " assert" " toplevel_only" :: K"Symbol" [K " inert" ex] ]
33203398 [K " global" name]
3321- [K " const" name]
33223399 [K " if"
33233400 [K " &&"
33243401 [K " isdefined" name]
33253402 [K " call" " _equiv_typedef" :: K"core" name newtype_var]
33263403 ]
33273404 nothing_ (ctx, ex)
3328- [K "= " name newtype_var]
3405+ [K "constdecl " name newtype_var]
33293406 ]
33303407 nothing_ (ctx, ex)
33313408 ]
@@ -3827,9 +3904,10 @@ function expand_struct_def(ctx, ex, docs)
38273904 @ast ctx ex [K " block"
38283905 [K " assert" " toplevel_only" :: K"Symbol" [K " inert" ex] ]
38293906 [K " scope_block" (scope_type= :hard )
3907+ # Needed for later constdecl to work, though plain global form may be removed soon.
3908+ [K " global" global_struct_name]
38303909 [K " block"
38313910 [K " global" global_struct_name]
3832- [K " const" global_struct_name]
38333911 [K " local" struct_name]
38343912 [K " always_defined" struct_name]
38353913 typevar_stmts...
@@ -3868,9 +3946,9 @@ function expand_struct_def(ctx, ex, docs)
38683946 end
38693947 ]
38703948 # Otherwise do an assignment to trigger an error
3871- [K "= " global_struct_name struct_name]
3949+ [K "const " global_struct_name struct_name]
38723950 ]
3873- [K "= " global_struct_name struct_name]
3951+ [K "const " global_struct_name struct_name]
38743952 ]
38753953 [K " call" (type_body)
38763954 " _typebody!" :: K"core"
@@ -4271,7 +4349,9 @@ function expand_forms_2(ctx::DesugaringContext, ex::SyntaxTree, docs=nothing)
42714349 ]
42724350 elseif k == K " let"
42734351 expand_forms_2 (ctx, expand_let (ctx, ex))
4274- elseif k == K " local" || k == K " global" || k == K " const"
4352+ elseif k == K " const"
4353+ expand_const_decl (ctx, ex)
4354+ elseif k == K " local" || k == K " global"
42754355 if numchildren (ex) == 1 && kind (ex[1 ]) == K " Identifier"
42764356 # Don't recurse when already simplified - `local x`, etc
42774357 ex
0 commit comments