This commit is contained in:
blueloveTH 2023-01-27 05:52:19 +08:00
parent 5c2352fa90
commit d4401bfa98
6 changed files with 33 additions and 34 deletions

View File

@ -20,6 +20,7 @@
#include <queue> #include <queue>
#include <iomanip> #include <iomanip>
#include <memory> #include <memory>
// #include <functional>
#include <atomic> #include <atomic>
#include <iostream> #include <iostream>
@ -38,4 +39,8 @@
#define PK_VERSION "0.8.0" #define PK_VERSION "0.8.0"
typedef int64_t i64;
typedef double f64;
#define DUMMY_VAL (i64)0
//#define PKPY_NO_INDEX_CHECK //#define PKPY_NO_INDEX_CHECK

View File

@ -2,15 +2,13 @@
#include "safestl.h" #include "safestl.h"
typedef int64_t i64;
typedef double f64;
struct CodeObject; struct CodeObject;
struct BaseRef; struct BaseRef;
class VM; class VM;
class Frame; class Frame;
typedef PyVar (*_CppFunc)(VM*, const pkpy::ArgList&); typedef PyVar (*_CppFunc)(VM*, const pkpy::ArgList&);
//typedef std::function<PyVar(VM*, const pkpy::ArgList&)> _CppFunc;
typedef pkpy::shared_ptr<CodeObject> _Code; typedef pkpy::shared_ptr<CodeObject> _Code;
struct Function { struct Function {

View File

@ -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){ PyVar __regex_search(const _Str& pattern, const _Str& string, bool fromStart, VM* vm){
std::regex re(pattern); std::regex re(pattern);
std::smatch m; std::smatch m;
if(std::regex_search(string, m, re)){ if(std::regex_search(string, m, re)){
if(fromStart && m.position() != 0){ if(fromStart && m.position() != 0) return vm->None;
return vm->None; i64 start = string.__to_u8_index(m.position());
} i64 end = string.__to_u8_index(m.position() + m.length());
PyVar ret = vm->new_object(vm->_userTypes["re.Match"], (i64)1); return vm->new_object(vm->_userTypes["re.Match"], ReMatch(start, end, m));
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;
} }
return vm->None; return vm->None;
}; };
@ -723,32 +720,29 @@ PyVar __regex_search(const _Str& pattern, const _Str& string, bool fromStart, VM
void __addModuleRe(VM* vm){ void __addModuleRe(VM* vm){
PyVar mod = vm->newModule("re"); PyVar mod = vm->newModule("re");
PyVar _tp_match = vm->new_user_type_object(mod, "Match", vm->_tp_object); 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->bindMethod("re.Match", "start", [](VM* vm, const pkpy::ArgList& args) {
vm->check_args_size(args, 1, true); vm->check_args_size(args, 1, true);
PyVar self = args[0]; return vm->PyInt(UNION_GET(ReMatch, args[0]).start);
return vm->getattr(self, "_start");
}); });
vm->bindMethod("re.Match", "end", [](VM* vm, const pkpy::ArgList& args) { vm->bindMethod("re.Match", "end", [](VM* vm, const pkpy::ArgList& args) {
vm->check_args_size(args, 1, true); vm->check_args_size(args, 1, true);
PyVar self = args[0]; return vm->PyInt(UNION_GET(ReMatch, args[0]).end);
return vm->getattr(self, "_end");
}); });
vm->bindMethod("re.Match", "span", [](VM* vm, const pkpy::ArgList& args) { vm->bindMethod("re.Match", "span", [](VM* vm, const pkpy::ArgList& args) {
vm->check_args_size(args, 1, true); vm->check_args_size(args, 1, true);
PyVar self = args[0]; auto& m = UNION_GET(ReMatch, args[0]);
PyVarList vec = { vm->getattr(self, "_start"), vm->getattr(self, "_end") }; PyVarList vec = { vm->PyInt(m.start), vm->PyInt(m.end) };
return vm->PyTuple(vec); return vm->PyTuple(vec);
}); });
vm->bindMethod("re.Match", "group", [](VM* vm, const pkpy::ArgList& args) { vm->bindMethod("re.Match", "group", [](VM* vm, const pkpy::ArgList& args) {
vm->check_args_size(args, 2, true); vm->check_args_size(args, 2, true);
auto& m = UNION_GET(ReMatch, args[0]);
int index = (int)vm->PyInt_AS_C(args[1]); int index = (int)vm->PyInt_AS_C(args[1]);
const auto& vec = vm->PyTuple_AS_C(vm->getattr(args[0], "_groups")); vm->normalizedIndex(index, m.m.size());
vm->normalizedIndex(index, vec.size()); return vm->PyStr(m.m[index].str());
return vec[index];
}); });
vm->bindFunc(mod, "match", [](VM* vm, const pkpy::ArgList& args) { vm->bindFunc(mod, "match", [](VM* vm, const pkpy::ArgList& args) {

View File

@ -52,11 +52,11 @@ public:
return _hash; return _hash;
} }
int __to_u8_index(int64_t index) const{ i64 __to_u8_index(i64 index) const{
utf8_lazy_init(); utf8_lazy_init();
auto p = std::lower_bound(_u8_index->begin(), _u8_index->end(), index); auto p = std::lower_bound(_u8_index->begin(), _u8_index->end(), index);
if(*p != index) UNREACHABLE(); if(p != _u8_index->end() && *p != index) UNREACHABLE();
return (int)(p - _u8_index->begin()); return p - _u8_index->begin();
} }
int u8_length() const { int u8_length() const {

View File

@ -440,7 +440,7 @@ public:
if(it != _callable->attribs.end()){ if(it != _callable->attribs.end()){
obj = call(it->second, args, kwargs, false); obj = call(it->second, args, kwargs, false);
}else{ }else{
obj = new_object(_callable, (i64)-1); obj = new_object(_callable, DUMMY_VAL);
PyVarOrNull init_fn = getattr(obj, __init__, false); PyVarOrNull init_fn = getattr(obj, __init__, false);
if (init_fn != nullptr) call(init_fn, args, kwargs, false); if (init_fn != nullptr) call(init_fn, args, kwargs, false);
} }

View File

@ -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.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