mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
implement async for function in compiler
This commit is contained in:
committed by
Jeong YunWon
parent
2856aff757
commit
61f37b10e2
@@ -2656,11 +2656,8 @@ impl Compiler {
|
||||
}
|
||||
|
||||
let mut loop_labels = vec![];
|
||||
let mut is_async = false;
|
||||
for generator in generators {
|
||||
if generator.is_async {
|
||||
unimplemented!("async for comprehensions");
|
||||
}
|
||||
|
||||
let loop_block = self.new_block();
|
||||
let after_block = self.new_block();
|
||||
|
||||
@@ -2672,35 +2669,31 @@ impl Compiler {
|
||||
self.compile_expression(&generator.iter)?;
|
||||
|
||||
// Get iterator / turn item into an iterator
|
||||
emit!(self, Instruction::GetIter);
|
||||
if generator.is_async {
|
||||
emit!(self, Instruction::GetAIter);
|
||||
} else {
|
||||
emit!(self, Instruction::GetIter);
|
||||
}
|
||||
}
|
||||
|
||||
loop_labels.push((loop_block, after_block));
|
||||
|
||||
self.switch_to_block(loop_block);
|
||||
if generator.is_async {
|
||||
let check_asynciter_block = self.new_block();
|
||||
|
||||
self.emit(Instruction::GetAIter);
|
||||
self.switch_to_block(loop_block);
|
||||
self.emit(Instruction::SetupExcept {
|
||||
handler: check_asynciter_block,
|
||||
is_async = true;
|
||||
emit!(self, Instruction::SetupExcept {
|
||||
handler: after_block,
|
||||
});
|
||||
self.emit(Instruction::GetANext);
|
||||
emit!(self, Instruction::GetANext);
|
||||
self.emit_constant(ConstantData::None);
|
||||
self.emit(Instruction::YieldFrom);
|
||||
self.compile_store(&generator.target)?;
|
||||
self.emit(Instruction::PopBlock);
|
||||
|
||||
emit!(self, Instruction::YieldFrom);
|
||||
emit!(self, Instruction::PopBlock);
|
||||
} else {
|
||||
// Get iterator / turn item into an iterator
|
||||
self.emit(Instruction::GetIter);
|
||||
|
||||
self.switch_to_block(loop_block);
|
||||
self.emit(Instruction::ForIter {
|
||||
target: after_block,
|
||||
});
|
||||
|
||||
self.compile_store(&generator.target)?;
|
||||
emit!(
|
||||
self,
|
||||
Instruction::ForIter {
|
||||
target: after_block,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
self.compile_store(&generator.target)?;
|
||||
@@ -2719,6 +2712,9 @@ impl Compiler {
|
||||
|
||||
// End of for loop:
|
||||
self.switch_to_block(after_block);
|
||||
if is_async {
|
||||
emit!(self, Instruction::EndAsyncFor);
|
||||
}
|
||||
}
|
||||
|
||||
if return_none {
|
||||
@@ -2755,10 +2751,19 @@ impl Compiler {
|
||||
self.compile_expression(&generators[0].iter)?;
|
||||
|
||||
// Get iterator / turn item into an iterator
|
||||
emit!(self, Instruction::GetIter);
|
||||
if is_async {
|
||||
emit!(self, Instruction::GetAIter);
|
||||
} else {
|
||||
emit!(self, Instruction::GetIter);
|
||||
};
|
||||
|
||||
// Call just created <listcomp> function:
|
||||
emit!(self, Instruction::CallFunctionPositional { nargs: 1 });
|
||||
if is_async {
|
||||
emit!(self, Instruction::GetAwaitable);
|
||||
self.emit_constant(ConstantData::None);
|
||||
emit!(self, Instruction::YieldFrom);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user