diff --git a/src/__stl__.h b/src/__stl__.h index 5f0e7436..46063e37 100644 --- a/src/__stl__.h +++ b/src/__stl__.h @@ -20,6 +20,7 @@ #include #include #include +// #include #include #include @@ -38,4 +39,8 @@ #define PK_VERSION "0.8.0" +typedef int64_t i64; +typedef double f64; +#define DUMMY_VAL (i64)0 + //#define PKPY_NO_INDEX_CHECK \ No newline at end of file diff --git a/src/obj.h b/src/obj.h index e061de70..867d94af 100644 --- a/src/obj.h +++ b/src/obj.h @@ -2,15 +2,13 @@ #include "safestl.h" -typedef int64_t i64; -typedef double f64; - struct CodeObject; struct BaseRef; class VM; class Frame; typedef PyVar (*_CppFunc)(VM*, const pkpy::ArgList&); +//typedef std::function _CppFunc; typedef pkpy::shared_ptr _Code; struct Function { diff --git a/src/pocketpy.h b/src/pocketpy.h index d06d88ba..44336733 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -696,26 +696,23 @@ void __addModuleMath(VM* vm){ }); } + +struct ReMatch { + i64 start; + i64 end; + std::smatch m; + ReMatch(i64 start, i64 end, std::smatch m) : start(start), end(end), m(m) {} +}; + + PyVar __regex_search(const _Str& pattern, const _Str& string, bool fromStart, VM* vm){ std::regex re(pattern); std::smatch m; if(std::regex_search(string, m, re)){ - if(fromStart && m.position() != 0){ - return vm->None; - } - PyVar ret = vm->new_object(vm->_userTypes["re.Match"], (i64)1); - vm->setattr(ret, "_start", vm->PyInt( - string.__to_u8_index(m.position()) - )); - vm->setattr(ret, "_end", vm->PyInt( - string.__to_u8_index(m.position() + m.length()) - )); - PyVarList groups(m.size()); - for(size_t i = 0; i < m.size(); ++i){ - groups[i] = vm->PyStr(m[i].str()); - } - vm->setattr(ret, "_groups", vm->PyTuple(groups)); - return ret; + if(fromStart && m.position() != 0) return vm->None; + i64 start = string.__to_u8_index(m.position()); + i64 end = string.__to_u8_index(m.position() + m.length()); + return vm->new_object(vm->_userTypes["re.Match"], ReMatch(start, end, m)); } return vm->None; }; @@ -723,32 +720,29 @@ PyVar __regex_search(const _Str& pattern, const _Str& string, bool fromStart, VM void __addModuleRe(VM* vm){ PyVar mod = vm->newModule("re"); PyVar _tp_match = vm->new_user_type_object(mod, "Match", vm->_tp_object); - vm->bindMethod("re.Match", "start", [](VM* vm, const pkpy::ArgList& args) { vm->check_args_size(args, 1, true); - PyVar self = args[0]; - return vm->getattr(self, "_start"); + return vm->PyInt(UNION_GET(ReMatch, args[0]).start); }); vm->bindMethod("re.Match", "end", [](VM* vm, const pkpy::ArgList& args) { vm->check_args_size(args, 1, true); - PyVar self = args[0]; - return vm->getattr(self, "_end"); + return vm->PyInt(UNION_GET(ReMatch, args[0]).end); }); vm->bindMethod("re.Match", "span", [](VM* vm, const pkpy::ArgList& args) { vm->check_args_size(args, 1, true); - PyVar self = args[0]; - PyVarList vec = { vm->getattr(self, "_start"), vm->getattr(self, "_end") }; + auto& m = UNION_GET(ReMatch, args[0]); + PyVarList vec = { vm->PyInt(m.start), vm->PyInt(m.end) }; return vm->PyTuple(vec); }); vm->bindMethod("re.Match", "group", [](VM* vm, const pkpy::ArgList& args) { vm->check_args_size(args, 2, true); + auto& m = UNION_GET(ReMatch, args[0]); int index = (int)vm->PyInt_AS_C(args[1]); - const auto& vec = vm->PyTuple_AS_C(vm->getattr(args[0], "_groups")); - vm->normalizedIndex(index, vec.size()); - return vec[index]; + vm->normalizedIndex(index, m.m.size()); + return vm->PyStr(m.m[index].str()); }); vm->bindFunc(mod, "match", [](VM* vm, const pkpy::ArgList& args) { diff --git a/src/str.h b/src/str.h index e77574ae..3c6c4294 100644 --- a/src/str.h +++ b/src/str.h @@ -52,11 +52,11 @@ public: return _hash; } - int __to_u8_index(int64_t index) const{ + i64 __to_u8_index(i64 index) const{ utf8_lazy_init(); auto p = std::lower_bound(_u8_index->begin(), _u8_index->end(), index); - if(*p != index) UNREACHABLE(); - return (int)(p - _u8_index->begin()); + if(p != _u8_index->end() && *p != index) UNREACHABLE(); + return p - _u8_index->begin(); } int u8_length() const { diff --git a/src/vm.h b/src/vm.h index ce21d61c..64e63db3 100644 --- a/src/vm.h +++ b/src/vm.h @@ -440,7 +440,7 @@ public: if(it != _callable->attribs.end()){ obj = call(it->second, args, kwargs, false); }else{ - obj = new_object(_callable, (i64)-1); + obj = new_object(_callable, DUMMY_VAL); PyVarOrNull init_fn = getattr(obj, __init__, false); if (init_fn != nullptr) call(init_fn, args, kwargs, false); } diff --git a/tests/_re.py b/tests/_re.py index 5ea32032..247d5d37 100644 --- a/tests/_re.py +++ b/tests/_re.py @@ -14,4 +14,6 @@ assert re.split('测试','测试123测试12321测试') == ['', '123', '12321'] assert re.split(',','123,456,789,10') == ['123', '456', '789', '10'] assert re.split(',',',123,456,789,10') == ['', '123', '456', '789', '10'] -assert re.split(',','123,456,789,10,') == ['123', '456', '789', '10'] \ No newline at end of file +assert re.split(',','123,456,789,10,') == ['123', '456', '789', '10'] + +assert re.match('1','1') is not None \ No newline at end of file