From 08238b1330d976736164b8bf0d30bd03a9d7a0e7 Mon Sep 17 00:00:00 2001 From: BLUELOVETH Date: Wed, 19 Jul 2023 15:35:17 +0800 Subject: [PATCH] ... --- include/pocketpy/common.h | 3 -- include/pocketpy/random.h | 63 +-------------------------- include/pocketpy/re.h | 89 +------------------------------------ src/random.cpp | 66 ++++++++++++++++++++++++++++ src/re.cpp | 92 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+), 151 deletions(-) create mode 100644 src/random.cpp create mode 100644 src/re.cpp diff --git a/include/pocketpy/common.h b/include/pocketpy/common.h index eca94256..2f8c4691 100644 --- a/include/pocketpy/common.h +++ b/include/pocketpy/common.h @@ -154,7 +154,4 @@ inline bool is_both_float(PyObject* a, PyObject* b) noexcept { inline PyObject* const PY_NULL = (PyObject*)0b000011; // tagged null inline PyObject* const PY_OP_CALL = (PyObject*)0b100011; inline PyObject* const PY_OP_YIELD = (PyObject*)0b110011; - -#define ADD_MODULE_PLACEHOLDER(name) namespace pkpy { inline void add_module_##name(void* vm) { (void)vm; } } - } // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/random.h b/include/pocketpy/random.h index f49feaf3..9824705d 100644 --- a/include/pocketpy/random.h +++ b/include/pocketpy/random.h @@ -1,68 +1,9 @@ #pragma once -#include "common.h" - -#if PK_MODULE_RANDOM - -#include - #include "cffi.h" -#include "_generated.h" namespace pkpy{ -struct Random{ - PY_CLASS(Random, random, Random) - std::mt19937 gen; +void add_module_random(VM* vm); - Random(){ - gen.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count()); - } - - static void _register(VM* vm, PyObject* mod, PyObject* type){ - vm->bind_default_constructor(type); - - vm->bind_method<1>(type, "seed", [](VM* vm, ArgsView args) { - Random& self = _CAST(Random&, args[0]); - self.gen.seed(CAST(i64, args[1])); - return vm->None; - }); - - vm->bind_method<2>(type, "randint", [](VM* vm, ArgsView args) { - Random& self = _CAST(Random&, args[0]); - i64 a = CAST(i64, args[1]); - i64 b = CAST(i64, args[2]); - std::uniform_int_distribution dis(a, b); - return VAR(dis(self.gen)); - }); - - vm->bind_method<0>(type, "random", [](VM* vm, ArgsView args) { - Random& self = _CAST(Random&, args[0]); - std::uniform_real_distribution dis(0.0, 1.0); - return VAR(dis(self.gen)); - }); - - vm->bind_method<2>(type, "uniform", [](VM* vm, ArgsView args) { - Random& self = _CAST(Random&, args[0]); - f64 a = CAST(f64, args[1]); - f64 b = CAST(f64, args[2]); - std::uniform_real_distribution dis(a, b); - return VAR(dis(self.gen)); - }); - } -}; - -inline void add_module_random(VM* vm){ - PyObject* mod = vm->new_module("random"); - Random::register_class(vm, mod); - CodeObject_ code = vm->compile(kPythonLibs["random"], "random.py", EXEC_MODE); - vm->_exec(code, mod); -} - -} // namespace pkpy - -#else - -ADD_MODULE_PLACEHOLDER(random) - -#endif \ No newline at end of file +} // namespace pkpy \ No newline at end of file diff --git a/include/pocketpy/re.h b/include/pocketpy/re.h index c0f4b882..1d97d434 100644 --- a/include/pocketpy/re.h +++ b/include/pocketpy/re.h @@ -1,94 +1,9 @@ #pragma once -#include "common.h" - -#if PK_MODULE_RE - #include "cffi.h" namespace pkpy{ -struct ReMatch { - PY_CLASS(ReMatch, re, Match) +void add_module_re(VM* vm); - i64 start; - i64 end; - std::cmatch m; - ReMatch(i64 start, i64 end, std::cmatch m) : start(start), end(end), m(m) {} - - static void _register(VM* vm, PyObject* mod, PyObject* type){ - vm->bind_notimplemented_constructor(type); - vm->bind_method<0>(type, "start", PK_LAMBDA(VAR(_CAST(ReMatch&, args[0]).start))); - vm->bind_method<0>(type, "end", PK_LAMBDA(VAR(_CAST(ReMatch&, args[0]).end))); - - vm->bind_method<0>(type, "span", [](VM* vm, ArgsView args) { - auto& self = _CAST(ReMatch&, args[0]); - return VAR(Tuple({VAR(self.start), VAR(self.end)})); - }); - - vm->bind_method<1>(type, "group", [](VM* vm, ArgsView args) { - auto& self = _CAST(ReMatch&, args[0]); - int index = CAST(int, args[1]); - index = vm->normalized_index(index, self.m.size()); - return VAR(self.m[index].str()); - }); - } -}; - -inline PyObject* _regex_search(const Str& pattern, const Str& string, bool from_start, VM* vm){ - std::regex re(pattern.begin(), pattern.end()); - std::cmatch m; - if(std::regex_search(string.begin(), string.end(), m, re)){ - if(from_start && m.position() != 0) return vm->None; - i64 start = string._byte_index_to_unicode(m.position()); - i64 end = string._byte_index_to_unicode(m.position() + m.length()); - return VAR_T(ReMatch, start, end, m); - } - return vm->None; -}; - -inline void add_module_re(VM* vm){ - PyObject* mod = vm->new_module("re"); - ReMatch::register_class(vm, mod); - - vm->bind_func<2>(mod, "match", [](VM* vm, ArgsView args) { - const Str& pattern = CAST(Str&, args[0]); - const Str& string = CAST(Str&, args[1]); - return _regex_search(pattern, string, true, vm); - }); - - vm->bind_func<2>(mod, "search", [](VM* vm, ArgsView args) { - const Str& pattern = CAST(Str&, args[0]); - const Str& string = CAST(Str&, args[1]); - return _regex_search(pattern, string, false, vm); - }); - - vm->bind_func<3>(mod, "sub", [](VM* vm, ArgsView args) { - const Str& pattern = CAST(Str&, args[0]); - const Str& repl = CAST(Str&, args[1]); - const Str& string = CAST(Str&, args[2]); - std::regex re(pattern.begin(), pattern.end()); - return VAR(std::regex_replace(string.str(), re, repl.str())); - }); - - vm->bind_func<2>(mod, "split", [](VM* vm, ArgsView args) { - const Str& pattern = CAST(Str&, args[0]); - const Str& string = CAST(Str&, args[1]); - std::regex re(pattern.begin(), pattern.end()); - std::cregex_token_iterator it(string.begin(), string.end(), re, -1); - std::cregex_token_iterator end; - List vec; - for(; it != end; ++it){ - vec.push_back(VAR(it->str())); - } - return VAR(vec); - }); -} - -} // namespace pkpy - -#else - -ADD_MODULE_PLACEHOLDER(re) - -#endif \ No newline at end of file +} // namespace pkpy \ No newline at end of file diff --git a/src/random.cpp b/src/random.cpp new file mode 100644 index 00000000..7165f256 --- /dev/null +++ b/src/random.cpp @@ -0,0 +1,66 @@ +#include "pocketpy/random.h" + +#if PK_MODULE_RANDOM + +#include +#include "pocketpy/_generated.h" + +namespace pkpy{ + +struct Random{ + PY_CLASS(Random, random, Random) + std::mt19937 gen; + + Random(){ + gen.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count()); + } + + static void _register(VM* vm, PyObject* mod, PyObject* type){ + vm->bind_default_constructor(type); + + vm->bind_method<1>(type, "seed", [](VM* vm, ArgsView args) { + Random& self = _CAST(Random&, args[0]); + self.gen.seed(CAST(i64, args[1])); + return vm->None; + }); + + vm->bind_method<2>(type, "randint", [](VM* vm, ArgsView args) { + Random& self = _CAST(Random&, args[0]); + i64 a = CAST(i64, args[1]); + i64 b = CAST(i64, args[2]); + std::uniform_int_distribution dis(a, b); + return VAR(dis(self.gen)); + }); + + vm->bind_method<0>(type, "random", [](VM* vm, ArgsView args) { + Random& self = _CAST(Random&, args[0]); + std::uniform_real_distribution dis(0.0, 1.0); + return VAR(dis(self.gen)); + }); + + vm->bind_method<2>(type, "uniform", [](VM* vm, ArgsView args) { + Random& self = _CAST(Random&, args[0]); + f64 a = CAST(f64, args[1]); + f64 b = CAST(f64, args[2]); + std::uniform_real_distribution dis(a, b); + return VAR(dis(self.gen)); + }); + } +}; + +void add_module_random(VM* vm){ + PyObject* mod = vm->new_module("random"); + Random::register_class(vm, mod); + CodeObject_ code = vm->compile(kPythonLibs["random"], "random.py", EXEC_MODE); + vm->_exec(code, mod); +} + +} // namespace pkpy + +#else + +namespace pkpy{ +void add_module_random(VM* vm){ (void)vm; } +} // namespace pkpy + +#endif \ No newline at end of file diff --git a/src/re.cpp b/src/re.cpp new file mode 100644 index 00000000..1831bff3 --- /dev/null +++ b/src/re.cpp @@ -0,0 +1,92 @@ +#include "pocketpy/re.h" + +#if PK_MODULE_RE + +namespace pkpy{ + +struct ReMatch { + PY_CLASS(ReMatch, re, Match) + + i64 start; + i64 end; + std::cmatch m; + ReMatch(i64 start, i64 end, std::cmatch m) : start(start), end(end), m(m) {} + + static void _register(VM* vm, PyObject* mod, PyObject* type){ + vm->bind_notimplemented_constructor(type); + vm->bind_method<0>(type, "start", PK_LAMBDA(VAR(_CAST(ReMatch&, args[0]).start))); + vm->bind_method<0>(type, "end", PK_LAMBDA(VAR(_CAST(ReMatch&, args[0]).end))); + + vm->bind_method<0>(type, "span", [](VM* vm, ArgsView args) { + auto& self = _CAST(ReMatch&, args[0]); + return VAR(Tuple({VAR(self.start), VAR(self.end)})); + }); + + vm->bind_method<1>(type, "group", [](VM* vm, ArgsView args) { + auto& self = _CAST(ReMatch&, args[0]); + int index = CAST(int, args[1]); + index = vm->normalized_index(index, self.m.size()); + return VAR(self.m[index].str()); + }); + } +}; + +static PyObject* _regex_search(const Str& pattern, const Str& string, bool from_start, VM* vm){ + std::regex re(pattern.begin(), pattern.end()); + std::cmatch m; + if(std::regex_search(string.begin(), string.end(), m, re)){ + if(from_start && m.position() != 0) return vm->None; + i64 start = string._byte_index_to_unicode(m.position()); + i64 end = string._byte_index_to_unicode(m.position() + m.length()); + return VAR_T(ReMatch, start, end, m); + } + return vm->None; +}; + +void add_module_re(VM* vm){ + PyObject* mod = vm->new_module("re"); + ReMatch::register_class(vm, mod); + + vm->bind_func<2>(mod, "match", [](VM* vm, ArgsView args) { + const Str& pattern = CAST(Str&, args[0]); + const Str& string = CAST(Str&, args[1]); + return _regex_search(pattern, string, true, vm); + }); + + vm->bind_func<2>(mod, "search", [](VM* vm, ArgsView args) { + const Str& pattern = CAST(Str&, args[0]); + const Str& string = CAST(Str&, args[1]); + return _regex_search(pattern, string, false, vm); + }); + + vm->bind_func<3>(mod, "sub", [](VM* vm, ArgsView args) { + const Str& pattern = CAST(Str&, args[0]); + const Str& repl = CAST(Str&, args[1]); + const Str& string = CAST(Str&, args[2]); + std::regex re(pattern.begin(), pattern.end()); + return VAR(std::regex_replace(string.str(), re, repl.str())); + }); + + vm->bind_func<2>(mod, "split", [](VM* vm, ArgsView args) { + const Str& pattern = CAST(Str&, args[0]); + const Str& string = CAST(Str&, args[1]); + std::regex re(pattern.begin(), pattern.end()); + std::cregex_token_iterator it(string.begin(), string.end(), re, -1); + std::cregex_token_iterator end; + List vec; + for(; it != end; ++it){ + vec.push_back(VAR(it->str())); + } + return VAR(vec); + }); +} + +} // namespace pkpy + +#else + +namespace pkpy{ +void add_module_re(VM* vm){ (void)vm; } +} // namespace pkpy + +#endif \ No newline at end of file