@@ -33,6 +33,7 @@ enum CallType {
33
33
Keyword { nargs : u32 } ,
34
34
Ex { has_kwargs : bool } ,
35
35
}
36
+
36
37
impl CallType {
37
38
fn normal_call ( self ) -> Instruction {
38
39
match self {
@@ -69,6 +70,7 @@ pub struct CompileOpts {
69
70
/// not emit assert statements
70
71
pub optimize : u8 ,
71
72
}
73
+
72
74
impl Default for CompileOpts {
73
75
fn default ( ) -> Self {
74
76
CompileOpts { optimize : 0 }
@@ -1608,7 +1610,7 @@ impl Compiler {
1608
1610
"starred assignment target must be in a list or tuple" . to_owned ( ) ,
1609
1611
) ,
1610
1612
_ => CompileErrorType :: Assign ( target. node . name ( ) ) ,
1611
- } ) )
1613
+ } ) ) ;
1612
1614
}
1613
1615
}
1614
1616
@@ -1907,10 +1909,10 @@ impl Compiler {
1907
1909
YieldFrom { value } => {
1908
1910
match self . ctx . func {
1909
1911
FunctionContext :: NoFunction => {
1910
- return Err ( self . error ( CompileErrorType :: InvalidYieldFrom ) )
1912
+ return Err ( self . error ( CompileErrorType :: InvalidYieldFrom ) ) ;
1911
1913
}
1912
1914
FunctionContext :: AsyncFunction => {
1913
- return Err ( self . error ( CompileErrorType :: AsyncYieldFrom ) )
1915
+ return Err ( self . error ( CompileErrorType :: AsyncYieldFrom ) ) ;
1914
1916
}
1915
1917
FunctionContext :: Function => { }
1916
1918
}
@@ -2295,37 +2297,48 @@ impl Compiler {
2295
2297
}
2296
2298
2297
2299
let mut loop_labels = vec ! [ ] ;
2300
+ let mut is_async = false ;
2298
2301
for generator in generators {
2299
- if generator. is_async {
2300
- unimplemented ! ( "async for comprehensions" ) ;
2301
- }
2302
-
2303
2302
let loop_block = self . new_block ( ) ;
2304
2303
let after_block = self . new_block ( ) ;
2305
2304
2306
2305
// Setup for loop:
2307
- self . emit ( Instruction :: SetupLoop {
2308
- break_target : after_block,
2309
- } ) ;
2306
+ if !generator. is_async {
2307
+ self . emit ( Instruction :: SetupLoop {
2308
+ break_target : after_block,
2309
+ } ) ;
2310
+ }
2310
2311
2311
2312
if loop_labels. is_empty ( ) {
2312
2313
// Load iterator onto stack (passed as first argument):
2313
2314
self . emit ( Instruction :: LoadFast ( arg0) ) ;
2314
2315
} else {
2315
2316
// Evaluate iterated item:
2316
2317
self . compile_expression ( & generator. iter ) ?;
2317
-
2318
- // Get iterator / turn item into an iterator
2319
- self . emit ( Instruction :: GetIter ) ;
2318
+ if generator. is_async {
2319
+ self . emit ( Instruction :: GetAIter ) ;
2320
+ } else {
2321
+ // Get iterator / turn item into an iterator
2322
+ self . emit ( Instruction :: GetIter ) ;
2323
+ }
2320
2324
}
2321
2325
2322
2326
loop_labels. push ( ( loop_block, after_block) ) ;
2323
-
2324
2327
self . switch_to_block ( loop_block) ;
2325
- self . emit ( Instruction :: ForIter {
2326
- target : after_block,
2327
- } ) ;
2328
-
2328
+ if generator. is_async {
2329
+ is_async = true ;
2330
+ self . emit ( Instruction :: SetupFinally {
2331
+ handler : after_block,
2332
+ } ) ;
2333
+ self . emit ( Instruction :: GetANext ) ;
2334
+ self . emit_constant ( ConstantData :: None ) ;
2335
+ self . emit ( Instruction :: YieldFrom ) ;
2336
+ self . emit ( Instruction :: PopBlock ) ;
2337
+ } else {
2338
+ self . emit ( Instruction :: ForIter {
2339
+ target : after_block,
2340
+ } ) ;
2341
+ }
2329
2342
self . compile_store ( & generator. target ) ?;
2330
2343
2331
2344
// Now evaluate the ifs:
@@ -2342,7 +2355,11 @@ impl Compiler {
2342
2355
2343
2356
// End of for loop:
2344
2357
self . switch_to_block ( after_block) ;
2345
- self . emit ( Instruction :: PopBlock ) ;
2358
+ if is_async {
2359
+ self . emit ( Instruction :: EndAsyncFor ) ;
2360
+ } else {
2361
+ self . emit ( Instruction :: PopBlock ) ;
2362
+ }
2346
2363
}
2347
2364
2348
2365
if return_none {
@@ -2379,10 +2396,19 @@ impl Compiler {
2379
2396
self . compile_expression ( & generators[ 0 ] . iter ) ?;
2380
2397
2381
2398
// Get iterator / turn item into an iterator
2382
- self . emit ( Instruction :: GetIter ) ;
2399
+ if is_async {
2400
+ self . emit ( Instruction :: GetAIter ) ;
2401
+ } else {
2402
+ self . emit ( Instruction :: GetIter ) ;
2403
+ }
2383
2404
2384
2405
// Call just created <listcomp> function:
2385
2406
self . emit ( Instruction :: CallFunctionPositional { nargs : 1 } ) ;
2407
+ if is_async {
2408
+ self . emit ( Instruction :: GetAwaitable ) ;
2409
+ self . emit_constant ( ConstantData :: None ) ;
2410
+ self . emit ( Instruction :: YieldFrom ) ;
2411
+ }
2386
2412
Ok ( ( ) )
2387
2413
}
2388
2414
@@ -2398,7 +2424,9 @@ impl Compiler {
2398
2424
// "generator_stop" => {}
2399
2425
// "annotations" => {}
2400
2426
other => {
2401
- return Err ( self . error ( CompileErrorType :: InvalidFutureFeature ( other. to_owned ( ) ) ) )
2427
+ return Err (
2428
+ self . error ( CompileErrorType :: InvalidFutureFeature ( other. to_owned ( ) ) )
2429
+ ) ;
2402
2430
}
2403
2431
}
2404
2432
}
0 commit comments