This commit is contained in:
blueloveTH 2023-06-10 13:16:35 +08:00
parent d0453ab15f
commit 7669c67c38
6 changed files with 110 additions and 99 deletions

View File

@ -37,8 +37,7 @@ int main(){
pkpy_vm_exec(vm, "print(sum(a))"); pkpy_vm_exec(vm, "print(sum(a))");
// 释放资源 // 释放资源
pkpy_delete(result); pkpy_delete_vm(vm);
pkpy_delete(vm);
return 0; return 0;
} }
``` ```

View File

@ -9,7 +9,7 @@ pipeline = [
["common.h", "memory.h", "vector.h", "str.h", "tuplelist.h", "namedict.h", "error.h", "lexer.h"], ["common.h", "memory.h", "vector.h", "str.h", "tuplelist.h", "namedict.h", "error.h", "lexer.h"],
["obj.h", "dict.h", "codeobject.h", "frame.h"], ["obj.h", "dict.h", "codeobject.h", "frame.h"],
["gc.h", "vm.h", "ceval.h", "expr.h", "compiler.h", "repl.h"], ["gc.h", "vm.h", "ceval.h", "expr.h", "compiler.h", "repl.h"],
["_generated.h", "cffi.h", "iter.h", "base64.h", "linalg.h", "easing.h", "requests.h", "io.h"], ["_generated.h", "cffi.h", "iter.h", "base64.h", "re.h", "linalg.h", "easing.h", "requests.h", "io.h"],
["export.h", "pocketpy.h"] ["export.h", "pocketpy.h"]
] ]

View File

@ -20,11 +20,14 @@ Run a given source on a virtual machine.
Advanced version of `pkpy_vm_exec`. Advanced version of `pkpy_vm_exec`.
#### `void pkpy_delete(void* p)` #### `void pkpy_free(void* p)`
Delete a pointer allocated by `pkpy_xxx_xxx`. Free a pointer via `free`.
It can be `VM*`, `REPL*`, `char*`, etc.
!!! #### `void pkpy_delete_vm(VM* vm)`
If the pointer is not allocated by `pkpy_xxx_xxx`, the behavior is undefined.
!!! Delete a virtual machine.
#### `void pkpy_delete_repl(REPL* repl)`
Delete a REPL.

View File

@ -22,7 +22,7 @@ int main(int argc, char** argv){
if(eof) break; if(eof) break;
need_more_lines = pkpy_repl_input(repl, line.c_str()); need_more_lines = pkpy_repl_input(repl, line.c_str());
} }
pkpy_delete(vm); pkpy_delete_vm(vm);
return 0; return 0;
} }
@ -49,7 +49,7 @@ int main(int argc, char** argv){
pkpy::PyObject* ret = nullptr; pkpy::PyObject* ret = nullptr;
ret = vm->exec(src.c_str(), filepath.filename().string(), pkpy::EXEC_MODE); ret = vm->exec(src.c_str(), filepath.filename().string(), pkpy::EXEC_MODE);
pkpy_delete(vm); pkpy_delete_vm(vm);
return ret != nullptr ? 0 : 1; return ret != nullptr ? 0 : 1;
} }

View File

@ -14,6 +14,7 @@
#include "_generated.h" #include "_generated.h"
#include "export.h" #include "export.h"
#include "vm.h" #include "vm.h"
#include "re.h"
namespace pkpy { namespace pkpy {
@ -1263,83 +1264,6 @@ inline void add_module_dis(VM* vm){
}); });
} }
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<ReMatch>(type);
vm->bind_method<0>(type, "start", CPP_LAMBDA(VAR(_CAST(ReMatch&, args[0]).start)));
vm->bind_method<0>(type, "end", CPP_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);
});
}
struct Random{ struct Random{
PY_CLASS(Random, random, Random) PY_CLASS(Random, random, Random)
std::mt19937 gen; std::mt19937 gen;
@ -1469,17 +1393,10 @@ inline void VM::post_init(){
} // namespace pkpy } // namespace pkpy
/*************************GLOBAL NAMESPACE*************************/ /*************************GLOBAL NAMESPACE*************************/
static std::map<void*, void(*)(void*)> _pk_deleter_map;
extern "C" { extern "C" {
PK_LEGACY_EXPORT PK_LEGACY_EXPORT
void pkpy_delete(void* p){ void pkpy_free(void* p){
auto it = _pk_deleter_map.find(p); free(p);
if(it != _pk_deleter_map.end()){
it->second(p);
}else{
free(p);
}
} }
PK_LEGACY_EXPORT PK_LEGACY_EXPORT
@ -1501,7 +1418,6 @@ extern "C" {
PK_LEGACY_EXPORT PK_LEGACY_EXPORT
pkpy::REPL* pkpy_new_repl(pkpy::VM* vm){ pkpy::REPL* pkpy_new_repl(pkpy::VM* vm){
pkpy::REPL* p = new pkpy::REPL(vm); pkpy::REPL* p = new pkpy::REPL(vm);
_pk_deleter_map[p] = [](void* p){ delete (pkpy::REPL*)p; };
return p; return p;
} }
@ -1518,10 +1434,19 @@ extern "C" {
PK_LEGACY_EXPORT PK_LEGACY_EXPORT
pkpy::VM* pkpy_new_vm(bool enable_os=true){ pkpy::VM* pkpy_new_vm(bool enable_os=true){
pkpy::VM* p = new pkpy::VM(enable_os); pkpy::VM* p = new pkpy::VM(enable_os);
_pk_deleter_map[p] = [](void* p){ delete (pkpy::VM*)p; };
return p; return p;
} }
PK_LEGACY_EXPORT
void pkpy_delete_vm(pkpy::VM* vm){
delete vm;
}
PK_LEGACY_EXPORT
void pkpy_delete_repl(pkpy::REPL* repl){
delete repl;
}
PK_LEGACY_EXPORT PK_LEGACY_EXPORT
void pkpy_vm_gc_on_delete(pkpy::VM* vm, void (*f)(pkpy::VM *, pkpy::PyObject *)){ void pkpy_vm_gc_on_delete(pkpy::VM* vm, void (*f)(pkpy::VM *, pkpy::PyObject *)){
vm->heap._gc_on_delete = f; vm->heap._gc_on_delete = f;

84
src/re.h Normal file
View File

@ -0,0 +1,84 @@
#pragma once
#include "cffi.h"
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<ReMatch>(type);
vm->bind_method<0>(type, "start", CPP_LAMBDA(VAR(_CAST(ReMatch&, args[0]).start)));
vm->bind_method<0>(type, "end", CPP_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