blueloveTH 3 лет назад
Родитель
Сommit
d4401bfa98
6 измененных файлов с 33 добавлено и 34 удалено
  1. 5 0
      src/__stl__.h
  2. 1 3
      src/obj.h
  3. 20 26
      src/pocketpy.h
  4. 3 3
      src/str.h
  5. 1 1
      src/vm.h
  6. 3 1
      tests/_re.py

+ 5 - 0
src/__stl__.h

@@ -20,6 +20,7 @@
 #include <queue>
 #include <iomanip>
 #include <memory>
+// #include <functional>
 
 #include <atomic>
 #include <iostream>
@@ -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

+ 1 - 3
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<PyVar(VM*, const pkpy::ArgList&)> _CppFunc;
 typedef pkpy::shared_ptr<CodeObject> _Code;
 
 struct Function {

+ 20 - 26
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) {

+ 3 - 3
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 {

+ 1 - 1
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);
             }

+ 3 - 1
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']
+assert re.split(',','123,456,789,10,') == ['123', '456', '789', '10']
+
+assert re.match('1','1') is not None