mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 21:10:19 +00:00
...
This commit is contained in:
parent
3de3e625ee
commit
2f9b5eb700
@ -14,6 +14,34 @@ typedef PyObject* (*NativeFuncC)(VM*, ArgsView);
|
|||||||
+ The second argument is an array-like object indicates the arguments list. You can use `[]` operator to get the element.
|
+ The second argument is an array-like object indicates the arguments list. You can use `[]` operator to get the element.
|
||||||
+ The return value is a `PyObject*`, which should not be `nullptr`. If there is no return value, return `vm->None`.
|
+ The return value is a `PyObject*`, which should not be `nullptr`. If there is no return value, return `vm->None`.
|
||||||
|
|
||||||
|
|
||||||
|
## New style bindings
|
||||||
|
|
||||||
|
Use `vm->bind` to bind a function or method.
|
||||||
|
|
||||||
|
+ `PyObject* bind(PyObject*, const char* sig, NativeFuncC)`
|
||||||
|
+ `PyObject* bind(PyObject*, const char* sig, const char* docstring, NativeFuncC)`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
|
||||||
|
vm->bind(obj, "add(a: int, b: int) -> int", [](VM* vm, ArgsView args){
|
||||||
|
int a = CAST(int, args[0]);
|
||||||
|
int b = CAST(int, args[1]);
|
||||||
|
return VAR(a + b);
|
||||||
|
});
|
||||||
|
|
||||||
|
// or you can provide a docstring
|
||||||
|
vm->bind(obj,
|
||||||
|
"add(a: int, b: int) -> int",
|
||||||
|
"add two integers", [](VM* vm, ArgsView args){
|
||||||
|
int a = CAST(int, args[0]);
|
||||||
|
int b = CAST(int, args[1]);
|
||||||
|
return VAR(a + b);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Old style bindings
|
||||||
|
|
||||||
!!!
|
!!!
|
||||||
Native functions do not support keyword arguments.
|
Native functions do not support keyword arguments.
|
||||||
!!!
|
!!!
|
||||||
|
|||||||
@ -37,9 +37,13 @@ using FuncDecl_ = shared_ptr<FuncDecl>;
|
|||||||
|
|
||||||
struct NativeFunc {
|
struct NativeFunc {
|
||||||
NativeFuncC f;
|
NativeFuncC f;
|
||||||
|
|
||||||
|
// old style argc-based call
|
||||||
int argc;
|
int argc;
|
||||||
|
|
||||||
FuncDecl_ decl; // if this is not null, use ex call
|
// new style decl-based call
|
||||||
|
FuncDecl_ decl;
|
||||||
|
const char* docstring;
|
||||||
|
|
||||||
using UserData = char[32];
|
using UserData = char[32];
|
||||||
UserData _userdata;
|
UserData _userdata;
|
||||||
@ -71,10 +75,11 @@ struct NativeFunc {
|
|||||||
_has_userdata = false;
|
_has_userdata = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeFunc(NativeFuncC f, FuncDecl_ decl){
|
NativeFunc(NativeFuncC f, FuncDecl_ decl, const char* docstring){
|
||||||
this->f = f;
|
this->f = f;
|
||||||
this->argc = -1;
|
this->argc = -1;
|
||||||
this->decl = decl;
|
this->decl = decl;
|
||||||
|
this->docstring = docstring;
|
||||||
_has_userdata = false;
|
_has_userdata = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
src/vm.h
16
src/vm.h
@ -689,7 +689,8 @@ public:
|
|||||||
void post_init();
|
void post_init();
|
||||||
PyObject* _py_generator(Frame&& frame, ArgsView buffer);
|
PyObject* _py_generator(Frame&& frame, ArgsView buffer);
|
||||||
// new style binding api
|
// new style binding api
|
||||||
PyObject* bind(PyObject*, const Str&, NativeFuncC);
|
PyObject* bind(PyObject*, const char*, const char*, NativeFuncC);
|
||||||
|
PyObject* bind(PyObject*, const char*, NativeFuncC);
|
||||||
void _prepare_py_call(PyObject**, ArgsView, ArgsView, const FuncDecl_&);
|
void _prepare_py_call(PyObject**, ArgsView, ArgsView, const FuncDecl_&);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1544,20 +1545,23 @@ PyObject* VM::bind_func(PyObject* obj, Str name, NativeFuncC fn) {
|
|||||||
return nf;
|
return nf;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PyObject* VM::bind(PyObject* obj, const Str& sig, NativeFuncC fn){
|
inline PyObject* VM::bind(PyObject* obj, const char* sig, NativeFuncC fn){
|
||||||
|
return bind(obj, sig, nullptr, fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, NativeFuncC fn){
|
||||||
CodeObject_ co;
|
CodeObject_ co;
|
||||||
try{
|
try{
|
||||||
// fn(a, b, *c, d=1) -> None
|
// fn(a, b, *c, d=1) -> None
|
||||||
co = compile("def " + sig + " : pass", "<bind>", EXEC_MODE);
|
co = compile("def " + Str(sig) + " : pass", "<bind>", EXEC_MODE);
|
||||||
}catch(Exception& e){
|
}catch(Exception& e){
|
||||||
throw std::runtime_error(("invalid signature: " + sig).str());
|
throw std::runtime_error("invalid signature: " + std::string(sig));
|
||||||
}
|
}
|
||||||
if(co->func_decls.size() != 1){
|
if(co->func_decls.size() != 1){
|
||||||
throw std::runtime_error("expected 1 function declaration");
|
throw std::runtime_error("expected 1 function declaration");
|
||||||
}
|
}
|
||||||
FuncDecl_ decl = co->func_decls[0];
|
FuncDecl_ decl = co->func_decls[0];
|
||||||
// return VAR(NativeFuncEx(fn, argc, false, sig));
|
return VAR(NativeFunc(fn, decl, docstring));
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void VM::_error(Exception e){
|
inline void VM::_error(Exception e){
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user