From bccb6f3bf55ed0f1b32a1554d006873dff402a8d Mon Sep 17 00:00:00 2001 From: Windel Bouwman Date: Sun, 14 Oct 2018 10:59:00 +0200 Subject: [PATCH] Add draft re module --- Cargo.lock | 1 + tests/snippets/test_re.py | 8 +++++ vm/Cargo.toml | 1 + vm/src/stdlib/mod.rs | 2 ++ vm/src/stdlib/re.rs | 61 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+) create mode 100644 tests/snippets/test_re.py create mode 100644 vm/src/stdlib/re.rs diff --git a/Cargo.lock b/Cargo.lock index 98ab04562..ff07d7cae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -474,6 +474,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustpython_parser 0.0.1", "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/tests/snippets/test_re.py b/tests/snippets/test_re.py new file mode 100644 index 000000000..24a2ee3b4 --- /dev/null +++ b/tests/snippets/test_re.py @@ -0,0 +1,8 @@ + +import re + +haystack = "Hello world" +needle = 'ello' + +print(re.search(needle, haystack)) + diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 74106dad5..5897d829e 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -11,3 +11,4 @@ serde = "1.0.66" serde_derive = "1.0.66" serde_json = "1.0.26" byteorder = "1.2.6" +regex = "1" diff --git a/vm/src/stdlib/mod.rs b/vm/src/stdlib/mod.rs index 99b392d90..d1210cc99 100644 --- a/vm/src/stdlib/mod.rs +++ b/vm/src/stdlib/mod.rs @@ -4,6 +4,7 @@ mod json; mod keyword; mod math; mod pystruct; +mod re; use std::collections::HashMap; use super::pyobject::{PyContext, PyObjectRef}; @@ -17,6 +18,7 @@ pub fn get_module_inits() -> HashMap { modules.insert("ast".to_string(), ast::mk_module as StdlibInitFunc); modules.insert("keyword".to_string(), keyword::mk_module as StdlibInitFunc); modules.insert("math".to_string(), math::mk_module as StdlibInitFunc); + modules.insert("re".to_string(), re::mk_module as StdlibInitFunc); modules.insert("struct".to_string(), pystruct::mk_module as StdlibInitFunc); modules } diff --git a/vm/src/stdlib/re.rs b/vm/src/stdlib/re.rs new file mode 100644 index 000000000..3a53770c6 --- /dev/null +++ b/vm/src/stdlib/re.rs @@ -0,0 +1,61 @@ +/* + * Regular expressions. + * + * This module fits the python re interface onto the rust regular expression + * system. + */ + +extern crate regex; +use self::regex::Regex; + +use super::super::obj::{objstr, objtype}; +use super::super::pyobject::{ + DictProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol, +}; +use super::super::VirtualMachine; + +fn re_match(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { + // TODO: + error!("TODO: implement match"); + re_search(vm, args) +} + +fn re_search(vm: &mut 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 search_text = objstr::get_value(&string); + + match Regex::new(&pattern_str) { + Ok(regex) => { + // Now use regex to search: + match regex.find(&search_text) { + None => Ok(vm.get_none()), + Some(result) => { + // Return match object: + // TODO: implement match object + // TODO: how to refer to match object defined in this + // module? + Ok(vm.ctx.new_str(result.as_str().to_string())) + } + } + } + Err(err) => Err(vm.new_value_error(format!("Error in regex: {:?}", err))), + } +} + +pub fn mk_module(ctx: &PyContext) -> PyObjectRef { + let py_mod = ctx.new_module(&"re".to_string(), ctx.new_scope(None)); + let match_type = ctx.new_class(&"Match".to_string(), ctx.object()); + py_mod.set_item("Match", match_type); + py_mod.set_item("match", ctx.new_rustfunc(re_match)); + py_mod.set_item("search", ctx.new_rustfunc(re_search)); + py_mod +}