@@ -1207,6 +1207,13 @@ def expr_variable(tree, location, scope):
1207
1207
if in_dev_tree :
1208
1208
e = in_dev_tree
1209
1209
if e is None :
1210
+ # TODO/HACK: The discard ref is exposed like this to allow it to be as
1211
+ # keyword-like as possible while still allowing it to be shadowed.
1212
+ # Once we remove support for discard_ref_shadowing the discard ref
1213
+ # should become a proper keyword and its codegen be done via dedicated
1214
+ # dispatch
1215
+ if name == '_' and tree .site .dml_version () != (1 , 2 ):
1216
+ return mkDiscardRef (tree .site )
1210
1217
raise EIDENT (tree .site , name )
1211
1218
return e
1212
1219
@@ -2341,14 +2348,25 @@ def try_codegen_invocation(site, init_ast, outargs, location, scope):
2341
2348
else :
2342
2349
return common_inline (site , meth_node , indices , inargs , outargs )
2343
2350
2351
+ def codegen_src_for_nonvalue_target (site , tgt , src_ast , location , scope ):
2352
+ if not tgt .writable :
2353
+ raise EASSIGN (site , tgt )
2354
+ if src_ast .kind != 'initializer_scalar' :
2355
+ raise EDATAINIT (tgt .site ,
2356
+ f'{ tgt } can only be used as the target '
2357
+ + 'of an assignment if its initializer is a '
2358
+ + 'simple expression or a return value of a '
2359
+ + 'method call' )
2360
+ return codegen_expression (src_ast .args [0 ], location , scope )
2361
+
2344
2362
@statement_dispatcher
2345
2363
def stmt_assign (stmt , location , scope ):
2346
2364
(_ , site , tgt_ast , src_asts ) = stmt
2347
2365
assert tgt_ast .kind in ('assign_target_chain' , 'assign_target_tuple' )
2348
- tgts = [codegen_expression (ast , location , scope )
2366
+ tgts = [codegen_expression_maybe_nonvalue (ast , location , scope )
2349
2367
for ast in tgt_ast .args [0 ]]
2350
2368
for tgt in tgts :
2351
- if deep_const (tgt .ctype ()):
2369
+ if not isinstance ( tgt , NonValue ) and deep_const (tgt .ctype ()):
2352
2370
raise ECONST (tgt .site )
2353
2371
if tgt_ast .kind == 'assign_target_chain' :
2354
2372
method_tgts = [tgts [0 ]]
@@ -2370,14 +2388,21 @@ def stmt_assign(stmt, location, scope):
2370
2388
+ f'initializer: Expected { src_asts } , got 1' ))
2371
2389
return []
2372
2390
2373
- lscope = Symtab (scope )
2391
+ if isinstance (tgts [- 1 ], NonValue ):
2392
+ if len (tgts ) != 1 :
2393
+ raise tgts [- 1 ].exc ()
2394
+ expr = codegen_src_for_nonvalue_target (site , tgts [0 ], src_asts [0 ],
2395
+ location , scope )
2396
+ return [mkCopyData (site , expr , tgts [0 ])]
2397
+
2374
2398
init_typ = tgts [- 1 ].ctype ()
2375
2399
init = eval_initializer (
2376
2400
tgts [- 1 ].site , init_typ , src_asts [0 ], location , scope , False )
2377
2401
2378
2402
if len (tgts ) == 1 :
2379
2403
return [mkAssignStatement (tgts [0 ].site , tgts [0 ], init )]
2380
2404
2405
+ lscope = Symtab (scope )
2381
2406
sym = lscope .add_variable (
2382
2407
'tmp' , type = init_typ , site = init .site , init = init ,
2383
2408
stmt = True )
@@ -2406,22 +2431,27 @@ def stmt_assign(stmt, location, scope):
2406
2431
2407
2432
stmts = []
2408
2433
lscope = Symtab (scope )
2409
- syms = []
2434
+ stmt_pairs = []
2410
2435
for (i , (tgt , src_ast )) in enumerate (zip (tgts , src_asts )):
2411
- init = eval_initializer (site , tgt .ctype (), src_ast , location ,
2412
- scope , False )
2413
- name = 'tmp%d' % (i ,)
2414
- sym = lscope .add_variable (
2415
- name , type = tgt .ctype (), site = tgt .site , init = init ,
2416
- stmt = True )
2417
- syms .append (sym )
2418
-
2419
- stmts .extend (sym_declaration (sym ) for sym in syms )
2420
- stmts .extend (
2421
- AssignStatement (
2422
- tgt .site , tgt ,
2423
- ExpressionInitializer (mkLocalVariable (tgt .site , sym )))
2424
- for (tgt , sym ) in zip (tgts , syms ))
2436
+ if isinstance (tgt , NonValue ):
2437
+ expr = codegen_src_for_nonvalue_target (site , tgt , src_ast ,
2438
+ location , scope )
2439
+ stmt_pairs .append ((mkCopyData (tgt .site , expr , tgt ), None ))
2440
+ else :
2441
+ init = eval_initializer (site , tgt .ctype (), src_ast , location ,
2442
+ scope , False )
2443
+ name = 'tmp%d' % (i ,)
2444
+ sym = lscope .add_variable (
2445
+ name , type = tgt .ctype (), site = tgt .site , init = init ,
2446
+ stmt = True )
2447
+ write = AssignStatement (
2448
+ tgt .site , tgt ,
2449
+ ExpressionInitializer (mkLocalVariable (tgt .site , sym )))
2450
+ stmt_pairs .append ((sym_declaration (sym ), write ))
2451
+
2452
+ stmts .extend (first for (first , _ ) in stmt_pairs )
2453
+ stmts .extend (second for (_ , second ) in stmt_pairs
2454
+ if second is not None )
2425
2455
return [mkCompound (site , stmts )]
2426
2456
2427
2457
@statement_dispatcher
@@ -3616,7 +3646,7 @@ def codegen_inline(site, meth_node, indices, inargs, outargs,
3616
3646
parmtype if parmtype else arg .ctype (),
3617
3647
meth_node .name )
3618
3648
for (arg , var , (parmname , parmtype )) in zip (
3619
- outargs , outvars , meth_node .outp )]
3649
+ outargs , outvars , meth_node .outp )]
3620
3650
exit_handler = GotoExit_dml12 ()
3621
3651
with exit_handler :
3622
3652
code = [codegen_statement (meth_node .astcode ,
@@ -4040,15 +4070,20 @@ def copy_outarg(arg, var, parmname, parmtype, method_name):
4040
4070
an exception. We would be able to skip the proxy variable for
4041
4071
calls to non-throwing methods when arg.ctype() and parmtype are
4042
4072
equivalent types, but we don't do this today.'''
4043
- argtype = arg .ctype ()
4044
-
4045
- if not argtype :
4046
- raise ICE (arg .site , "unknown expression type" )
4073
+ if isinstance (arg , NonValue ):
4074
+ if not arg .writable :
4075
+ raise arg .exc ()
4047
4076
else :
4048
- ok , trunc , constviol = realtype (parmtype ).canstore (realtype (argtype ))
4049
- if not ok :
4050
- raise EARGT (arg .site , 'call' , method_name ,
4051
- arg .ctype (), parmname , parmtype , 'output' )
4077
+ argtype = arg .ctype ()
4078
+
4079
+ if not argtype :
4080
+ raise ICE (arg .site , "unknown expression type" )
4081
+ else :
4082
+ ok , trunc , constviol = realtype (parmtype ).canstore (
4083
+ realtype (argtype ))
4084
+ if not ok :
4085
+ raise EARGT (arg .site , 'call' , method_name ,
4086
+ arg .ctype (), parmname , parmtype , 'output' )
4052
4087
4053
4088
return mkCopyData (var .site , var , arg )
4054
4089
0 commit comments