This commit is contained in:
blueloveTH 2023-04-23 14:06:32 +08:00
parent 286d603e31
commit a0b1e6cafb
13 changed files with 61 additions and 20 deletions

View File

@ -30,7 +30,7 @@ int TestFunc(int x) { return x+1; }
int testFunc(int x) { return x+1; } int testFunc(int x) { return x+1; }
``` ```
For special Python objects, use the same name as in Python. For special python objects, use the same name as in python.
```cpp ```cpp
auto x = vm->None; auto x = vm->None;
@ -55,7 +55,7 @@ For macros, use **SNAKE_CASE**
## Access control ## Access control
Please use Python style access control. Please use python style access control.
We do not recommend to use C++ keywords such as `private` or `public` to achieve access control. Also do not write any trivial setter/getter. We do not recommend to use C++ keywords such as `private` or `public` to achieve access control. Also do not write any trivial setter/getter.

View File

@ -5,7 +5,7 @@ order: 100
# basic # basic
The following table shows the basic features of PocketPy with respect to [CPython](https://github.com/python/cpython). The following table shows the basic features of pkpy with respect to [cpython](https://github.com/python/cpython).
The features marked with `YES` are supported, and the features marked with `NO` are not supported. The features marked with `YES` are supported, and the features marked with `NO` are not supported.
| Name | Example | Supported | | Name | Example | Supported |

View File

@ -4,7 +4,7 @@ icon: dot
# goto/label # goto/label
PocketPy supports `goto` and `label` just like C. You are allowed to change the control flow unconditionally. pkpy supports `goto` and `label` just like C. You are allowed to change the control flow unconditionally.
## Syntax ## Syntax

View File

@ -5,7 +5,7 @@ icon: dot
# ternary op # ternary op
Ternary operator is a short hand `if...else`. Ternary operator is a short hand `if...else`.
PocketPy supports both C and Python style ternary. pkpy supports both c and python style ternary.
## Syntax ## Syntax

View File

@ -6,7 +6,7 @@ label: License
# License # License
PocketPy is licensed under the [MIT License](http://opensource.org/licenses/MIT). pkpy is licensed under the [MIT License](http://opensource.org/licenses/MIT).
``` ```
MIT License MIT License

View File

@ -5,13 +5,13 @@ label: json
### `json.loads(s)` ### `json.loads(s)`
Decode a JSON string into a PocketPy object. Decode a JSON string into a python object.
It is supported by the `eval()` function. It is supported by the `eval()` function.
### `json.dumps(obj)` ### `json.dumps(obj)`
Encode a PocketPy object into a JSON string. Encode a python object into a JSON string.
It is supported by the compiler with `JSON_MODE` enabled. It is supported by the compiler with `JSON_MODE` enabled.

View File

@ -5,5 +5,5 @@ label: sys
### `sys.version` ### `sys.version`
The version of PocketPy. The version of pkpy.

View File

@ -6,7 +6,7 @@ label: Performance
# Performance # Performance
Currently, PocketPy is almost~ fast as CPython 3.8. Here is a benchmark result of a special commit. Currently, pkpy is almost~ fast as cpython 3.8. Here is a benchmark result of a special commit.
Benchmark files are located in `benchmarks/`. Benchmark files are located in `benchmarks/`.

View File

@ -4,7 +4,8 @@ label: 'Interop with PyObject'
order: 90 order: 90
--- ---
Any python object is represented by a `PyObject*`. In pkpy, any python object is represented by a `PyObject*`.
There are 3 macros for you to do convert.
+ `VAR(...)`, + `VAR(...)`,
create a `PyObject*` from a C type create a `PyObject*` from a C type
@ -23,7 +24,7 @@ std::cout << CAST(Str, i); // abc
#### Types #### Types
| `PyObject` type | C type | note | | python type | C type | note |
| ------------ | ---------------- | ---------------------- | | ------------ | ---------------- | ---------------------- |
| `int` | `i64` | 62 bits integer | | `int` | `i64` | 62 bits integer |
| `float` | `f64` | 62 bits floating point | | `float` | `f64` | 62 bits floating point |

View File

@ -4,9 +4,47 @@ label: 'Attribute access'
order: 80 order: 80
--- ---
#### `PyObject* getattr(PyObject* obj, StrName name, bool throw_err=true)` ### Direct access
This method is equivalent to `getattr` in Python. Some python objects have an instance dict, a.k.a, `__dict__` in cpython.
You can use `PyObject::attr()` to manipulate the instance dict of an object.
```cpp
// 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));
```
However, you cannot call `attr` on an object which does not have an instance dict.
For example, the `int` object.
```cpp
// create a `int` object
PyObject* obj = VAR(1);
// THIS IS WRONG!! WILL LEAD TO A SEGFAULT!!
PyObject* add = obj->attr("__add__");
```
To determine whether an object has instance dict or not, you can use this snippet.
```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);
bool ok = !is_tagged(obj) && obj->is_attr_valid(); // false
```
### General access
As you can see, direct access does not take care of derived attributes or methods. In most cases, what you need is `getattr` and `setattr`.
These two methods handle all possible cases.
#### `PyObject* VM::getattr(PyObject* obj, StrName name, bool throw_err=true)`
This method is equivalent to `getattr` in python.
If the attribute is not found, it will return `nullptr` If the attribute is not found, it will return `nullptr`
or throw an `AttributeError` depending on the value of `throw_err`. or throw an `AttributeError` depending on the value of `throw_err`.
@ -25,7 +63,7 @@ int result = CAST(int, ret);
std::cout << result << std::endl; // 3 std::cout << result << std::endl; // 3
``` ```
#### `void setattr(PyObject*, StrName, PyObject*)` #### `void VM::setattr(PyObject*, StrName, PyObject*)`
This method is equivalent to `setattr` in Python. This method is equivalent to `setattr` in python.
It raises `TypeError` if the object does not support attribute assignment. It raises `TypeError` if the object does not support attribute assignment.

View File

@ -4,7 +4,9 @@ label: 'Call a Python function'
order: 70 order: 70
--- ---
Use these to call a python function. pkpy uses a variant of the [Vectorcall](https://peps.python.org/pep-0590/) protocol (PEP 590).
There are 2 methods for calling a python function.
+ `PyObject* VM::call(PyObject* obj, ...)` + `PyObject* VM::call(PyObject* obj, ...)`
+ `PyObject* VM::call_method(PyObject* obj, StrName name, ...)` + `PyObject* VM::call_method(PyObject* obj, StrName name, ...)`

View File

@ -205,7 +205,7 @@ class _MyAppState extends State<MyApp> {
# basic # basic
The following table shows the basic features of PocketPy with respect to [CPython](https://github.com/python/cpython). The following table shows the basic features of pkpy with respect to [cpython](https://github.com/python/cpython).
The features marked with `YES` are supported, and the features marked with `NO` are not supported. The features marked with `YES` are supported, and the features marked with `NO` are not supported.
| Name | Example | Supported | | Name | Example | Supported |

View File

@ -429,7 +429,7 @@ struct TupleExpr: SequenceExpr{
}else{ }else{
// starred assignment target must be in a tuple // starred assignment target must be in a tuple
if(items.size() == 1) return false; if(items.size() == 1) return false;
// starred assignment target must be the last one (differ from CPython) // starred assignment target must be the last one (differ from cpython)
if(starred_i != items.size()-1) return false; if(starred_i != items.size()-1) return false;
// a,*b = [1,2,3] // a,*b = [1,2,3]
// stack is [1,2,3] -> [1,[2,3]] // stack is [1,2,3] -> [1,[2,3]]