Skip to content

Commit 5aa2f3d

Browse files
committed
tmp
1 parent 11a9b4d commit 5aa2f3d

File tree

1 file changed

+102
-3
lines changed

1 file changed

+102
-3
lines changed

compiler/codegen/src/compile.rs

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@ use malachite_bigint::BigInt;
1515
use num_complex::Complex;
1616
use num_traits::{Num, ToPrimitive};
1717
use ruff_python_ast::{
18-
Alias, Arguments, BoolOp, CmpOp, Comprehension, ConversionFlag, DebugText, Decorator, DictItem, ExceptHandler, ExceptHandlerExceptHandler, Expr, ExprAttribute, ExprBoolOp, ExprFString, ExprList, ExprName, ExprStarred, ExprSubscript, ExprTuple, ExprUnaryOp, FString, FStringElement, FStringElements, FStringPart, Identifier, Int, Keyword, MatchCase, ModExpression, ModModule, Operator, Parameters, Pattern, PatternMatchAs, PatternMatchOr, PatternMatchSingleton, PatternMatchStar, PatternMatchValue, Singleton, Stmt, StmtExpr, TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, TypeParams, UnaryOp, WithItem
18+
Alias, Arguments, BoolOp, CmpOp, Comprehension, ConversionFlag, DebugText, Decorator, DictItem, ExceptHandler, ExceptHandlerExceptHandler, Expr, ExprAttribute, ExprBoolOp, ExprFString, ExprList, ExprName, ExprStarred, ExprSubscript, ExprTuple, ExprUnaryOp, FString, FStringElement, FStringElements, FStringPart, Identifier, Int, Keyword, MatchCase, ModExpression, ModModule, Operator, Parameters, Pattern, PatternMatchAs, PatternMatchOr, PatternMatchSequence, PatternMatchSingleton, PatternMatchStar, PatternMatchValue, Singleton, Stmt, StmtExpr, TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, TypeParams, UnaryOp, WithItem
1919
};
2020
use ruff_source_file::OneIndexed;
2121
use ruff_text_size::{Ranged, TextRange};
2222
// use rustpython_ast::located::{self as located_ast, Located};
2323
use rustpython_compiler_core::{
24-
Mode,
25-
bytecode::{self, Arg as OpArgMarker, CodeObject, ConstantData, Instruction, OpArg, OpArgType},
24+
bytecode::{self, Arg as OpArgMarker, CodeObject, ComparisonOperator, ConstantData, Instruction, OpArg, OpArgType}, Mode
2625
};
2726
use rustpython_compiler_source::SourceCode;
2827
// use rustpython_parser_core::source_code::{LineNumber, SourceLocation};
@@ -1954,6 +1953,49 @@ impl Compiler<'_> {
19541953
Ok(())
19551954
}
19561955

1956+
fn pattern_helper_sequence_subscr(
1957+
&mut self,
1958+
patterns: &[Pattern],
1959+
star: usize,
1960+
pc: &mut PatternContext,
1961+
) -> CompileResult<()> {
1962+
// Keep the subject around for extracting elements.
1963+
pc.on_top += 1;
1964+
let size = patterns.len();
1965+
for i in 0..size {
1966+
let pattern = &patterns[i];
1967+
// if pattern.is_wildcard() {
1968+
// continue;
1969+
// }
1970+
if i == star {
1971+
// This must be a starred wildcard.
1972+
// assert!(pattern.is_star_wildcard());
1973+
continue;
1974+
}
1975+
// Duplicate the subject.
1976+
emit!(self, Instruction::CopyItem { index: 1 as u32 });
1977+
if i < star {
1978+
// For indices before the star, use a nonnegative index equal to i.
1979+
self.emit_load_const(ConstantData::Integer { value: i.into() });
1980+
} else {
1981+
// For indices after the star, compute a nonnegative index:
1982+
// index = len(subject) - (size - i)
1983+
emit!(self, Instruction::GET_LEN);
1984+
emit!(self, Instruction::LoadConstNew { arg: PyObject::from_ssize_t((size - i) as isize) });
1985+
// Subtract to compute the correct index.
1986+
emit!(self, Instruction::BINARY { arg: BinaryOp::Sub });
1987+
}
1988+
// Use BINARY_OP/NB_SUBSCR to extract the element.
1989+
emit!(self, Instruction::BINARY_OP { arg: NB_SUBSCR });
1990+
// Compile the subpattern in irrefutable mode.
1991+
self.compiler_pattern_subpattern(pattern, pc)?;
1992+
}
1993+
// Pop the subject off the stack.
1994+
pc.on_top = pc.on_top.saturating_sub(1);
1995+
emit!(self, Instruction::POP_TOP);
1996+
Ok(())
1997+
}
1998+
19571999
fn compile_pattern_subpattern(
19582000
&mut self,
19592001
p: &Pattern,
@@ -2145,6 +2187,63 @@ impl Compiler<'_> {
21452187
Ok(())
21462188
}
21472189

2190+
fn codegen_pattern_sequence(&mut self, p: &PatternMatchSequence, pc: &mut PatternContext) -> CompileResult<()> {
2191+
// Ensure the pattern is a MatchSequence.
2192+
let patterns = p.patterns; // a slice of Pattern
2193+
let size = patterns.len();
2194+
let mut star: Option<usize> = None;
2195+
let mut only_wildcard = true;
2196+
let mut star_wildcard = false;
2197+
2198+
// Find a starred pattern, if it exists. There may be at most one.
2199+
for (i, pattern) in patterns.iter().enumerate() {
2200+
if pattern.is_match_star() {
2201+
if star.is_some() {
2202+
return Err(self.error(CodegenErrorType::MultipleStarArgs));
2203+
// return self._py_compile_error(loc(p), "multiple starred names in sequence pattern");
2204+
}
2205+
// star wildcard check
2206+
star_wildcard = pattern.as_match_star().map(|m| m.name.is_none()).unwrap_or(false);
2207+
only_wildcard &= star_wildcard;
2208+
star = Some(i);
2209+
continue;
2210+
}
2211+
// wildcard check
2212+
only_wildcard &= pattern.as_match_as().map(|m| m.name.is_none()).unwrap_or(false);
2213+
}
2214+
2215+
// Keep the subject on top during the sequence and length checks.
2216+
pc.on_top += 1;
2217+
emit!(self, Instruction::MatchSequence);
2218+
self.jump_to_fail_pop(pc, JumpOp::PopJumpIfFalse)?;
2219+
2220+
if star.is_none() {
2221+
// No star: len(subject) == size
2222+
emit!(self, Instruction::GetLen);
2223+
self.emit_load_const(ConstantData::Integer { value: size.into() });
2224+
emit!(self, Instruction::CompareOperation { op: ComparisonOperator::Equal });
2225+
self.jump_to_fail_pop(pc, JumpOp::PopJumpIfFalse)?;
2226+
} else if size > 1 {
2227+
// Star exists: len(subject) >= size - 1
2228+
emit!(self, Instruction::GetLen);
2229+
self.emit_load_const(ConstantData::Integer { value: (size - 1).into() });
2230+
emit!(self, Instruction::CompareOperation { op: ComparisonOperator::GreaterOrEqual });
2231+
self.jump_to_fail_pop(pc, JumpOp::PopJumpIfFalse)?;
2232+
}
2233+
2234+
// Whatever comes next should consume the subject.
2235+
pc.on_top -= 1;
2236+
if only_wildcard {
2237+
// Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc.
2238+
emit!(self, Instruction::Pop);
2239+
} else if star_wildcard {
2240+
self.pattern_helper_sequence_subscr(patterns, star, pc)?;
2241+
} else {
2242+
self.pattern_helper_sequence_unpack(patterns, star, pc)?;
2243+
}
2244+
Ok(())
2245+
}
2246+
21482247
fn compile_pattern_value(
21492248
&mut self,
21502249
p: &PatternMatchValue,

0 commit comments

Comments
 (0)