(
&mut self,
p: &ast::PatternMatchClass,
pc: &mut PatternContext,
)
| 6224 | } |
| 6225 | |
| 6226 | fn compile_pattern_class( |
| 6227 | &mut self, |
| 6228 | p: &ast::PatternMatchClass, |
| 6229 | pc: &mut PatternContext, |
| 6230 | ) -> CompileResult<()> { |
| 6231 | // Extract components from the MatchClass pattern. |
| 6232 | let match_class = p; |
| 6233 | let patterns = &match_class.arguments.patterns; |
| 6234 | |
| 6235 | // Extract keyword attributes and patterns. |
| 6236 | // Capacity is pre-allocated based on the number of keyword arguments. |
| 6237 | let mut kwd_attrs = Vec::with_capacity(match_class.arguments.keywords.len()); |
| 6238 | let mut kwd_patterns = Vec::with_capacity(match_class.arguments.keywords.len()); |
| 6239 | for kwd in &match_class.arguments.keywords { |
| 6240 | kwd_attrs.push(kwd.attr.clone()); |
| 6241 | kwd_patterns.push(kwd.pattern.clone()); |
| 6242 | } |
| 6243 | |
| 6244 | let nargs = patterns.len(); |
| 6245 | let n_attrs = kwd_attrs.len(); |
| 6246 | |
| 6247 | // Check for too many sub-patterns. |
| 6248 | if nargs > u32::MAX as usize || (nargs + n_attrs).saturating_sub(1) > i32::MAX as usize { |
| 6249 | return Err(self.error(CodegenErrorType::SyntaxError( |
| 6250 | "too many sub-patterns in class pattern".to_owned(), |
| 6251 | ))); |
| 6252 | } |
| 6253 | |
| 6254 | // Validate keyword attributes if any. |
| 6255 | if n_attrs != 0 { |
| 6256 | self.validate_kwd_attrs(&kwd_attrs, &kwd_patterns)?; |
| 6257 | } |
| 6258 | |
| 6259 | // Compile the class expression. |
| 6260 | self.compile_expression(&match_class.cls)?; |
| 6261 | |
| 6262 | // Create a new tuple of attribute names. |
| 6263 | let mut attr_names = vec![]; |
| 6264 | for name in &kwd_attrs { |
| 6265 | // Py_NewRef(name) is emulated by cloning the name into a PyObject. |
| 6266 | attr_names.push(ConstantData::Str { |
| 6267 | value: name.as_str().to_string().into(), |
| 6268 | }); |
| 6269 | } |
| 6270 | |
| 6271 | // Emit instructions: |
| 6272 | // 1. Load the new tuple of attribute names. |
| 6273 | self.emit_load_const(ConstantData::Tuple { |
| 6274 | elements: attr_names, |
| 6275 | }); |
| 6276 | // 2. Emit MATCH_CLASS with nargs. |
| 6277 | emit!( |
| 6278 | self, |
| 6279 | Instruction::MatchClass { |
| 6280 | count: u32::try_from(nargs).unwrap() |
| 6281 | } |
| 6282 | ); |
| 6283 | // 3. Duplicate the top of the stack. |
no test coverage detected