Compile a subscript expression = compiler_subscript
(
&mut self,
value: &ast::Expr,
slice: &ast::Expr,
ctx: ast::ExprContext,
)
| 510 | /// Compile a subscript expression |
| 511 | // = compiler_subscript |
| 512 | fn compile_subscript( |
| 513 | &mut self, |
| 514 | value: &ast::Expr, |
| 515 | slice: &ast::Expr, |
| 516 | ctx: ast::ExprContext, |
| 517 | ) -> CompileResult<()> { |
| 518 | // Save full subscript expression range (set by compile_expression before this call) |
| 519 | let subscript_range = self.current_source_range; |
| 520 | |
| 521 | // VISIT(c, expr, e->v.Subscript.value) |
| 522 | self.compile_expression(value)?; |
| 523 | |
| 524 | // Handle two-element non-constant slice with BINARY_SLICE/STORE_SLICE |
| 525 | let use_slice_opt = matches!(ctx, ast::ExprContext::Load | ast::ExprContext::Store) |
| 526 | && slice.should_use_slice_optimization(); |
| 527 | if use_slice_opt { |
| 528 | match slice { |
| 529 | ast::Expr::Slice(s) => self.compile_slice_two_parts(s)?, |
| 530 | _ => unreachable!( |
| 531 | "should_use_slice_optimization should only return true for ast::Expr::Slice" |
| 532 | ), |
| 533 | }; |
| 534 | } else { |
| 535 | // VISIT(c, expr, e->v.Subscript.slice) |
| 536 | self.compile_expression(slice)?; |
| 537 | } |
| 538 | |
| 539 | // Restore full subscript expression range before emitting |
| 540 | self.set_source_range(subscript_range); |
| 541 | |
| 542 | match (use_slice_opt, ctx) { |
| 543 | (true, ast::ExprContext::Load) => emit!(self, Instruction::BinarySlice), |
| 544 | (true, ast::ExprContext::Store) => emit!(self, Instruction::StoreSlice), |
| 545 | (true, _) => unreachable!(), |
| 546 | (false, ast::ExprContext::Load) => emit!( |
| 547 | self, |
| 548 | Instruction::BinaryOp { |
| 549 | op: BinaryOperator::Subscr |
| 550 | } |
| 551 | ), |
| 552 | (false, ast::ExprContext::Store) => emit!(self, Instruction::StoreSubscr), |
| 553 | (false, ast::ExprContext::Del) => emit!(self, Instruction::DeleteSubscr), |
| 554 | (false, ast::ExprContext::Invalid) => { |
| 555 | return Err(self.error(CodegenErrorType::SyntaxError( |
| 556 | "Invalid expression context".to_owned(), |
| 557 | ))); |
| 558 | } |
| 559 | } |
| 560 | |
| 561 | Ok(()) |
| 562 | } |
| 563 | |
| 564 | /// Helper function for compiling tuples/lists/sets with starred expressions |
| 565 | /// |
no test coverage detected