From 792c6a103e38a35cd21a36ba063d86d26a0f347c Mon Sep 17 00:00:00 2001 From: Adrian Wielgosik Date: Wed, 27 Mar 2019 18:56:42 +0100 Subject: [PATCH] Convert re to new style args --- vm/src/stdlib/re.rs | 184 ++++++++++++++------------------------------ 1 file changed, 56 insertions(+), 128 deletions(-) diff --git a/vm/src/stdlib/re.rs b/vm/src/stdlib/re.rs index 4dab1b0c3f..fee100bfeb 100644 --- a/vm/src/stdlib/re.rs +++ b/vm/src/stdlib/re.rs @@ -6,11 +6,9 @@ */ use regex::{Match, Regex}; -use crate::function::PyFuncArgs; -use crate::obj::objstr; use crate::obj::objstr::PyStringRef; use crate::obj::objtype::PyClassRef; -use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol}; +use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue}; use crate::vm::VirtualMachine; impl PyValue for Regex { @@ -19,73 +17,39 @@ impl PyValue for Regex { } } -/// Create the python `re` module with all its members. -pub fn make_module(ctx: &PyContext) -> PyObjectRef { - let match_type = py_class!(ctx, "Match", ctx.object(), { - "start" => ctx.new_rustfunc(match_start), - "end" => ctx.new_rustfunc(match_end) - }); - - let pattern_type = py_class!(ctx, "Pattern", ctx.object(), { - "match" => ctx.new_rustfunc(pattern_match), - "search" => ctx.new_rustfunc(pattern_search) - }); +/// Inner data for a match object. +#[derive(Debug)] +struct PyMatch { + start: usize, + end: usize, +} - py_module!(ctx, "re", { - "compile" => ctx.new_rustfunc(re_compile), - "Match" => match_type, - "match" => ctx.new_rustfunc(re_match), - "Pattern" => pattern_type, - "search" => ctx.new_rustfunc(re_search) - }) +impl PyValue for PyMatch { + fn class(vm: &VirtualMachine) -> PyClassRef { + vm.class("re", "Match") + } } -/// Implement re.match -/// See also: -/// https://docs.python.org/3/library/re.html#re.match -fn re_match(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [ - (pattern, Some(vm.ctx.str_type())), - (string, Some(vm.ctx.str_type())) - ] - ); - let pattern_str = objstr::get_value(&pattern); - let regex = make_regex(vm, &pattern_str)?; - let search_text = objstr::get_value(string); - - do_match(vm, ®ex, search_text) +type PyRegexRef = PyRef; +type PyMatchRef = PyRef; + +fn re_match(pattern: PyStringRef, string: PyStringRef, vm: &VirtualMachine) -> PyResult { + let regex = make_regex(vm, &pattern.value)?; + do_match(vm, ®ex, &string.value) } -/// Implement re.search -/// See also: -/// https://docs.python.org/3/library/re.html#re.search -fn re_search(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [ - (pattern, Some(vm.ctx.str_type())), - (string, Some(vm.ctx.str_type())) - ] - ); - - let pattern_str = objstr::get_value(&pattern); - let regex = make_regex(vm, &pattern_str)?; - let search_text = objstr::get_value(string); - - do_search(vm, ®ex, search_text) +fn re_search(pattern: PyStringRef, string: PyStringRef, vm: &VirtualMachine) -> PyResult { + let regex = make_regex(vm, &pattern.value)?; + do_search(vm, ®ex, &string.value) } -fn do_match(vm: &VirtualMachine, regex: &Regex, search_text: String) -> PyResult { +fn do_match(vm: &VirtualMachine, regex: &Regex, search_text: &str) -> PyResult { // TODO: implement match! do_search(vm, regex, search_text) } -fn do_search(vm: &VirtualMachine, regex: &Regex, search_text: String) -> PyResult { - match regex.find(&search_text) { +fn do_search(vm: &VirtualMachine, regex: &Regex, search_text: &str) -> PyResult { + match regex.find(search_text) { None => Ok(vm.get_none()), Some(result) => create_match(vm, &result), } @@ -98,19 +62,6 @@ fn make_regex(vm: &VirtualMachine, pattern: &str) -> PyResult { } } -/// Inner data for a match object. -#[derive(Debug)] -struct PyMatch { - start: usize, - end: usize, -} - -impl PyValue for PyMatch { - fn class(vm: &VirtualMachine) -> PyClassRef { - vm.class("re", "Match") - } -} - /// Take a found regular expression and convert it to proper match object. fn create_match(vm: &VirtualMachine, match_value: &Match) -> PyResult { // let mo = vm.invoke(match_class, PyFuncArgs::default())?; @@ -124,68 +75,45 @@ fn create_match(vm: &VirtualMachine, match_value: &Match) -> PyResult { .into_object()) } -/// Compile a regular expression into a Pattern object. -/// See also: -/// https://docs.python.org/3/library/re.html#re.compile -fn re_compile(pattern: PyStringRef, vm: &VirtualMachine) -> PyResult> { - let regex = make_regex(vm, &pattern.value)?; - - Ok(regex.into_ref(vm)) +fn re_compile(pattern: PyStringRef, vm: &VirtualMachine) -> PyResult { + make_regex(vm, &pattern.value) } -fn pattern_match(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [(zelf, None), (text, Some(vm.ctx.str_type()))] - ); - - let regex = get_regex(zelf); - let search_text = objstr::get_value(text); - do_match(vm, ®ex, search_text) -} - -fn pattern_search(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [(zelf, None), (text, Some(vm.ctx.str_type()))] - ); - - let regex = get_regex(zelf); - let search_text = objstr::get_value(text); - do_search(vm, ®ex, search_text) +impl PyRegexRef { + fn match_(self, text: PyStringRef, vm: &VirtualMachine) -> PyResult { + do_match(vm, &self, &text.value) + } + fn search(self, text: PyStringRef, vm: &VirtualMachine) -> PyResult { + do_search(vm, &self, &text.value) + } } -/// Returns start of match -/// see: https://docs.python.org/3/library/re.html#re.Match.start -fn match_start(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!(vm, args, required = [(zelf, None)]); - // TODO: implement groups - let m = get_match(zelf); - Ok(vm.new_int(m.start)) +impl PyMatchRef { + fn start(self, _vm: &VirtualMachine) -> usize { + self.start + } + fn end(self, _vm: &VirtualMachine) -> usize { + self.end + } } -fn match_end(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!(vm, args, required = [(zelf, None)]); - // TODO: implement groups - let m = get_match(zelf); - Ok(vm.new_int(m.end)) -} +/// Create the python `re` module with all its members. +pub fn make_module(ctx: &PyContext) -> PyObjectRef { + let match_type = py_class!(ctx, "Match", ctx.object(), { + "start" => ctx.new_rustfunc(PyMatchRef::start), + "end" => ctx.new_rustfunc(PyMatchRef::end) + }); -/// Retrieve inner rust regex from python object: -fn get_regex(obj: &PyObjectRef) -> &Regex { - // TODO: Regex shouldn't be stored in payload directly, create newtype wrapper - if let Some(regex) = obj.payload::() { - return regex; - } - panic!("Inner error getting regex {:?}", obj); -} + let pattern_type = py_class!(ctx, "Pattern", ctx.object(), { + "match" => ctx.new_rustfunc(PyRegexRef::match_), + "search" => ctx.new_rustfunc(PyRegexRef::search) + }); -/// Retrieve inner rust match from python object: -fn get_match(obj: &PyObjectRef) -> &PyMatch { - if let Some(value) = obj.payload::() { - return value; - } - panic!("Inner error getting match {:?}", obj); + py_module!(ctx, "re", { + "compile" => ctx.new_rustfunc(re_compile), + "Match" => match_type, + "match" => ctx.new_rustfunc(re_match), + "Pattern" => pattern_type, + "search" => ctx.new_rustfunc(re_search) + }) }