Merge pull request #1 from qingshi163/master

add tests; fix OpAssert panic
This commit is contained in:
Noah
2021-02-01 14:20:39 -06:00
committed by GitHub
3 changed files with 29 additions and 7 deletions

View File

@@ -369,20 +369,18 @@ fn once<F: FnOnce(&mut StackDrive)>(f: F) -> Box<OpOnce<F>> {
Box::new(OpOnce { f: Some(f) })
}
// F1 F2 are same identical, but workaround for closure
struct OpTwice<F1, F2> {
f1: Option<F1>,
f2: Option<F2>,
}
impl<F1, F2> OpcodeExecutor for OpTwice<F1, F2>
where
F1: FnOnce(&mut StackDrive),
F1: FnOnce(&mut StackDrive) -> Option<()>,
F2: FnOnce(&mut StackDrive),
{
fn next(&mut self, drive: &mut StackDrive) -> Option<()> {
if let Some(f1) = self.f1.take() {
f1(drive);
Some(())
f1(drive)
} else if let Some(f2) = self.f2.take() {
f2(drive);
None
@@ -393,7 +391,7 @@ where
}
fn twice<F1, F2>(f1: F1, f2: F2) -> Box<OpTwice<F1, F2>>
where
F1: FnOnce(&mut StackDrive),
F1: FnOnce(&mut StackDrive) -> Option<()>,
F2: FnOnce(&mut StackDrive),
{
Box::new(OpTwice {
@@ -483,11 +481,12 @@ impl OpcodeDispatcher {
let passed = drive.ctx().string_position - drive.state.start;
if passed < back {
drive.ctx_mut().has_matched = Some(false);
return;
return None;
}
drive.state.string_position = drive.ctx().string_position - back;
drive.push_new_context(3);
drive.state.context_stack.last_mut().unwrap().toplevel = false;
Some(())
},
|drive| {
let child_ctx = drive.state.popped_context.unwrap();
@@ -504,11 +503,12 @@ impl OpcodeDispatcher {
let passed = drive.ctx().string_position - drive.state.start;
if passed < back {
drive.skip_code(drive.peek_code(1) as usize + 1);
return;
return None;
}
drive.state.string_position = drive.ctx().string_position - back;
drive.push_new_context(3);
drive.state.context_stack.last_mut().unwrap().toplevel = false;
Some(())
},
|drive| {
let child_ctx = drive.state.popped_context.unwrap();
@@ -598,6 +598,7 @@ impl OpcodeDispatcher {
drive.state.string_position = drive.ctx().string_position;
// execute UNTIL operator
drive.push_new_context(drive.peek_code(1) as usize + 1);
Some(())
},
|drive| {
drive.state.repeat_stack.pop();

View File

@@ -1,5 +1,7 @@
pub mod constants;
pub mod engine;
#[cfg(test)]
mod tests;
pub const CODESIZE: usize = 4;

19
src/tests.rs Normal file
View File

@@ -0,0 +1,19 @@
use engine::{State, StrDrive};
use super::*;
#[test]
fn test_2427() {
let str_drive = StrDrive::Str("x");
// r'(?<!\.)x\b'
let code: Vec<u32> = vec![15, 4, 0, 1, 1, 5, 5, 1, 17, 46, 1, 17, 120, 6, 10, 1];
let mut state = State::new(
str_drive,
0,
std::usize::MAX,
constants::SreFlag::UNICODE,
&code,
);
state = state.pymatch();
assert!(state.has_matched == Some(true));
}