blueloveTH há 2 anos atrás
pai
commit
ced9662530

+ 1 - 1
docs/modules/box2d.md

@@ -1,5 +1,5 @@
 ---
-icon: package
+icon: package-dependencies
 label: box2d
 ---
 

+ 1 - 1
docs/modules/os.md

@@ -1,5 +1,5 @@
 ---
-icon: package
+icon: package-dependencies
 label: os
 ---
 

+ 8 - 6
docs/quick-start/attr.md

@@ -10,12 +10,14 @@ Some python objects have an instance dict, a.k.a, `__dict__` in cpython.
 You can use `obj->attr()` to manipulate the instance dict of an object.
 
 ```cpp
+VM* vm = new VM();
+
 // get the `builtin` module
 PyObject* builtins = vm->builtins;
 // get `dict` type
 PyObject* dict = builtins->attr("dict");
 // set `pi = 3.14`
-builtins->attr().set("pi", VAR(3.14));
+builtins->attr().set("pi", py_var(vm, 3.14));
 ```
 
 However, you cannot call `attr` on an object which does not have an instance dict.
@@ -23,7 +25,7 @@ For example, the `int` object.
 
 ```cpp
 // create a `int` object
-PyObject* obj = VAR(1);
+PyObject* obj = py_var(vm, 1);
 // THIS IS WRONG!! WILL LEAD TO A SEGFAULT!!
 PyObject* add = obj->attr("__add__");
 ```
@@ -33,7 +35,7 @@ To determine whether an object has instance dict or not, you can use this snippe
 ```cpp
 // 1. call `is_tagged` to check the object supports `->` operator
 // 2. call `is_attr_valid` to check the existence of instance dict
-PyObject* obj = VAR(1);
+PyObject* obj = py_var(vm, 1);
 bool ok = !is_tagged(obj) && obj->is_attr_valid();  // false
 ```
 
@@ -51,16 +53,16 @@ or throw an `AttributeError` depending on the value of `throw_err`.
 
 ```cpp
 // create a `int` object
-PyObject* obj = VAR(1);
+PyObject* obj = py_var(vm, 1);
 
 // get its `__add__` method, which is a `bound_method` object
 PyObject* add = vm->getattr(obj, "__add__");
 
 // call it (equivalent to `1 + 2`)
-PyObject* ret = vm->call(add, VAR(2));
+PyObject* ret = vm->call(add, py_var(vm, 2););
 
 // get the result
-int result = CAST(int, ret);
+int result = py_cast<int>(vm, ret);
 std::cout << result << std::endl; // 3
 ```
 

+ 5 - 3
docs/quick-start/call.md

@@ -34,12 +34,14 @@ PyObject* obj = vm->call(tp);	// this is a `dict`
 And set a key-value pair,
 
 ```cpp
-vm->call_method(obj, "__setitem__", VAR("a"), VAR(5));
+PyObject* _0 = py_var(vm, "a");
+PyObject* _1 = py_var(vm, 5);
+vm->call_method(obj, "__setitem__", _0, _1);
 ```
 
 And get the value,
 
 ```cpp
-PyObject* ret = vm->call_method(obj, "__getitem__", VAR("a"));
-std::cout << CAST(i64, ret) << std::endl;
+PyObject* ret = vm->call_method(obj, "__getitem__", _0);
+std::cout << py_cast<int>(vm, i64);
 ```

+ 18 - 19
docs/quick-start/interop.md

@@ -11,13 +11,13 @@ In pkpy, any python object is represented by a `PyObject*`.
 
 A set of overloaded function `PyObject* py_var(VM* vm, ...)` were implemented to
 create a `PyObject*` from a supported C type.
-In order to make it less verbose, we usually use macro `VAR(...)`, which is just a wrapper of `py_var`.
 
-For example, create a python `int` object from a C `i64` type:
+Assume we have a `VM* vm` instance.
+You can create a python `int` object from a C `i64` type:
 
 ```cpp
 i64 i = 2;
-PyObject* obj = VAR(i);
+PyObject* obj = py_var(vm, i);
 ```
 
 Each python type has a corresponding C type, for example, `int` in python is `i64` in C.
@@ -26,7 +26,7 @@ For strings, we have defined
 a set of overloaded version including `const char*`, `std::string`, `std::string_view`, `Str`, etc.
 
 ```cpp
-PyObject* obj = VAR("abc");		// create a python str object
+PyObject* obj = py_var(vm, "abc");		// create a python str object
 ```
 
 A more complex example is to create a python `list`.
@@ -35,50 +35,49 @@ In the following code, we create a `list` equals to `[0, 1, 2, 3]`.
 ```cpp
 List list;
 for (i64 i = 0; i < 4; i++) {
-    list.push_back(VAR(i));
+    list.push_back(py_var(vm, i));
 }
 
-obj = VAR(std::move(list));		// create a python list object
+obj = py_var(vm, std::move(list));		// create a python list object
 ```
 
 Please note that `std::move` is used here to avoid unnecessary copy.
-Most types have both a rvalue and a lvalue version of `VAR` function.
+Most types have both a rvalue and a lvalue version of `py_var` function.
 
 ### Access internal C type of `PyObject*`
 
-A set of template function `T py_cast<T>(VM* vm, PyObject* obj)` were implemented
-for each supported C type. We usually use macro `CAST(T, ...)` to make it less verbose.
+A set of template function `T py_cast<T>(VM* vm, PyObject* obj)` were implemented.
 
 ```cpp
 i64 i = 2;
-PyObject* obj = VAR(i);
+PyObject* obj = py_var(vm, i);
 
 // cast a PyObject* to C i64
-i64 j = CAST(i64, obj);		
+i64 j = py_cast<i64>(vm, obj);
 ```
 
-The `CAST` function will check the type of `obj` before casting.
+The `py_cast` function will check the type of `obj` before casting.
 If the type is not matched, a `TypeError` will be thrown.
 
 However, this type check has a cost. If you are sure about the type of `obj`,
-you can use the underscore version `_CAST` to skip the type check.
+you can use the underscore version `_py_cast` to skip the type check.
 
 ```cpp
 // cast a PyObject* to C i64 (unsafe but faster)
-i64 j = _CAST(i64, obj);		
+i64 j = _py_cast<i64>(vm, obj);		
 ```
 
 For complex objects like `list`, we can use reference cast to avoid unnecessary copy.
 
 ```cpp
-PyObject* obj = VAR(List());
+PyObject* obj = py_var(vm, List());
 // reference cast (no copy)
-List& list = CAST(List&, obj);
+List& list = py_cast<List&>(vm, obj);
 ```
 
 ### Check type of `PyObject*`
 
-Each `PyObject*` has a `Type` field to indicate its type.
+Each `PyObject*` has a `Type type` field to indicate its type.
 `Type` is just an integer which is the global index in `vm->_all_types`.
 
 `VM` class has a set of predefined `Type` constants for quick access.
@@ -86,7 +85,7 @@ They are prefixed by `tp_`. For example, `tp_object`(object),
 `tp_int`(int), `tp_str`(str), `tp_list`(list), etc.
 
 Types are divided into **tagged type** and **non-tagged type**.
-+ `int` and `float` are tagged type.
++ `int` (small) and `float` are tagged type.
 + Other types are non-tagged type.
 
 To determine whether a `PyObject*` is of a specific type,
@@ -99,7 +98,7 @@ you can use the following functions:
 + `bool is_non_tagged_type(PyObject* obj, Type type)`
 
 ```cpp
-PyObject* obj = VAR(1);
+PyObject* obj = py_var(vm, 1);
 
 bool ok = is_type(obj, vm->tp_int);		// true
 ok = is_int(obj);						// true

+ 9 - 8
docs/quick-start/modules.md

@@ -28,17 +28,18 @@ A native module is a module written in c++ or mixed c++/python.
 Native modules are always compiled and executed when the VM is created.
 
 To creata a native module,
-use `vm->new_module(...)`.
+use `vm->new_module(Str name)`.
 
 ```cpp
 PyObject* mod = vm->new_module("test");
-mod->attr().set("pi", VAR(3.14));
-
-vm->bind_func<2>(mod, "add", [](VM* vm, ArgsView args){
-    i64 a = CAST(i64, args[0]);
-    i64 b = CAST(i64, args[1]);
-    return VAR(a + b);
-});
+mod->attr().set("pi", py_var(vm, 3.14));
+
+vm->bind(mod, "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);
+    });
 ```
 
 ```python