MCPcopy Create free account
hub / github.com/dylan-sutton-chavez/edge-python / for_stmt_inner

Method for_stmt_inner

compiler/src/modules/parser/control.rs:369–441  ·  view source on GitHub ↗
(&mut self, is_async: bool)

Source from the content-addressed store, hash-verified

367 /* for / async for, with optional tuple/star unpacking. */
368
369 pub(super) fn for_stmt_inner(&mut self, is_async: bool) {
370 self.advance();
371
372 let parens = self.eat_if(TokenType::Lpar);
373 let mut vars = Vec::new();
374 let mut star_pos: Option<usize> = None;
375 loop {
376 if self.eat_if(TokenType::Star) { star_pos = Some(vars.len()); }
377 vars.push(self.advance_text());
378 if !self.eat_if(TokenType::Comma) { break; }
379 if matches!(self.peek(), Some(TokenType::In | TokenType::Rpar)) { break; }
380 }
381 if parens {
382 self.eat(TokenType::Rpar);
383 }
384
385 self.eat(TokenType::In);
386 self.expr();
387 // Unparenthesized tuple iterable: `for x in 1, 2:` iterates the tuple.
388 let mut n = 1u16;
389 while self.eat_if(TokenType::Comma) {
390 if matches!(self.peek(), Some(TokenType::Colon) | None) { break; }
391 self.expr();
392 n += 1;
393 }
394 if n > 1 { self.chunk.emit(OpCode::BuildTuple, n); }
395 self.chunk.emit(OpCode::GetIter, is_async as u16);
396
397 self.enter_block();
398
399 let loop_start = self.chunk.instructions.len() as u16;
400 self.loop_starts.push(loop_start);
401 self.loop_breaks.push(vec![]);
402 self.loop_kinds.push(true);
403 self.loop_cleanup_base.push(self.cleanup_count);
404
405 let fi = self.emit_jump(OpCode::ForIter);
406
407 if vars.len() == 1 && star_pos.is_none() {
408 self.store_name(vars[0].clone());
409 } else {
410 if let Some(sp) = star_pos {
411 let before = sp as u16;
412 let after = (vars.len() - sp - 1) as u16;
413 self.chunk.emit(OpCode::UnpackEx, (before << 8) | after);
414 } else {
415 self.chunk.emit(OpCode::UnpackSequence, vars.len() as u16);
416 }
417 for var in &vars { self.store_name(var.clone()); }
418 }
419
420 self.eat(TokenType::Colon);
421 self.compile_block();
422
423 self.chunk.emit(OpCode::Jump, loop_start);
424 self.patch(fi);
425
426 // Pop loop state before the else so its break/continue target the enclosing loop.

Callers 1

stmtMethod · 0.80

Calls 15

advanceMethod · 0.80
eat_ifMethod · 0.80
pushMethod · 0.80
advance_textMethod · 0.80
eatMethod · 0.80
exprMethod · 0.80
emitMethod · 0.80
enter_blockMethod · 0.80
emit_jumpMethod · 0.80
is_noneMethod · 0.80
store_nameMethod · 0.80
compile_blockMethod · 0.80

Tested by

no test coverage detected