Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
blueloveTH committed Feb 8, 2023
1 parent dbbcf29 commit 5e9082b
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 55 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

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
#include "pocketpy.h"
Expand Down Expand Up @@ -139,6 +139,7 @@ You can download `artifact.zip` from [Github Release](https://github.com/bluelov
- linux/
- x86_64/
- pocketpy
- pocketpy.so
- macos/
- pocketpy.bundle/
- web/
Expand Down
1 change: 1 addition & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ flutter pub add pocketpy
- linux/
- x86_64/
- pocketpy
- pocketpy.so
- macos/
- pocketpy.bundle/
- web/
Expand Down
5 changes: 3 additions & 2 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@
#include <emscripten.h>
#endif

#define PK_VERSION "0.8.1"
#define PK_VERSION "0.8.2"

typedef int64_t i64;
typedef double f64;
#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 changes: 4 additions & 16 deletions src/iter.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ class RangeIterator : public BaseIterator {
}

bool hasNext() override {
if(r.step > 0){
return current < r.stop;
}else{
return current > r.stop;
}
return r.step > 0 ? current < r.stop : current > r.stop;
}

PyVar next() override;
Expand All @@ -32,13 +28,8 @@ class VectorIterator : public BaseIterator {
vec = &OBJ_GET(PyVarList, _ref);
}

bool hasNext(){
return index < vec->size();
}

PyVar next(){
return vec->operator[](index++);
}
bool hasNext(){ return index < vec->size(); }
PyVar next(){ return vec->operator[](index++); }
};

class StringIterator : public BaseIterator {
Expand All @@ -50,9 +41,6 @@ class StringIterator : public BaseIterator {
str = OBJ_GET(_Str, _ref);
}

bool hasNext(){
return index < str.u8_length();
}

bool hasNext(){ return index < str.u8_length(); }
PyVar next();
};
10 changes: 8 additions & 2 deletions src/obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,13 @@ struct Py_ : PyObject {
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_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; }
29 changes: 11 additions & 18 deletions src/pocketpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
PY_CLASS(re, Match)

Expand All @@ -583,27 +581,22 @@ struct ReMatch {
std::smatch m;
ReMatch(i64 start, i64 end, std::smatch m) : start(start), end(end), m(m) {}

static PyVar _register(VM* vm, PyVar mod){
PyVar _tp_match = vm->new_user_type_object(mod, "Match", vm->_tp_object);
vm->bindMethod<-1>(_tp_match, "__init__", [](VM* vm, const pkpy::Args& args){
vm->notImplementedError();
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)));
static void _register(VM* vm, PyVar mod, PyVar type){
vm->bindMethod<-1>(type, "__init__", CPP_NOT_IMPLEMENTED());
vm->bindMethod<0>(type, "start", CPP_LAMBDA(vm->PyInt(vm->py_cast<ReMatch>(args[0]).start)));
vm->bindMethod<0>(type, "end", CPP_LAMBDA(vm->PyInt(vm->py_cast<ReMatch>(args[0]).end)));

vm->bindMethod<0>(_tp_match, "span", [](VM* vm, const pkpy::Args& args) {
auto& self = OBJ_GET(ReMatch, args[0]);
vm->bindMethod<0>(type, "span", [](VM* vm, const pkpy::Args& args) {
auto& self = vm->py_cast<ReMatch>(args[0]);
return vm->PyTuple({ vm->PyInt(self.start), vm->PyInt(self.end) });
});

vm->bindMethod<1>(_tp_match, "group", [](VM* vm, const pkpy::Args& args) {
auto& self = OBJ_GET(ReMatch, args[0]);
vm->bindMethod<1>(type, "group", [](VM* vm, const pkpy::Args& args) {
auto& self = vm->py_cast<ReMatch>(args[0]);
int index = (int)vm->PyInt_AS_C(args[1]);
index = vm->normalized_index(index, self.m.size());
return vm->PyStr(self.m[index].str());
});
return _tp_match;
}
};

Expand All @@ -614,14 +607,14 @@ PyVar __regex_search(const _Str& pattern, const _Str& string, bool fromStart, VM
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_c<ReMatch>(start, end, m);
return vm->new_object<ReMatch>(start, end, m);
}
return vm->None;
};

void __add_module_re(VM* vm){
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) {
const _Str& pattern = vm->PyStr_AS_C(args[0]);
Expand Down Expand Up @@ -827,7 +820,7 @@ extern "C" {
for(int i=0; mod[i]; i++) if(mod[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++);
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){
_StrStream ss;
ss << f_header;
Expand Down
25 changes: 16 additions & 9 deletions src/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -613,23 +613,17 @@ class VM {
}

template<typename T, typename... Args>
inline PyVar new_object_c(Args&&... args) {
return new_object(T::_tp(this), T(std::forward<Args>(args)...));
inline PyVar new_object(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);
setattr(obj, __name__, PyStr(name));
_modules[name] = 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) {
PyVarDict::iterator it;
PyObject* cls;
Expand Down Expand Up @@ -944,6 +938,19 @@ class VM {
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() {
if(!use_stdio){
delete _stdout;
Expand Down
7 changes: 0 additions & 7 deletions test_cpp.sh

This file was deleted.

0 comments on commit 5e9082b

Please sign in to comment.