Parses one `del` target: name, subscript, attribute, or a parenthesized group. */
(&mut self)
| 585 | |
| 586 | /* Parses one `del` target: name, subscript, attribute, or a parenthesized group. */ |
| 587 | fn parse_del_target(&mut self) { |
| 588 | if matches!(self.peek(), Some(TokenType::Name)) { |
| 589 | let name = self.advance_text(); |
| 590 | if self.eat_if(TokenType::Lsqb) { |
| 591 | // del `x[k]` or `x[a:b]`: BuildSlice so DelItem sees HeapObj::Slice. |
| 592 | self.emit_load_ssa(name); |
| 593 | self.parse_subscript(); |
| 594 | // Chained subscripts (`d[0][0]`): all but the last index in place. |
| 595 | while self.eat_if(TokenType::Lsqb) { |
| 596 | self.chunk.emit(OpCode::GetItem, 0); |
| 597 | self.parse_subscript(); |
| 598 | } |
| 599 | self.chunk.emit(OpCode::DelItem, 0); |
| 600 | } else if matches!(self.peek(), Some(TokenType::Dot)) { |
| 601 | // del `obj.attr` (chained): load object, LoadAttr intermediates, DelAttr last. |
| 602 | self.emit_load_ssa(name); |
| 603 | self.eat(TokenType::Dot); |
| 604 | let mut attr = self.advance_text(); |
| 605 | while matches!(self.peek(), Some(TokenType::Dot)) { |
| 606 | let idx = self.chunk.push_name(&attr); |
| 607 | self.chunk.emit(OpCode::LoadAttr, idx); |
| 608 | self.eat(TokenType::Dot); |
| 609 | attr = self.advance_text(); |
| 610 | } |
| 611 | let idx = self.chunk.push_name(&attr); |
| 612 | self.chunk.emit(OpCode::DelAttr, idx); |
| 613 | } else { |
| 614 | let idx = self.push_ssa_name(&name, self.current_version(&name)); |
| 615 | self.chunk.emit(OpCode::Del, idx); |
| 616 | } |
| 617 | } else { |
| 618 | // Parse as an expression, then rewrite the trailing access into its delete form. |
| 619 | self.expr(); |
| 620 | match self.chunk.instructions.last().map(|i| i.opcode) { |
| 621 | Some(OpCode::GetItem) => self.chunk.instructions.last_mut().unwrap().opcode = OpCode::DelItem, |
| 622 | Some(OpCode::LoadAttr) => self.chunk.instructions.last_mut().unwrap().opcode = OpCode::DelAttr, |
| 623 | Some(OpCode::LoadName) => self.chunk.instructions.last_mut().unwrap().opcode = OpCode::Del, |
| 624 | // `del (a, b)` / `del [a, b]`: a target group unbinds each plain name. |
| 625 | Some(OpCode::BuildTuple | OpCode::BuildList) => self.del_group_targets(), |
| 626 | _ => {} |
| 627 | } |
| 628 | } |
| 629 | } |
| 630 | |
| 631 | /* Rewrites a just-built tuple/list of name loads into individual unbinds. */ |
| 632 | fn del_group_targets(&mut self) { |
no test coverage detected