@@ -1165,16 +1165,21 @@ end
1165
1165
# Expand assignments
1166
1166
1167
1167
# 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 )
1169
1169
if numchildren (lhs) <= 1
1170
1170
throw (LoweringError (lhs, " empty type parameter list in type alias" ))
1171
1171
end
1172
1172
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
+ )
1178
1183
end
1179
1184
1180
1185
# Expand general assignment syntax, including
@@ -1184,13 +1189,13 @@ end
1184
1189
# * Assignments to array elements
1185
1190
# * Destructuring
1186
1191
# * Typed variable declarations
1187
- function expand_assignment (ctx, ex)
1192
+ function expand_assignment (ctx, ex, is_const = false )
1188
1193
@chk numchildren (ex) == 2
1189
1194
lhs = ex[1 ]
1190
1195
rhs = ex[2 ]
1191
1196
kl = kind (lhs)
1192
1197
if kl == K " curly"
1193
- expand_unionall_def (ctx, ex, lhs, rhs)
1198
+ expand_unionall_def (ctx, ex, lhs, rhs, is_const )
1194
1199
elseif kind (rhs) == K " ="
1195
1200
# Expand chains of assignments
1196
1201
# a = b = c ==> b=c; a=c
@@ -1207,7 +1212,9 @@ function expand_assignment(ctx, ex)
1207
1212
tmp_rhs = ssavar (ctx, rhs, " rhs" )
1208
1213
rr = tmp_rhs
1209
1214
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)
1211
1218
stmts[i] = @ast ctx ex [K " =" stmts[i] rr]
1212
1219
end
1213
1220
if ! isnothing (tmp_rhs)
@@ -1220,9 +1227,20 @@ function expand_assignment(ctx, ex)
1220
1227
]
1221
1228
)
1222
1229
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
1224
1241
elseif kl == K " ."
1225
1242
# a.b = rhs ==> setproperty!(a, :b, rhs)
1243
+ @chk ! is_const (ex, " cannot declare `.` form const" )
1226
1244
@chk numchildren (lhs) == 2
1227
1245
a = lhs[1 ]
1228
1246
b = lhs[2 ]
@@ -1250,16 +1268,24 @@ function expand_assignment(ctx, ex)
1250
1268
end
1251
1269
elseif kl == K " ref"
1252
1270
# a[i1, i2] = rhs
1271
+ @chk ! is_const (ex, " cannot declare ref form const" )
1253
1272
expand_forms_2 (ctx, expand_setindex (ctx, ex))
1254
1273
elseif kl == K " ::" && numchildren (lhs) == 2
1255
1274
x = lhs[1 ]
1256
1275
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)
1258
1284
# Identifer in lhs[1] is a variable type declaration, eg
1259
1285
# x::T = rhs
1260
1286
@ast ctx ex [K " block"
1261
1287
[K " decl" lhs[1 ] lhs[2 ]]
1262
- [K " =" lhs[1 ] rhs]
1288
+ is_const ? [ K " const " [ K " = " lhs[ 1 ] rhs]] : [K " =" lhs[1 ] rhs]
1263
1289
]
1264
1290
else
1265
1291
# Otherwise just a type assertion, eg
@@ -1271,6 +1297,7 @@ function expand_assignment(ctx, ex)
1271
1297
# needs to be detected somewhere but won't be detected here. Maybe
1272
1298
# it shows that remove_argument_side_effects() is not the ideal
1273
1299
# solution here?
1300
+ # TODO : handle underscore?
1274
1301
@ast ctx ex [K " block"
1275
1302
stmts...
1276
1303
[K " ::" l1 lhs[2 ]]
@@ -2097,9 +2124,8 @@ function strip_decls!(ctx, stmts, declkind, declkind2, declmeta, ex)
2097
2124
end
2098
2125
end
2099
2126
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?)
2103
2129
function expand_decls (ctx, ex)
2104
2130
declkind = kind (ex)
2105
2131
declmeta = get (ex, :meta , nothing )
@@ -2129,6 +2155,58 @@ function expand_decls(ctx, ex)
2129
2155
makenode (ctx, ex, K " block" , stmts)
2130
2156
end
2131
2157
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
+
2132
2210
# -------------------------------------------------------------------------------
2133
2211
# Expansion of function definitions
2134
2212
@@ -3318,14 +3396,13 @@ function expand_abstract_or_primitive_type(ctx, ex)
3318
3396
]
3319
3397
[K " assert" " toplevel_only" :: K"Symbol" [K " inert" ex] ]
3320
3398
[K " global" name]
3321
- [K " const" name]
3322
3399
[K " if"
3323
3400
[K " &&"
3324
3401
[K " isdefined" name]
3325
3402
[K " call" " _equiv_typedef" :: K"core" name newtype_var]
3326
3403
]
3327
3404
nothing_ (ctx, ex)
3328
- [K "= " name newtype_var]
3405
+ [K "constdecl " name newtype_var]
3329
3406
]
3330
3407
nothing_ (ctx, ex)
3331
3408
]
@@ -3827,9 +3904,10 @@ function expand_struct_def(ctx, ex, docs)
3827
3904
@ast ctx ex [K " block"
3828
3905
[K " assert" " toplevel_only" :: K"Symbol" [K " inert" ex] ]
3829
3906
[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]
3830
3909
[K " block"
3831
3910
[K " global" global_struct_name]
3832
- [K " const" global_struct_name]
3833
3911
[K " local" struct_name]
3834
3912
[K " always_defined" struct_name]
3835
3913
typevar_stmts...
@@ -3868,9 +3946,9 @@ function expand_struct_def(ctx, ex, docs)
3868
3946
end
3869
3947
]
3870
3948
# Otherwise do an assignment to trigger an error
3871
- [K "= " global_struct_name struct_name]
3949
+ [K "const " global_struct_name struct_name]
3872
3950
]
3873
- [K "= " global_struct_name struct_name]
3951
+ [K "const " global_struct_name struct_name]
3874
3952
]
3875
3953
[K " call" (type_body)
3876
3954
" _typebody!" :: K"core"
@@ -4271,7 +4349,9 @@ function expand_forms_2(ctx::DesugaringContext, ex::SyntaxTree, docs=nothing)
4271
4349
]
4272
4350
elseif k == K " let"
4273
4351
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"
4275
4355
if numchildren (ex) == 1 && kind (ex[1 ]) == K " Identifier"
4276
4356
# Don't recurse when already simplified - `local x`, etc
4277
4357
ex
0 commit comments