(
&mut self,
test: &ast::Expr,
body: &[ast::Stmt],
orelse: &[ast::Stmt],
)
| 5494 | } |
| 5495 | |
| 5496 | fn compile_while( |
| 5497 | &mut self, |
| 5498 | test: &ast::Expr, |
| 5499 | body: &[ast::Stmt], |
| 5500 | orelse: &[ast::Stmt], |
| 5501 | ) -> CompileResult<()> { |
| 5502 | self.enter_conditional_block(); |
| 5503 | |
| 5504 | let constant = Self::expr_constant(test); |
| 5505 | |
| 5506 | // while False: body → walk body (consuming sub_tables) but don't emit, |
| 5507 | // then compile orelse |
| 5508 | if constant == Some(false) { |
| 5509 | self.emit_nop(); |
| 5510 | let while_block = self.new_block(); |
| 5511 | let after_block = self.new_block(); |
| 5512 | self.push_fblock(FBlockType::WhileLoop, while_block, after_block)?; |
| 5513 | self.do_not_emit_bytecode += 1; |
| 5514 | self.compile_statements(body)?; |
| 5515 | self.do_not_emit_bytecode -= 1; |
| 5516 | self.pop_fblock(FBlockType::WhileLoop); |
| 5517 | self.compile_statements(orelse)?; |
| 5518 | self.leave_conditional_block(); |
| 5519 | return Ok(()); |
| 5520 | } |
| 5521 | |
| 5522 | let while_block = self.new_block(); |
| 5523 | let else_block = self.new_block(); |
| 5524 | let after_block = self.new_block(); |
| 5525 | |
| 5526 | self.switch_to_block(while_block); |
| 5527 | self.push_fblock(FBlockType::WhileLoop, while_block, after_block)?; |
| 5528 | |
| 5529 | // while True: → no condition test, just NOP |
| 5530 | if constant == Some(true) { |
| 5531 | self.emit_nop(); |
| 5532 | } else { |
| 5533 | self.compile_jump_if(test, false, else_block)?; |
| 5534 | } |
| 5535 | |
| 5536 | let was_in_loop = self.ctx.loop_data.replace((while_block, after_block)); |
| 5537 | self.compile_statements(body)?; |
| 5538 | self.ctx.loop_data = was_in_loop; |
| 5539 | emit!(self, PseudoInstruction::Jump { delta: while_block }); |
| 5540 | self.switch_to_block(else_block); |
| 5541 | |
| 5542 | self.pop_fblock(FBlockType::WhileLoop); |
| 5543 | self.compile_statements(orelse)?; |
| 5544 | self.switch_to_block(after_block); |
| 5545 | |
| 5546 | self.leave_conditional_block(); |
| 5547 | Ok(()) |
| 5548 | } |
| 5549 | |
| 5550 | fn compile_with( |
| 5551 | &mut self, |
no test coverage detected