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 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.
|
||||
!!!
|
||||
|
@ -37,9 +37,13 @@ using FuncDecl_ = shared_ptr<FuncDecl>;
|
||||
|
||||
struct NativeFunc {
|
||||
NativeFuncC f;
|
||||
|
||||
// old style argc-based call
|
||||
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];
|
||||
UserData _userdata;
|
||||
@ -71,10 +75,11 @@ struct NativeFunc {
|
||||
_has_userdata = false;
|
||||
}
|
||||
|
||||
NativeFunc(NativeFuncC f, FuncDecl_ decl){
|
||||
NativeFunc(NativeFuncC f, FuncDecl_ decl, const char* docstring){
|
||||
this->f = f;
|
||||
this->argc = -1;
|
||||
this->decl = decl;
|
||||
this->docstring = docstring;
|
||||
_has_userdata = false;
|
||||
}
|
||||
|
||||
|
16
src/vm.h
16
src/vm.h
@ -689,7 +689,8 @@ public:
|
||||
void post_init();
|
||||
PyObject* _py_generator(Frame&& frame, ArgsView buffer);
|
||||
// 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_&);
|
||||
};
|
||||
|
||||
@ -1544,20 +1545,23 @@ PyObject* VM::bind_func(PyObject* obj, Str name, NativeFuncC fn) {
|
||||
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;
|
||||
try{
|
||||
// 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){
|
||||
throw std::runtime_error(("invalid signature: " + sig).str());
|
||||
throw std::runtime_error("invalid signature: " + std::string(sig));
|
||||
}
|
||||
if(co->func_decls.size() != 1){
|
||||
throw std::runtime_error("expected 1 function declaration");
|
||||
}
|
||||
FuncDecl_ decl = co->func_decls[0];
|
||||
// return VAR(NativeFuncEx(fn, argc, false, sig));
|
||||
return nullptr;
|
||||
return VAR(NativeFunc(fn, decl, docstring));
|
||||
}
|
||||
|
||||
inline void VM::_error(Exception e){
|
||||
|
Loading…
x
Reference in New Issue
Block a user