(
&mut self,
target: &ast::Expr,
op: &ast::Operator,
value: &ast::Expr,
)
| 7236 | } |
| 7237 | |
| 7238 | fn compile_augassign( |
| 7239 | &mut self, |
| 7240 | target: &ast::Expr, |
| 7241 | op: &ast::Operator, |
| 7242 | value: &ast::Expr, |
| 7243 | ) -> CompileResult<()> { |
| 7244 | enum AugAssignKind<'a> { |
| 7245 | Name { id: &'a str }, |
| 7246 | Subscript, |
| 7247 | Attr { idx: bytecode::NameIdx }, |
| 7248 | } |
| 7249 | |
| 7250 | let kind = match &target { |
| 7251 | ast::Expr::Name(ast::ExprName { id, .. }) => { |
| 7252 | let id = id.as_str(); |
| 7253 | self.compile_name(id, NameUsage::Load)?; |
| 7254 | AugAssignKind::Name { id } |
| 7255 | } |
| 7256 | ast::Expr::Subscript(ast::ExprSubscript { |
| 7257 | value, |
| 7258 | slice, |
| 7259 | ctx: _, |
| 7260 | .. |
| 7261 | }) => { |
| 7262 | // For augmented assignment, we need to load the value first |
| 7263 | // But we can't use compile_subscript directly because we need DUP_TOP2 |
| 7264 | self.compile_expression(value)?; |
| 7265 | self.compile_expression(slice)?; |
| 7266 | emit!(self, Instruction::Copy { i: 2 }); |
| 7267 | emit!(self, Instruction::Copy { i: 2 }); |
| 7268 | emit!( |
| 7269 | self, |
| 7270 | Instruction::BinaryOp { |
| 7271 | op: BinaryOperator::Subscr |
| 7272 | } |
| 7273 | ); |
| 7274 | AugAssignKind::Subscript |
| 7275 | } |
| 7276 | ast::Expr::Attribute(ast::ExprAttribute { value, attr, .. }) => { |
| 7277 | let attr = attr.as_str(); |
| 7278 | self.compile_expression(value)?; |
| 7279 | emit!(self, Instruction::Copy { i: 1 }); |
| 7280 | let idx = self.name(attr); |
| 7281 | self.emit_load_attr(idx); |
| 7282 | AugAssignKind::Attr { idx } |
| 7283 | } |
| 7284 | _ => { |
| 7285 | return Err(self.error(CodegenErrorType::Assign(target.python_name()))); |
| 7286 | } |
| 7287 | }; |
| 7288 | |
| 7289 | self.compile_expression(value)?; |
| 7290 | self.compile_op(op, true); |
| 7291 | |
| 7292 | match kind { |
| 7293 | AugAssignKind::Name { id } => { |
| 7294 | // stack: RESULT |
| 7295 | self.compile_name(id, NameUsage::Store)?; |
no test coverage detected