@@ -2460,37 +2460,48 @@ impl Compiler {
2460
2460
}
2461
2461
2462
2462
let mut loop_labels = vec ! [ ] ;
2463
+ let mut is_async = false ;
2463
2464
for generator in generators {
2464
- if generator. is_async {
2465
- unimplemented ! ( "async for comprehensions" ) ;
2466
- }
2467
-
2468
2465
let loop_block = self . new_block ( ) ;
2469
2466
let after_block = self . new_block ( ) ;
2470
2467
2471
2468
// Setup for loop:
2472
- self . emit ( Instruction :: SetupLoop {
2473
- break_target : after_block,
2474
- } ) ;
2469
+ if !generator. is_async {
2470
+ self . emit ( Instruction :: SetupLoop {
2471
+ break_target : after_block,
2472
+ } ) ;
2473
+ }
2475
2474
2476
2475
if loop_labels. is_empty ( ) {
2477
2476
// Load iterator onto stack (passed as first argument):
2478
2477
self . emit ( Instruction :: LoadFast ( arg0) ) ;
2479
2478
} else {
2480
2479
// Evaluate iterated item:
2481
2480
self . compile_expression ( & generator. iter ) ?;
2482
-
2483
- // Get iterator / turn item into an iterator
2484
- self . emit ( Instruction :: GetIter ) ;
2481
+ if generator. is_async {
2482
+ self . emit ( Instruction :: GetAIter ) ;
2483
+ } else {
2484
+ // Get iterator / turn item into an iterator
2485
+ self . emit ( Instruction :: GetIter ) ;
2486
+ }
2485
2487
}
2486
2488
2487
2489
loop_labels. push ( ( loop_block, after_block) ) ;
2488
-
2489
2490
self . switch_to_block ( loop_block) ;
2490
- self . emit ( Instruction :: ForIter {
2491
- target : after_block,
2492
- } ) ;
2493
-
2491
+ if generator. is_async {
2492
+ is_async = true ;
2493
+ self . emit ( Instruction :: SetupFinally {
2494
+ handler : after_block,
2495
+ } ) ;
2496
+ self . emit ( Instruction :: GetANext ) ;
2497
+ self . emit_constant ( ConstantData :: None ) ;
2498
+ self . emit ( Instruction :: YieldFrom ) ;
2499
+ self . emit ( Instruction :: PopBlock ) ;
2500
+ } else {
2501
+ self . emit ( Instruction :: ForIter {
2502
+ target : after_block,
2503
+ } ) ;
2504
+ }
2494
2505
self . compile_store ( & generator. target ) ?;
2495
2506
2496
2507
// Now evaluate the ifs:
@@ -2507,7 +2518,11 @@ impl Compiler {
2507
2518
2508
2519
// End of for loop:
2509
2520
self . switch_to_block ( after_block) ;
2510
- self . emit ( Instruction :: PopBlock ) ;
2521
+ if is_async {
2522
+ self . emit ( Instruction :: EndAsyncFor ) ;
2523
+ } else {
2524
+ self . emit ( Instruction :: PopBlock ) ;
2525
+ }
2511
2526
}
2512
2527
2513
2528
if return_none {
@@ -2544,10 +2559,19 @@ impl Compiler {
2544
2559
self . compile_expression ( & generators[ 0 ] . iter ) ?;
2545
2560
2546
2561
// Get iterator / turn item into an iterator
2547
- self . emit ( Instruction :: GetIter ) ;
2562
+ if is_async {
2563
+ self . emit ( Instruction :: GetAIter ) ;
2564
+ } else {
2565
+ self . emit ( Instruction :: GetIter ) ;
2566
+ }
2548
2567
2549
2568
// Call just created <listcomp> function:
2550
2569
self . emit ( Instruction :: CallFunctionPositional { nargs : 1 } ) ;
2570
+ if is_async {
2571
+ self . emit ( Instruction :: GetAwaitable ) ;
2572
+ self . emit_constant ( ConstantData :: None ) ;
2573
+ self . emit ( Instruction :: YieldFrom ) ;
2574
+ }
2551
2575
Ok ( ( ) )
2552
2576
}
2553
2577
@@ -2563,7 +2587,9 @@ impl Compiler {
2563
2587
// "generator_stop" => {}
2564
2588
"annotations" => self . future_annotations = true ,
2565
2589
other => {
2566
- return Err ( self . error ( CompileErrorType :: InvalidFutureFeature ( other. to_owned ( ) ) ) )
2590
+ return Err (
2591
+ self . error ( CompileErrorType :: InvalidFutureFeature ( other. to_owned ( ) ) )
2592
+ ) ;
2567
2593
}
2568
2594
}
2569
2595
}
0 commit comments