mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 04:50:17 +00:00
...
This commit is contained in:
parent
d0453ab15f
commit
7669c67c38
@ -37,8 +37,7 @@ int main(){
|
||||
pkpy_vm_exec(vm, "print(sum(a))");
|
||||
|
||||
// 释放资源
|
||||
pkpy_delete(result);
|
||||
pkpy_delete(vm);
|
||||
pkpy_delete_vm(vm);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
@ -9,7 +9,7 @@ pipeline = [
|
||||
["common.h", "memory.h", "vector.h", "str.h", "tuplelist.h", "namedict.h", "error.h", "lexer.h"],
|
||||
["obj.h", "dict.h", "codeobject.h", "frame.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"]
|
||||
]
|
||||
|
||||
|
@ -20,11 +20,14 @@ Run a given source on a virtual machine.
|
||||
|
||||
Advanced version of `pkpy_vm_exec`.
|
||||
|
||||
#### `void pkpy_delete(void* p)`
|
||||
#### `void pkpy_free(void* p)`
|
||||
|
||||
Delete a pointer allocated by `pkpy_xxx_xxx`.
|
||||
It can be `VM*`, `REPL*`, `char*`, etc.
|
||||
Free a pointer via `free`.
|
||||
|
||||
!!!
|
||||
If the pointer is not allocated by `pkpy_xxx_xxx`, the behavior is undefined.
|
||||
!!!
|
||||
#### `void pkpy_delete_vm(VM* vm)`
|
||||
|
||||
Delete a virtual machine.
|
||||
|
||||
#### `void pkpy_delete_repl(REPL* repl)`
|
||||
|
||||
Delete a REPL.
|
@ -22,7 +22,7 @@ int main(int argc, char** argv){
|
||||
if(eof) break;
|
||||
need_more_lines = pkpy_repl_input(repl, line.c_str());
|
||||
}
|
||||
pkpy_delete(vm);
|
||||
pkpy_delete_vm(vm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ int main(int argc, char** argv){
|
||||
|
||||
pkpy::PyObject* ret = nullptr;
|
||||
ret = vm->exec(src.c_str(), filepath.filename().string(), pkpy::EXEC_MODE);
|
||||
pkpy_delete(vm);
|
||||
pkpy_delete_vm(vm);
|
||||
return ret != nullptr ? 0 : 1;
|
||||
}
|
||||
|
||||
|
101
src/pocketpy.h
101
src/pocketpy.h
@ -14,6 +14,7 @@
|
||||
#include "_generated.h"
|
||||
#include "export.h"
|
||||
#include "vm.h"
|
||||
#include "re.h"
|
||||
|
||||
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{
|
||||
PY_CLASS(Random, random, Random)
|
||||
std::mt19937 gen;
|
||||
@ -1469,17 +1393,10 @@ inline void VM::post_init(){
|
||||
} // namespace pkpy
|
||||
|
||||
/*************************GLOBAL NAMESPACE*************************/
|
||||
static std::map<void*, void(*)(void*)> _pk_deleter_map;
|
||||
|
||||
extern "C" {
|
||||
PK_LEGACY_EXPORT
|
||||
void pkpy_delete(void* p){
|
||||
auto it = _pk_deleter_map.find(p);
|
||||
if(it != _pk_deleter_map.end()){
|
||||
it->second(p);
|
||||
}else{
|
||||
free(p);
|
||||
}
|
||||
void pkpy_free(void* p){
|
||||
free(p);
|
||||
}
|
||||
|
||||
PK_LEGACY_EXPORT
|
||||
@ -1501,7 +1418,6 @@ extern "C" {
|
||||
PK_LEGACY_EXPORT
|
||||
pkpy::REPL* pkpy_new_repl(pkpy::VM* vm){
|
||||
pkpy::REPL* p = new pkpy::REPL(vm);
|
||||
_pk_deleter_map[p] = [](void* p){ delete (pkpy::REPL*)p; };
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -1518,10 +1434,19 @@ extern "C" {
|
||||
PK_LEGACY_EXPORT
|
||||
pkpy::VM* pkpy_new_vm(bool enable_os=true){
|
||||
pkpy::VM* p = new pkpy::VM(enable_os);
|
||||
_pk_deleter_map[p] = [](void* p){ delete (pkpy::VM*)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
|
||||
void pkpy_vm_gc_on_delete(pkpy::VM* vm, void (*f)(pkpy::VM *, pkpy::PyObject *)){
|
||||
vm->heap._gc_on_delete = f;
|
||||
|
84
src/re.h
Normal file
84
src/re.h
Normal 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
|
Loading…
x
Reference in New Issue
Block a user