blueloveTH 2023-09-30 11:27:13 +08:00
parent 44d158e2fb
commit d3debb6cf9
3 changed files with 90 additions and 60 deletions

View File

@ -76,20 +76,20 @@ int main(){
// Eval the sum of the list // Eval the sum of the list
PyObject* result = vm->eval("sum(a)"); PyObject* result = vm->eval("sum(a)");
std::cout << CAST(int, result); // 6 std::cout << py_cast<int>(vm, result); // 6
// Bindings // Bindings
vm->bind(vm->_main, "add(a: int, b: int)", vm->bind(vm->_main, "add(a: int, b: int)",
[](VM* vm, ArgsView args){ [](VM* vm, ArgsView args){
int a = CAST(int, args[0]); int a = py_cast<int>(vm, args[0]);
int b = CAST(int, args[1]); int b = py_cast<int>(vm, args[1]);
return VAR(a + b); return py_var(vm, a + b);
}); });
// Call the function // Call the function
PyObject* f_add = vm->_main->attr("add"); PyObject* f_add = vm->_main->attr("add");
result = vm->call(f_add, VAR(3), VAR(7)); result = vm->call(f_add, py_var(vm, 3), py_var(vm, 7));
std::cout << CAST(int, result); // 10 std::cout << py_cast<int>(vm, result); // 10
// Dispose the virtual machine // Dispose the virtual machine
delete vm; delete vm;

View File

@ -37,21 +37,37 @@ pkpy 支持任何拥有 C++17 编译器的平台。
```cpp ```cpp
#include "pocketpy.h" #include "pocketpy.h"
using namespace pkpy;
int main(){ int main(){
// 创建一个虚拟机 // 建一个虚拟机
auto vm = pkpy_new_vm(); VM* vm = new VM();
// Hello world! // Hello world!
pkpy_vm_exec(vm, "print('Hello world!')"); vm->exec("print('Hello world!')");
// 构一个列表 // 构一个列表
pkpy_vm_exec(vm, "a = [1, 2, 3]"); vm->exec("a = [1, 2, 3]");
// 对列表进行求和 // 计算列表元素之和
pkpy_vm_exec(vm, "print(sum(a))"); PyObject* result = vm->eval("sum(a)");
std::cout << py_cast<int>(vm, result); // 6
// 释放资源 // 绑定一个函数
pkpy_delete_vm(vm); vm->bind(vm->_main, "add(a: int, b: int)",
[](VM* vm, ArgsView args){
int a = py_cast<int>(vm, args[0]);
int b = py_cast<int>(vm, args[1]);
return py_var(vm, a + b);
});
// 调用函数
PyObject* f_add = vm->_main->attr("add");
result = vm->call(f_add, py_var(vm, 3), py_var(vm, 7));
std::cout << py_cast<int>(vm, result); // 10
// 释放虚拟机
delete vm;
return 0; return 0;
} }
``` ```

View File

@ -35,7 +35,7 @@ Evaluate a source string
```cpp ```cpp
PyObject* obj = vm->eval("123"); PyObject* obj = vm->eval("123");
std::cout << CAST(i64, obj); // 123 std::cout << py_cast<int>(vm, obj); // 123
``` ```
Compile a source string into a code object Compile a source string into a code object
@ -60,10 +60,10 @@ Create primitive objects
```cpp ```cpp
PyObject* obj; PyObject* obj;
obj = VAR(1); // create a int obj = py_var(vm, 1); // create a int
obj = VAR(1.0); // create a float obj = py_var(vm, 1.0); // create a float
obj = VAR("123"); // create a string obj = py_var(vm, "123"); // create a string
obj = VAR(true); // create a bool obj = py_var(vm, true); // create a bool
``` ```
Create a tuple object Create a tuple object
@ -71,10 +71,10 @@ Create a tuple object
```cpp ```cpp
// obj = (1, 1.0, '123') // obj = (1, 1.0, '123')
Tuple t(3); Tuple t(3);
t[0] = VAR(1); t[0] = py_var(vm, 1);
t[1] = VAR(1.0); t[1] = py_var(vm, 1.0);
t[2] = VAR("123"); t[2] = py_var(vm, "123");
PyObject* obj = VAR(std::move(t)); PyObject* obj = py_var(vm, std::move(t));
``` ```
Create a list object Create a list object
@ -82,10 +82,10 @@ Create a list object
```cpp ```cpp
// obj = [1, 1.0, '123'] // obj = [1, 1.0, '123']
List t; List t;
t.push_back(VAR(1)); t.push_back(py_var(vm, 1));
t.push_back(VAR(1.0)); t.push_back(py_var(vm, 1.0));
t.push_back(VAR("123")); t.push_back(py_var(vm, "123"));
PyObject* obj = VAR(std::move(t)); PyObject* obj = py_var(vm, std::move(t));
``` ```
Create a dict object Create a dict object
@ -93,23 +93,36 @@ Create a dict object
```cpp ```cpp
// obj = {'x': 1, 'y': '123'} // obj = {'x': 1, 'y': '123'}
Dict d(vm); Dict d(vm);
d.set(VAR('x'), VAR(1)); d.set(py_var(vm, "x"), py_var(vm, 1));
d.set(VAR('y'), VAR('123')); d.set(py_var(vm, "y"), py_var(vm, "123"));
PyObject* obj = VAR(std::move(d)); PyObject* obj = py_var(vm, std::move(d));
``` ```
Get native types from python objects Get native types from python objects
```cpp ```cpp
PyObject* obj; PyObject* obj;
i64 a = CAST(i64, obj); i64 a = py_cast<i64>(vm, obj);
f64 b = CAST(f64, obj); f64 b = py_cast<f64>(vm, obj);
Str& c = CAST(Str&, obj); // reference cast Str& c = py_cast<Str&>(vm, obj); // reference cast
bool d = CAST(bool, obj); bool d = py_cast<bool>(vm, obj);
Tuple& e = CAST(Tuple&, obj); // reference cast Tuple& e = py_cast<Tuple&>(vm, obj); // reference cast
List& f = CAST(List&, obj); // reference cast List& f = py_cast<List&>(vm, obj); // reference cast
Dict& g = CAST(Dict&, obj); // reference cast Dict& g = py_cast<Dict&>(vm, obj); // reference cast
```
Get native types without type checking
```cpp
// unsafe version 1 (for int and float you must use `_py_cast`)
i64 a = _py_cast<i64>(vm, obj);
Str& c = _py_cast<Str&>(vm, obj);
Tuple& e = _py_cast<Tuple&>(vm, obj);
// unsafe version 2 (for others, you can use both versions)
i64 a_ = PK_OBJ_GET(i64, obj);
Str& c_ = PK_OBJ_GET(Str, obj);
Tuple& e_ = PK_OBJ_GET(Tuple, obj);
``` ```
## Access python types ## Access python types
@ -127,6 +140,7 @@ PyObject* list_t = vm->_t(vm->tp_list);
Access extended python types Access extended python types
```cpp ```cpp
// VoidP was defined by `PY_CLASS` macro
PyObject* voidp_t = VoidP::_type(vm); PyObject* voidp_t = VoidP::_type(vm);
``` ```
@ -140,7 +154,7 @@ bool ok = is_type(obj, vm->tp_int); // check if obj is an int
Get the type of a python object Get the type of a python object
```cpp ```cpp
PyObject* obj = VAR(1); PyObject* obj = py_var(vm, 1);
PyObject* t = vm->_t(obj); // <class 'int'> PyObject* t = vm->_t(obj); // <class 'int'>
``` ```
@ -176,7 +190,7 @@ Get and set attributes
```cpp ```cpp
PyObject* obj = vm->exec("MyClass(1, 2)"); PyObject* obj = vm->exec("MyClass(1, 2)");
PyObject* x = vm->getattr(obj, "x"); // obj.x PyObject* x = vm->getattr(obj, "x"); // obj.x
vm->setattr(obj, "x", VAR(3)); // obj.x = 3 vm->setattr(obj, "x", py_var(vm, 3)); // obj.x = 3
``` ```
## Call python functions ## Call python functions
@ -190,8 +204,8 @@ Call a function
```cpp ```cpp
PyObject* f_add = vm->eval("add"); PyObject* f_add = vm->eval("add");
PyObject* ret = vm->call(f_add, VAR(1), VAR(2)); PyObject* ret = vm->call(f_add, py_var(vm, 1), py_var(vm, 2));
std::cout << CAST(i64, ret); // 3 std::cout << py_cast<int>(vm, ret); // 3
``` ```
Call a method Call a method
@ -199,7 +213,7 @@ Call a method
```cpp ```cpp
PyObject* obj = vm->exec("MyClass(1, 2)"); PyObject* obj = vm->exec("MyClass(1, 2)");
PyObject* ret = vm->call_method(obj, "sum"); PyObject* ret = vm->call_method(obj, "sum");
std::cout << CAST(i64, ret); // 3 std::cout << CAST(i64, ret); // 3
``` ```
Cache the name of a function or method to avoid string-based lookup Cache the name of a function or method to avoid string-based lookup
@ -215,36 +229,36 @@ PyObject* ret = vm->call_method(obj, m_sum);
Compare two python objects Compare two python objects
```cpp ```cpp
PyObject* obj1 = VAR(1); PyObject* obj1 = py_var(vm, 1);
PyObject* obj2 = VAR(2); PyObject* obj2 = py_var(vm, 2);
bool ok = vm->py_equals(obj1, obj2); bool ok = vm->py_equals(obj1, obj2);
``` ```
Convert a python object to string Convert a python object to string
```cpp ```cpp
PyObject* obj = VAR("123"); PyObject* obj = py_var(vm, 123);
PyObject* s = vm->py_str(obj); // 123 PyObject* s = vm->py_str(obj); // 123
``` ```
Get the string representation of a python object Get the string representation of a python object
```cpp ```cpp
PyObject* obj = VAR("123"); PyObject* obj = py_var(vm, "123");
std::cout << vm->py_repr(obj); // '123' std::cout << vm->py_repr(obj); // '123'
``` ```
Get the JSON representation of a python object Get the JSON representation of a python object
```cpp ```cpp
PyObject* obj = VAR("123"); PyObject* obj = py_var(vm, 123);
std::cout << vm->py_json(obj); // "123" std::cout << vm->py_json(obj); // "123"
``` ```
Get the hash value of a python object Get the hash value of a python object
```cpp ```cpp
PyObject* obj = VAR(1); PyObject* obj = py_var(vm, 1);
i64 h = vm->py_hash(obj); // 1 i64 h = vm->py_hash(obj); // 1
``` ```
@ -277,9 +291,9 @@ Bind a native function
```cpp ```cpp
vm->bind(obj, "add(a: int, b: int) -> int", [](VM* vm, ArgsView args){ vm->bind(obj, "add(a: int, b: int) -> int", [](VM* vm, ArgsView args){
int a = CAST(int, args[0]); int a = py_cast<int>(vm, args[0]);
int b = CAST(int, args[1]); int b = py_cast<int>(vm, args[1]);
return VAR(a + b); return py_var(vm, a + b);
}); });
// Bind a native function with docstring // Bind a native function with docstring
@ -287,9 +301,9 @@ vm->bind(obj, "add(a: int, b: int) -> int", [](VM* vm, ArgsView args){
vm->bind(obj, vm->bind(obj,
"add(a: int, b: int) -> int", "add(a: int, b: int) -> int",
"add two integers", [](VM* vm, ArgsView args){ "add two integers", [](VM* vm, ArgsView args){
int a = CAST(int, args[0]); int a = py_cast<int>(vm, args[0]);
int b = CAST(int, args[1]); int b = py_cast<int>(vm, args[1]);
return VAR(a + b); return py_var(vm, a + b);
}); });
``` ```
@ -299,12 +313,12 @@ Bind a property
// getter and setter of property `x` // getter and setter of property `x`
vm->bind_property(type, "x: int", vm->bind_property(type, "x: int",
[](VM* vm, ArgsView args){ [](VM* vm, ArgsView args){
Point& self = CAST(Point&, args[0]); Point& self = PK_OBJ_GET(Point, args[0]);
return VAR(self.x); return VAR(self.x);
}, },
[](VM* vm, ArgsView args){ [](VM* vm, ArgsView args){
Point& self = CAST(Point&, args[0]); Point& self = PK_OBJ_GET(Point, args[0]);
self.x = CAST(int, args[1]); self.x = py_cast<int>(vm, args[1]);
return vm->None; return vm->None;
}); });
``` ```
@ -323,6 +337,6 @@ Create a native module
```cpp ```cpp
PyObject* mod = vm->new_module("test"); PyObject* mod = vm->new_module("test");
vm->setattr(mod, "pi", VAR(3.14)); vm->setattr(mod, "pi", py_var(vm, 3.14));
``` ```