mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
general case for count
This commit is contained in:
@@ -80,13 +80,10 @@ mod _sre {
|
||||
indexgroup: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<Pattern> {
|
||||
let code = vm.extract_elements::<u32>(&code)?;
|
||||
dbg!(&code);
|
||||
|
||||
Ok(Pattern {
|
||||
pattern,
|
||||
flags: SreFlag::from_bits_truncate(flags),
|
||||
code,
|
||||
code: vm.extract_elements::<u32>(&code)?,
|
||||
groups,
|
||||
groupindex,
|
||||
indexgroup: vm.extract_elements(&indexgroup)?,
|
||||
@@ -134,21 +131,21 @@ mod _sre {
|
||||
#[pyimpl]
|
||||
impl Pattern {
|
||||
#[pymethod(name = "match")]
|
||||
fn pymatch(&self, string_args: StringArgs, vm: &VirtualMachine) -> Option<PyRef<Match>> {
|
||||
fn pymatch(zelf: PyRef<Pattern>, string_args: StringArgs, vm: &VirtualMachine) -> Option<PyRef<Match>> {
|
||||
interp::pymatch(
|
||||
string_args.string,
|
||||
string_args.pos,
|
||||
string_args.endpos,
|
||||
&self,
|
||||
zelf,
|
||||
)
|
||||
.map(|x| x.into_ref(vm))
|
||||
}
|
||||
#[pymethod]
|
||||
fn fullmatch(&self, string_args: StringArgs, vm: &VirtualMachine) -> Option<PyRef<Match>> {
|
||||
fn fullmatch(zelf: PyRef<Pattern>, string_args: StringArgs, vm: &VirtualMachine) -> Option<PyRef<Match>> {
|
||||
// TODO: need optimize
|
||||
let start = string_args.pos;
|
||||
let end = string_args.endpos;
|
||||
let m = self.pymatch(string_args, vm);
|
||||
let m = Self::pymatch(zelf, string_args, vm);
|
||||
if let Some(m) = m {
|
||||
if m.start == start && m.end == end {
|
||||
return Some(m);
|
||||
@@ -157,12 +154,12 @@ mod _sre {
|
||||
None
|
||||
}
|
||||
#[pymethod]
|
||||
fn search(&self, string_args: StringArgs, vm: &VirtualMachine) -> Option<PyRef<Match>> {
|
||||
fn search(zelf: PyRef<Pattern>, string_args: StringArgs, vm: &VirtualMachine) -> Option<PyRef<Match>> {
|
||||
// TODO: optimize by op info and skip prefix
|
||||
let start = string_args.pos;
|
||||
for i in start..string_args.endpos {
|
||||
if let Some(m) =
|
||||
interp::pymatch(string_args.string.clone(), i, string_args.endpos, &self)
|
||||
interp::pymatch(string_args.string.clone(), i, string_args.endpos, zelf.clone())
|
||||
{
|
||||
return Some(m.into_ref(vm));
|
||||
}
|
||||
@@ -189,6 +186,10 @@ mod _sre {
|
||||
fn flags(&self) -> u16 {
|
||||
self.flags.bits()
|
||||
}
|
||||
|
||||
fn subx(&self, sub_args: SubArgs, vm: &VirtualMachine) -> PyResult<PyStrRef> {
|
||||
Err(vm.new_not_implemented_error("".to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
use super::_sre::{Match, Pattern, MAXREPEAT};
|
||||
use super::constants::{SreAtCode, SreCatCode, SreFlag, SreOpcode};
|
||||
use crate::builtins::PyStrRef;
|
||||
use crate::pyobject::PyRef;
|
||||
use rustpython_common::borrow::BorrowValue;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
@@ -98,7 +99,7 @@ pub(crate) fn pymatch(
|
||||
string: PyStrRef,
|
||||
start: usize,
|
||||
end: usize,
|
||||
pattern: &Pattern,
|
||||
pattern: PyRef<Pattern>,
|
||||
) -> Option<Match> {
|
||||
let mut state = State::new(
|
||||
string.borrow_value(),
|
||||
@@ -135,7 +136,7 @@ pub(crate) fn pymatch(
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(Match::new(&state, pattern.pattern.clone(), string.clone()))
|
||||
Some(Match::new(&state, pattern.clone().into_object(), string.clone()))
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -425,7 +426,7 @@ impl OpcodeDispatcher {
|
||||
}),
|
||||
SreOpcode::IN_LOC_IGNORE => once(|drive| {
|
||||
let skip = drive.peek_code(1) as usize;
|
||||
if drive.at_end() || !charset_loc_ignore(&drive.pattern()[1..], drive.peek_char()) {
|
||||
if drive.at_end() || !charset_loc_ignore(&drive.pattern()[2..], drive.peek_char()) {
|
||||
drive.ctx_mut().has_matched = Some(false);
|
||||
} else {
|
||||
drive.skip_code(skip + 1);
|
||||
@@ -561,7 +562,7 @@ fn general_op_literal<F: FnOnce(u32, char) -> bool>(drive: &mut StackDrive, f: F
|
||||
|
||||
fn general_op_in<F: FnOnce(char) -> char>(drive: &mut StackDrive, f: F) {
|
||||
let skip = drive.peek_code(1) as usize;
|
||||
if drive.at_end() || !charset(&drive.pattern()[1..], f(drive.peek_char())) {
|
||||
if drive.at_end() || !charset(&drive.pattern()[2..], f(drive.peek_char())) {
|
||||
drive.ctx_mut().has_matched = Some(false);
|
||||
} else {
|
||||
drive.skip_code(skip + 1);
|
||||
@@ -698,7 +699,28 @@ fn charset(set: &[u32], c: char) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn count(stack_drive: &StackDrive, maxcount: usize) -> usize {
|
||||
fn count(drive: &mut StackDrive, maxcount: usize) -> usize {
|
||||
let mut count = 0;
|
||||
let maxcount = std::cmp::min(maxcount, drive.remaining_chars());
|
||||
|
||||
let save_ctx = *drive.ctx();
|
||||
drive.skip_code(4);
|
||||
let reset_position = drive.ctx().code_position;
|
||||
|
||||
let mut dispatcher = OpcodeDispatcher::new();
|
||||
while count < maxcount {
|
||||
drive.ctx_mut().code_position = reset_position;
|
||||
dispatcher.dispatch(SreOpcode::try_from(drive.peek_code(0)).unwrap(), drive);
|
||||
if drive.ctx().has_matched == Some(false) {
|
||||
break;
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
*drive.ctx_mut() = save_ctx;
|
||||
count
|
||||
}
|
||||
|
||||
fn _count(stack_drive: &StackDrive, maxcount: usize) -> usize {
|
||||
let mut drive = WrapDrive::drive(*stack_drive.ctx(), stack_drive);
|
||||
let maxcount = std::cmp::min(maxcount, drive.remaining_chars());
|
||||
let end = drive.ctx().string_position + maxcount;
|
||||
|
||||
Reference in New Issue
Block a user