mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
impl OpMinUntil
This commit is contained in:
59
interp.rs
59
interp.rs
@@ -478,11 +478,9 @@ impl OpcodeDispatcher {
|
||||
drive.skip_code(2);
|
||||
}),
|
||||
SreOpcode::MAX_UNTIL => Box::new(OpMaxUntil::default()),
|
||||
SreOpcode::MIN_UNTIL => unimplemented(),
|
||||
SreOpcode::RANGE => unimplemented(),
|
||||
SreOpcode::REPEAT => unimplemented(),
|
||||
SreOpcode::MIN_UNTIL => Box::new(OpMinUntil::default()),
|
||||
SreOpcode::REPEAT => Box::new(OpRepeat::default()),
|
||||
SreOpcode::REPEAT_ONE => unimplemented(),
|
||||
SreOpcode::SUBPATTERN => unimplemented(),
|
||||
SreOpcode::MIN_REPEAT_ONE => Box::new(OpMinRepeatOne::default()),
|
||||
SreOpcode::GROUPREF => once(|drive| general_op_groupref(drive, |x| x)),
|
||||
SreOpcode::GROUPREF_IGNORE => once(|drive| general_op_groupref(drive, lower_ascii)),
|
||||
@@ -501,9 +499,8 @@ impl OpcodeDispatcher {
|
||||
_ => drive.skip_code(drive.peek_code(2) as usize + 1),
|
||||
}
|
||||
}),
|
||||
SreOpcode::RANGE_UNI_IGNORE => unimplemented(),
|
||||
_ => {
|
||||
// TODO
|
||||
// TODO error expcetion
|
||||
unreachable!("unexpected opcode")
|
||||
}
|
||||
}
|
||||
@@ -1172,8 +1169,52 @@ impl OpcodeExecutor for OpMinUntil {
|
||||
}
|
||||
};
|
||||
self.count = repeat.count + 1;
|
||||
|
||||
if self.count < repeat.mincount as isize {
|
||||
// not enough matches
|
||||
repeat.count = self.count;
|
||||
self.child_ctx_id = drive.push_new_context(4);
|
||||
self.jump_id = 1;
|
||||
return Some(());
|
||||
}
|
||||
|
||||
// see if the tail matches
|
||||
drive.state.marks_push();
|
||||
self.child_ctx_id = drive.push_new_context(1);
|
||||
self.jump_id = 2;
|
||||
Some(())
|
||||
}
|
||||
1 => {
|
||||
let child_ctx = &drive.state.context_stack[self.child_ctx_id];
|
||||
drive.ctx_mut().has_matched = child_ctx.has_matched;
|
||||
if drive.ctx().has_matched != Some(true) {
|
||||
drive.state.string_position = drive.ctx().string_position;
|
||||
let repeat = drive.state.repeat_stack.last_mut().unwrap();
|
||||
repeat.count = self.count - 1;
|
||||
}
|
||||
None
|
||||
}
|
||||
2 => {
|
||||
let child_ctx = &drive.state.context_stack[self.child_ctx_id];
|
||||
if child_ctx.has_matched == Some(true) {
|
||||
drive.state.repeat_stack.pop();
|
||||
drive.ctx_mut().has_matched = Some(true);
|
||||
return None;
|
||||
}
|
||||
drive.state.string_position = drive.ctx().string_position;
|
||||
drive.state.marks_pop();
|
||||
|
||||
// match more until tail matches
|
||||
let repeat = drive.state.repeat_stack.last_mut().unwrap();
|
||||
if self.count >= repeat.maxcount as isize && repeat.maxcount != MAXREPEAT {
|
||||
drive.ctx_mut().has_matched = Some(false);
|
||||
return None;
|
||||
}
|
||||
repeat.count = self.count;
|
||||
self.child_ctx_id = drive.push_new_context(4);
|
||||
self.jump_id = 1;
|
||||
Some(())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@@ -1248,9 +1289,9 @@ impl OpcodeExecutor for OpRepeat {
|
||||
match self.jump_id {
|
||||
0 => {
|
||||
let repeat = RepeatContext {
|
||||
skip: drive.peek_code(1),
|
||||
mincount: drive.peek_code(2),
|
||||
maxcount: drive.peek_code(3),
|
||||
skip: drive.peek_code(1) as usize,
|
||||
mincount: drive.peek_code(2) as usize,
|
||||
maxcount: drive.peek_code(3) as usize,
|
||||
count: -1,
|
||||
last_position: -1,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user