Helper to store a captured name for a star pattern. If `n` is `None`, it emits a POP_TOP instruction. Otherwise, it first checks that the name is allowed and not already stored. Then it rotates the object on the stack beneath any preserved items and appends the name to the list of captured names.
(
&mut self,
n: Option<&ast::Identifier>,
pc: &mut PatternContext,
)
| 5993 | /// the object on the stack beneath any preserved items and appends the name |
| 5994 | /// to the list of captured names. |
| 5995 | fn pattern_helper_store_name( |
| 5996 | &mut self, |
| 5997 | n: Option<&ast::Identifier>, |
| 5998 | pc: &mut PatternContext, |
| 5999 | ) -> CompileResult<()> { |
| 6000 | match n { |
| 6001 | // If no name is provided, simply pop the top of the stack. |
| 6002 | None => { |
| 6003 | emit!(self, Instruction::PopTop); |
| 6004 | Ok(()) |
| 6005 | } |
| 6006 | Some(name) => { |
| 6007 | // Check if the name is forbidden for storing. |
| 6008 | if self.forbidden_name(name.as_str(), NameUsage::Store)? { |
| 6009 | return Err(self.compile_error_forbidden_name(name.as_str())); |
| 6010 | } |
| 6011 | |
| 6012 | // Ensure we don't store the same name twice. |
| 6013 | // TODO: maybe pc.stores should be a set? |
| 6014 | if pc.stores.contains(&name.to_string()) { |
| 6015 | return Err( |
| 6016 | self.error(CodegenErrorType::DuplicateStore(name.as_str().to_string())) |
| 6017 | ); |
| 6018 | } |
| 6019 | |
| 6020 | // Calculate how many items to rotate: |
| 6021 | let rotations = pc.on_top + pc.stores.len() + 1; |
| 6022 | self.pattern_helper_rotate(rotations)?; |
| 6023 | |
| 6024 | // Append the name to the captured stores. |
| 6025 | pc.stores.push(name.to_string()); |
| 6026 | Ok(()) |
| 6027 | } |
| 6028 | } |
| 6029 | } |
| 6030 | |
| 6031 | fn pattern_unpack_helper(&mut self, elts: &[ast::Pattern]) -> CompileResult<()> { |
| 6032 | let n = elts.len(); |
no test coverage detected