mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
up
This commit is contained in:
parent
dbbcf29df0
commit
5e9082b960
@ -52,7 +52,7 @@ For C/C++ developers, you can download the `pocketpy.h` on our GitHub release pa
|
|||||||
|
|
||||||
https://github.com/blueloveTH/pocketpy/releases/latest
|
https://github.com/blueloveTH/pocketpy/releases/latest
|
||||||
|
|
||||||
Check [C-API](https://pocketpy.dev/c-api/vm/) for references.
|
Check [C-API](https://pocketpy.dev/c-api/vm/) for references. C++ APIs will be available soon.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#include "pocketpy.h"
|
#include "pocketpy.h"
|
||||||
@ -139,6 +139,7 @@ You can download `artifact.zip` from [Github Release](https://github.com/bluelov
|
|||||||
- linux/
|
- linux/
|
||||||
- x86_64/
|
- x86_64/
|
||||||
- pocketpy
|
- pocketpy
|
||||||
|
- pocketpy.so
|
||||||
- macos/
|
- macos/
|
||||||
- pocketpy.bundle/
|
- pocketpy.bundle/
|
||||||
- web/
|
- web/
|
||||||
|
@ -132,6 +132,7 @@ flutter pub add pocketpy
|
|||||||
- linux/
|
- linux/
|
||||||
- x86_64/
|
- x86_64/
|
||||||
- pocketpy
|
- pocketpy
|
||||||
|
- pocketpy.so
|
||||||
- macos/
|
- macos/
|
||||||
- pocketpy.bundle/
|
- pocketpy.bundle/
|
||||||
- web/
|
- web/
|
||||||
|
@ -35,10 +35,11 @@
|
|||||||
#include <emscripten.h>
|
#include <emscripten.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PK_VERSION "0.8.1"
|
#define PK_VERSION "0.8.2"
|
||||||
|
|
||||||
typedef int64_t i64;
|
typedef int64_t i64;
|
||||||
typedef double f64;
|
typedef double f64;
|
||||||
#define DUMMY_VAL (i64)0
|
#define DUMMY_VAL (i64)0
|
||||||
|
|
||||||
#define CPP_LAMBDA(x) ([](VM* vm, const pkpy::Args& args) { return x; })
|
#define CPP_LAMBDA(x) ([](VM* vm, const pkpy::Args& args) { return x; })
|
||||||
|
#define CPP_NOT_IMPLEMENTED() ([](VM* vm, const pkpy::Args& args) { vm->notImplementedError(); return vm->None; })
|
20
src/iter.h
20
src/iter.h
@ -13,11 +13,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool hasNext() override {
|
bool hasNext() override {
|
||||||
if(r.step > 0){
|
return r.step > 0 ? current < r.stop : current > r.stop;
|
||||||
return current < r.stop;
|
|
||||||
}else{
|
|
||||||
return current > r.stop;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar next() override;
|
PyVar next() override;
|
||||||
@ -32,13 +28,8 @@ public:
|
|||||||
vec = &OBJ_GET(PyVarList, _ref);
|
vec = &OBJ_GET(PyVarList, _ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasNext(){
|
bool hasNext(){ return index < vec->size(); }
|
||||||
return index < vec->size();
|
PyVar next(){ return vec->operator[](index++); }
|
||||||
}
|
|
||||||
|
|
||||||
PyVar next(){
|
|
||||||
return vec->operator[](index++);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class StringIterator : public BaseIterator {
|
class StringIterator : public BaseIterator {
|
||||||
@ -50,9 +41,6 @@ public:
|
|||||||
str = OBJ_GET(_Str, _ref);
|
str = OBJ_GET(_Str, _ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasNext(){
|
bool hasNext(){ return index < str.u8_length(); }
|
||||||
return index < str.u8_length();
|
|
||||||
}
|
|
||||||
|
|
||||||
PyVar next();
|
PyVar next();
|
||||||
};
|
};
|
||||||
|
10
src/obj.h
10
src/obj.h
@ -93,7 +93,13 @@ struct Py_ : PyObject {
|
|||||||
virtual void* value() override { return &_value; }
|
virtual void* value() override { return &_value; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//#define OBJ_GET(T, obj) (((Py_<T>*)((obj).get()))->_value)
|
// Unsafe cast from PyObject to C++ type
|
||||||
#define OBJ_GET(T, obj) (*static_cast<T*>((obj)->value()))
|
#define OBJ_GET(T, obj) (*static_cast<T*>((obj)->value()))
|
||||||
#define OBJ_NAME(obj) OBJ_GET(_Str, (obj)->attribs[__name__])
|
#define OBJ_NAME(obj) OBJ_GET(_Str, (obj)->attribs[__name__])
|
||||||
#define OBJ_TP_NAME(obj) OBJ_GET(_Str, (obj)->type->attribs[__name__])
|
#define OBJ_TP_NAME(obj) OBJ_GET(_Str, (obj)->type->attribs[__name__])
|
||||||
|
|
||||||
|
#define PY_CLASS(mod, name) \
|
||||||
|
inline static PyVar _type(VM* vm) { return vm->_modules[#mod]->attribs[#name]; } \
|
||||||
|
inline static const char* _name() { return #name; }
|
||||||
|
|
||||||
|
#define PY_BUILTIN_CLASS(name) inline static PyVar _type(VM* vm) { return vm->_tp_##name; }
|
@ -573,8 +573,6 @@ void __add_module_dis(VM* vm){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PY_CLASS(mod, name) inline static PyVar _tp(VM* vm) { return vm->_modules[#mod]->attribs[#name]; }
|
|
||||||
|
|
||||||
struct ReMatch {
|
struct ReMatch {
|
||||||
PY_CLASS(re, Match)
|
PY_CLASS(re, Match)
|
||||||
|
|
||||||
@ -583,27 +581,22 @@ struct ReMatch {
|
|||||||
std::smatch m;
|
std::smatch m;
|
||||||
ReMatch(i64 start, i64 end, std::smatch m) : start(start), end(end), m(m) {}
|
ReMatch(i64 start, i64 end, std::smatch m) : start(start), end(end), m(m) {}
|
||||||
|
|
||||||
static PyVar _register(VM* vm, PyVar mod){
|
static void _register(VM* vm, PyVar mod, PyVar type){
|
||||||
PyVar _tp_match = vm->new_user_type_object(mod, "Match", vm->_tp_object);
|
vm->bindMethod<-1>(type, "__init__", CPP_NOT_IMPLEMENTED());
|
||||||
vm->bindMethod<-1>(_tp_match, "__init__", [](VM* vm, const pkpy::Args& args){
|
vm->bindMethod<0>(type, "start", CPP_LAMBDA(vm->PyInt(vm->py_cast<ReMatch>(args[0]).start)));
|
||||||
vm->notImplementedError();
|
vm->bindMethod<0>(type, "end", CPP_LAMBDA(vm->PyInt(vm->py_cast<ReMatch>(args[0]).end)));
|
||||||
return vm->None;
|
|
||||||
});
|
|
||||||
vm->bindMethod<0>(_tp_match, "start", CPP_LAMBDA(vm->PyInt(OBJ_GET(ReMatch, args[0]).start)));
|
|
||||||
vm->bindMethod<0>(_tp_match, "end", CPP_LAMBDA(vm->PyInt(OBJ_GET(ReMatch, args[0]).end)));
|
|
||||||
|
|
||||||
vm->bindMethod<0>(_tp_match, "span", [](VM* vm, const pkpy::Args& args) {
|
vm->bindMethod<0>(type, "span", [](VM* vm, const pkpy::Args& args) {
|
||||||
auto& self = OBJ_GET(ReMatch, args[0]);
|
auto& self = vm->py_cast<ReMatch>(args[0]);
|
||||||
return vm->PyTuple({ vm->PyInt(self.start), vm->PyInt(self.end) });
|
return vm->PyTuple({ vm->PyInt(self.start), vm->PyInt(self.end) });
|
||||||
});
|
});
|
||||||
|
|
||||||
vm->bindMethod<1>(_tp_match, "group", [](VM* vm, const pkpy::Args& args) {
|
vm->bindMethod<1>(type, "group", [](VM* vm, const pkpy::Args& args) {
|
||||||
auto& self = OBJ_GET(ReMatch, args[0]);
|
auto& self = vm->py_cast<ReMatch>(args[0]);
|
||||||
int index = (int)vm->PyInt_AS_C(args[1]);
|
int index = (int)vm->PyInt_AS_C(args[1]);
|
||||||
index = vm->normalized_index(index, self.m.size());
|
index = vm->normalized_index(index, self.m.size());
|
||||||
return vm->PyStr(self.m[index].str());
|
return vm->PyStr(self.m[index].str());
|
||||||
});
|
});
|
||||||
return _tp_match;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -614,14 +607,14 @@ PyVar __regex_search(const _Str& pattern, const _Str& string, bool fromStart, VM
|
|||||||
if(fromStart && m.position() != 0) return vm->None;
|
if(fromStart && m.position() != 0) return vm->None;
|
||||||
i64 start = string.__to_u8_index(m.position());
|
i64 start = string.__to_u8_index(m.position());
|
||||||
i64 end = string.__to_u8_index(m.position() + m.length());
|
i64 end = string.__to_u8_index(m.position() + m.length());
|
||||||
return vm->new_object_c<ReMatch>(start, end, m);
|
return vm->new_object<ReMatch>(start, end, m);
|
||||||
}
|
}
|
||||||
return vm->None;
|
return vm->None;
|
||||||
};
|
};
|
||||||
|
|
||||||
void __add_module_re(VM* vm){
|
void __add_module_re(VM* vm){
|
||||||
PyVar mod = vm->new_module("re");
|
PyVar mod = vm->new_module("re");
|
||||||
ReMatch::_register(vm, mod);
|
vm->register_class<ReMatch>(mod);
|
||||||
|
|
||||||
vm->bindFunc<2>(mod, "match", [](VM* vm, const pkpy::Args& args) {
|
vm->bindFunc<2>(mod, "match", [](VM* vm, const pkpy::Args& args) {
|
||||||
const _Str& pattern = vm->PyStr_AS_C(args[0]);
|
const _Str& pattern = vm->PyStr_AS_C(args[0]);
|
||||||
@ -827,7 +820,7 @@ extern "C" {
|
|||||||
for(int i=0; mod[i]; i++) if(mod[i] == ' ') return nullptr;
|
for(int i=0; mod[i]; i++) if(mod[i] == ' ') return nullptr;
|
||||||
for(int i=0; name[i]; i++) if(name[i] == ' ') return nullptr;
|
for(int i=0; name[i]; i++) if(name[i] == ' ') return nullptr;
|
||||||
std::string f_header = std::string(mod) + '.' + name + '#' + std::to_string(kGlobalBindId++);
|
std::string f_header = std::string(mod) + '.' + name + '#' + std::to_string(kGlobalBindId++);
|
||||||
PyVar obj = vm->new_module_if_not_existed(mod);
|
PyVar obj = vm->_modules.contains(mod) ? vm->_modules[mod] : vm->new_module(mod);
|
||||||
vm->bindFunc<-1>(obj, name, [ret_code, f_header](VM* vm, const pkpy::Args& args){
|
vm->bindFunc<-1>(obj, name, [ret_code, f_header](VM* vm, const pkpy::Args& args){
|
||||||
_StrStream ss;
|
_StrStream ss;
|
||||||
ss << f_header;
|
ss << f_header;
|
||||||
|
25
src/vm.h
25
src/vm.h
@ -613,23 +613,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
inline PyVar new_object_c(Args&&... args) {
|
inline PyVar new_object(Args&&... args) {
|
||||||
return new_object(T::_tp(this), T(std::forward<Args>(args)...));
|
return new_object(T::_type(this), T(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar new_module(_Str name) {
|
PyVar new_module(const _Str& name) {
|
||||||
PyVar obj = new_object(_tp_module, DUMMY_VAL);
|
PyVar obj = new_object(_tp_module, DUMMY_VAL);
|
||||||
setattr(obj, __name__, PyStr(name));
|
setattr(obj, __name__, PyStr(name));
|
||||||
_modules[name] = obj;
|
_modules[name] = obj;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyVar new_module_if_not_existed(_Str name) {
|
|
||||||
PyVar* it = _modules.try_get(name);
|
|
||||||
if(it != nullptr) return *it;
|
|
||||||
return new_module(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyVarOrNull getattr(const PyVar& obj, const _Str& name, bool throw_err=true) {
|
PyVarOrNull getattr(const PyVar& obj, const _Str& name, bool throw_err=true) {
|
||||||
PyVarDict::iterator it;
|
PyVarDict::iterator it;
|
||||||
PyObject* cls;
|
PyObject* cls;
|
||||||
@ -944,6 +938,19 @@ public:
|
|||||||
if(!obj->is_type(type)) typeError("expected '" + OBJ_NAME(type) + "', but got '" + OBJ_TP_NAME(obj) + "'");
|
if(!obj->is_type(type)) typeError("expected '" + OBJ_NAME(type) + "', but got '" + OBJ_TP_NAME(obj) + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
PyVar register_class(PyVar mod){
|
||||||
|
PyVar type = new_user_type_object(mod, T::_name(), _tp_object);
|
||||||
|
T::_register(this, mod, type);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T& py_cast(const PyVar& obj){
|
||||||
|
check_type(obj, T::_type(this));
|
||||||
|
return OBJ_GET(T, obj);
|
||||||
|
}
|
||||||
|
|
||||||
~VM() {
|
~VM() {
|
||||||
if(!use_stdio){
|
if(!use_stdio){
|
||||||
delete _stdout;
|
delete _stdout;
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
g++ -o pocketpy src/main.cpp --std=c++17 -pg -O1 -fno-rtti
|
|
||||||
|
|
||||||
./pocketpy tests/1.py
|
|
||||||
|
|
||||||
gprof pocketpy gmon.out > gprof.txt
|
|
||||||
|
|
||||||
rm gmon.out
|
|
Loading…
x
Reference in New Issue
Block a user