@@ -1944,32 +1944,35 @@ impl Compiler<'_> {
1944
1944
n : Option < & Identifier > ,
1945
1945
pc : & mut PatternContext ,
1946
1946
) -> CompileResult < ( ) > {
1947
- // If no name is provided, simply pop the top of the stack.
1948
- if n . is_none ( ) {
1949
- emit ! ( self , Instruction :: Pop ) ;
1950
- return Ok ( ( ) ) ;
1951
- }
1952
- let name = n . unwrap ( ) ;
1953
-
1954
- // Check if the name is forbidden for storing.
1955
- if self . forbidden_name ( name. as_str ( ) , NameUsage :: Store ) ? {
1956
- return Err ( self . compile_error_forbidden_name ( name. as_str ( ) ) ) ;
1957
- }
1947
+ match n {
1948
+ // If no name is provided, simply pop the top of the stack.
1949
+ None => {
1950
+ emit ! ( self , Instruction :: Pop ) ;
1951
+ Ok ( ( ) )
1952
+ }
1953
+ Some ( name ) => {
1954
+ // Check if the name is forbidden for storing.
1955
+ if self . forbidden_name ( name. as_str ( ) , NameUsage :: Store ) ? {
1956
+ return Err ( self . compile_error_forbidden_name ( name. as_str ( ) ) ) ;
1957
+ }
1958
1958
1959
- // Ensure we don't store the same name twice.
1960
- if pc. stores . contains ( & name. to_string ( ) ) {
1961
- return Err ( self . error ( CodegenErrorType :: DuplicateStore ( name. as_str ( ) . to_string ( ) ) ) ) ;
1962
- }
1959
+ // Ensure we don't store the same name twice.
1960
+ // TODO: maybe pc.stores should be a set?
1961
+ if pc. stores . contains ( & name. to_string ( ) ) {
1962
+ return Err (
1963
+ self . error ( CodegenErrorType :: DuplicateStore ( name. as_str ( ) . to_string ( ) ) )
1964
+ ) ;
1965
+ }
1963
1966
1964
- // Calculate how many items to rotate:
1965
- // the count is the number of items to preserve on top plus the current stored names,
1966
- // plus one for the new value.
1967
- let rotations = pc. on_top + pc. stores . len ( ) + 1 ;
1968
- self . pattern_helper_rotate ( rotations) ?;
1967
+ // Calculate how many items to rotate:
1968
+ let rotations = pc. on_top + pc. stores . len ( ) + 1 ;
1969
+ self . pattern_helper_rotate ( rotations) ?;
1969
1970
1970
- // Append the name to the captured stores.
1971
- pc. stores . push ( name. to_string ( ) ) ;
1972
- Ok ( ( ) )
1971
+ // Append the name to the captured stores.
1972
+ pc. stores . push ( name. to_string ( ) ) ;
1973
+ Ok ( ( ) )
1974
+ }
1975
+ }
1973
1976
}
1974
1977
1975
1978
fn pattern_unpack_helper ( & mut self , elts : & [ Pattern ] ) -> CompileResult < ( ) > {
@@ -2155,10 +2158,7 @@ impl Compiler<'_> {
2155
2158
for ident in attrs. iter ( ) . take ( n_attrs) . skip ( i + 1 ) {
2156
2159
let other = ident. as_str ( ) ;
2157
2160
if attr == other {
2158
- todo ! ( ) ;
2159
- // return Err(self.compiler_error(
2160
- // &format!("attribute name repeated in class pattern: {}", attr),
2161
- // ));
2161
+ return Err ( self . error ( CodegenErrorType :: RepeatedAttributePattern ) ) ;
2162
2162
}
2163
2163
}
2164
2164
}
@@ -2185,16 +2185,6 @@ impl Compiler<'_> {
2185
2185
2186
2186
let nargs = patterns. len ( ) ;
2187
2187
let n_attrs = kwd_attrs. len ( ) ;
2188
- let nkwd_patterns = kwd_patterns. len ( ) ;
2189
-
2190
- // Validate that keyword attribute names and patterns match in length.
2191
- if n_attrs != nkwd_patterns {
2192
- let msg = format ! (
2193
- "kwd_attrs ({}) / kwd_patterns ({}) length mismatch in class pattern" ,
2194
- n_attrs, nkwd_patterns
2195
- ) ;
2196
- unreachable ! ( "{}" , msg) ;
2197
- }
2198
2188
2199
2189
// Check for too many sub-patterns.
2200
2190
if nargs > u32:: MAX as usize || ( nargs + n_attrs) . saturating_sub ( 1 ) > i32:: MAX as usize {
@@ -2223,6 +2213,8 @@ impl Compiler<'_> {
2223
2213
} ) ;
2224
2214
}
2225
2215
2216
+ use bytecode:: TestOperator :: * ;
2217
+
2226
2218
// Emit instructions:
2227
2219
// 1. Load the new tuple of attribute names.
2228
2220
self . emit_load_const ( ConstantData :: Tuple {
@@ -2235,7 +2227,7 @@ impl Compiler<'_> {
2235
2227
// 4. Load None.
2236
2228
self . emit_load_const ( ConstantData :: None ) ;
2237
2229
// 5. Compare with IS_OP 1.
2238
- emit ! ( self , Instruction :: IsOperation ( true ) ) ;
2230
+ emit ! ( self , Instruction :: TestOperation { op : IsNot } ) ;
2239
2231
2240
2232
// At this point the TOS is a tuple of (nargs + n_attrs) attributes (or None).
2241
2233
pc. on_top += 1 ;
@@ -2253,20 +2245,12 @@ impl Compiler<'_> {
2253
2245
pc. on_top -= 1 ;
2254
2246
2255
2247
// Process each sub-pattern.
2256
- for i in 0 ..total {
2257
- // Decrement the on_top counter as each sub-pattern is processed.
2248
+ for subpattern in patterns. iter ( ) . chain ( kwd_patterns. iter ( ) ) {
2249
+ // Decrement the on_top counter as each sub-pattern is processed
2250
+ // (on_top should be zero at the end of the algorithm as a sanity check).
2258
2251
pc. on_top -= 1 ;
2259
- let subpattern = if i < nargs {
2260
- // Positional sub-pattern.
2261
- & patterns[ i]
2262
- } else {
2263
- // Keyword sub-pattern.
2264
- & kwd_patterns[ i - nargs]
2265
- } ;
2266
2252
if subpattern. is_wildcard ( ) {
2267
- // For wildcard patterns, simply pop the top of the stack.
2268
2253
emit ! ( self , Instruction :: Pop ) ;
2269
- continue ;
2270
2254
}
2271
2255
// Compile the subpattern without irrefutability checks.
2272
2256
self . compile_pattern_subpattern ( subpattern, pc) ?;
@@ -2351,7 +2335,7 @@ impl Compiler<'_> {
2351
2335
// emit!(self, Instruction::CopyItem { index: 1_u32 });
2352
2336
// self.emit_load_const(ConstantData::None);
2353
2337
// // TODO: should be is
2354
- // emit!(self, Instruction::IsOperation(true) );
2338
+ // emit!(self, Instruction::TestOperation::IsNot );
2355
2339
// self.jump_to_fail_pop(pc, JumpOp::PopJumpIfFalse)?;
2356
2340
2357
2341
// // Unpack the tuple of values.
@@ -2428,15 +2412,16 @@ impl Compiler<'_> {
2428
2412
} else {
2429
2413
let control_vec = control. as_ref ( ) . unwrap ( ) ;
2430
2414
if nstores != control_vec. len ( ) {
2431
- todo ! ( ) ;
2432
- // return self.compiler_error("alternative patterns bind different names");
2415
+ return Err ( self . error ( CodegenErrorType :: ConflictingNameBindPattern ) ) ;
2433
2416
} else if nstores > 0 {
2434
2417
// Check that the names occur in the same order.
2435
2418
for icontrol in ( 0 ..nstores) . rev ( ) {
2436
2419
let name = & control_vec[ icontrol] ;
2437
2420
// Find the index of `name` in the current stores.
2438
- let istores = pc. stores . iter ( ) . position ( |n| n == name) . unwrap ( ) ;
2439
- // .ok_or_else(|| self.compiler_error("alternative patterns bind different names"))?;
2421
+ let istores =
2422
+ pc. stores . iter ( ) . position ( |n| n == name) . ok_or_else ( || {
2423
+ self . error ( CodegenErrorType :: ConflictingNameBindPattern )
2424
+ } ) ?;
2440
2425
if icontrol != istores {
2441
2426
// The orders differ; we must reorder.
2442
2427
assert ! ( istores < icontrol, "expected istores < icontrol" ) ;
@@ -2480,14 +2465,14 @@ impl Compiler<'_> {
2480
2465
self . switch_to_block ( end) ;
2481
2466
2482
2467
// Adjust the final captures.
2483
- let nstores = control. as_ref ( ) . unwrap ( ) . len ( ) ;
2484
- let nrots = nstores + 1 + pc. on_top + pc. stores . len ( ) ;
2485
- for i in 0 ..nstores {
2468
+ let n_stores = control. as_ref ( ) . unwrap ( ) . len ( ) ;
2469
+ let n_rots = n_stores + 1 + pc. on_top + pc. stores . len ( ) ;
2470
+ for i in 0 ..n_stores {
2486
2471
// Rotate the capture to its proper place.
2487
- self . pattern_helper_rotate ( nrots ) ?;
2472
+ self . pattern_helper_rotate ( n_rots ) ?;
2488
2473
let name = & control. as_ref ( ) . unwrap ( ) [ i] ;
2489
2474
// Check for duplicate binding.
2490
- if pc. stores . iter ( ) . any ( |n| n == name) {
2475
+ if pc. stores . contains ( name) {
2491
2476
return Err ( self . error ( CodegenErrorType :: DuplicateStore ( name. to_string ( ) ) ) ) ;
2492
2477
}
2493
2478
pc. stores . push ( name. clone ( ) ) ;
@@ -4608,23 +4593,6 @@ for stop_exc in (StopIteration('spam'), StopAsyncIteration('ham')):
4608
4593
self.assertIs(ex, stop_exc)
4609
4594
else:
4610
4595
self.fail(f'{stop_exc} was suppressed')
4611
- "
4612
- ) ) ;
4613
- }
4614
-
4615
- #[ test]
4616
- fn test_match ( ) {
4617
- assert_dis_snapshot ! ( compile_exec(
4618
- "\
4619
- class Test:
4620
- pass
4621
-
4622
- t = Test()
4623
- match t:
4624
- case Test():
4625
- assert True
4626
- case _:
4627
- assert False
4628
4596
"
4629
4597
) ) ;
4630
4598
}
0 commit comments