mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
...
...
This commit is contained in:
parent
07a0122f4b
commit
5765760cea
164
README.md
164
README.md
@ -1,4 +1,4 @@
|
|||||||
# PocketPy
|
# pocketpy: python interpreter in 1 file
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a title="Build" href="https://github.com/blueloveTH/pocketpy/actions/workflows" ><img src="https://github.com/blueloveTH/pocketpy/actions/workflows/main.yml/badge.svg" /></a>
|
<a title="Build" href="https://github.com/blueloveTH/pocketpy/actions/workflows" ><img src="https://github.com/blueloveTH/pocketpy/actions/workflows/main.yml/badge.svg" /></a>
|
||||||
@ -8,21 +8,57 @@
|
|||||||
<img alt="GitHub release" src="https://img.shields.io/github/release/blueloveth/pocketpy.svg"></a>
|
<img alt="GitHub release" src="https://img.shields.io/github/release/blueloveth/pocketpy.svg"></a>
|
||||||
<a title="Pub" href="https://pub.dev/packages/pocketpy" ><img src="https://img.shields.io/pub/v/pocketpy" /></a>
|
<a title="Pub" href="https://pub.dev/packages/pocketpy" ><img src="https://img.shields.io/pub/v/pocketpy" /></a>
|
||||||
</p>
|
</p>
|
||||||
PocketPy is a lightweight(~8000 LOC) Python interpreter for game engines/apps.
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
#### The first production-ready version is `v1.0.0`, which will be available soon.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**English |** [**简体中文**](README_zh.md)
|
**English |** [**简体中文**](README_zh.md)
|
||||||
|
|
||||||
|
pkpy is a lightweight(~8000 LOC) Python interpreter for game engine/apps, built on C++17 with STL.
|
||||||
|
|
||||||
It is extremely easy to embed. Including a compiler, optimizer and bytecode virtual machine. All of them are available in a single header file `pocketpy.h`, without external dependencies.
|
It is extremely easy to embed. Including a compiler, optimizer and bytecode virtual machine. All of them are available in a single header file `pocketpy.h`, without external dependencies.
|
||||||
|
|
||||||
Please see https://pocketpy.dev for details or try [Live Demo](https://pocketpy.dev/static/web/).
|
Please see https://pocketpy.dev for details or try [Live Demo](https://pocketpy.dev/static/web/).
|
||||||
|
|
||||||

|
## Quick start
|
||||||
|
|
||||||
|
Download the `pocketpy.h` on our GitHub release page.
|
||||||
|
And `#include` it in your project.
|
||||||
|
|
||||||
|
https://github.com/blueloveTH/pocketpy/releases/latest
|
||||||
|
|
||||||
|
### Compile flags
|
||||||
|
|
||||||
|
To compile it with your project, these flags must be set:
|
||||||
|
|
||||||
|
+ `--std=c++17` flag must be set
|
||||||
|
+ Exception must be enabled
|
||||||
|
+ RTTI is not required
|
||||||
|
|
||||||
|
!!!
|
||||||
|
For maximum performance, we recommend to use `clang++` with `-O2` flag.
|
||||||
|
!!!
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "pocketpy.h"
|
||||||
|
|
||||||
|
using namespace pkpy;
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
// Create a virtual machine
|
||||||
|
VM* vm = new VM();
|
||||||
|
|
||||||
|
// Hello world!
|
||||||
|
vm->exec("print('Hello world!')", "main.py", EXEC_MODE);
|
||||||
|
|
||||||
|
// Create a list
|
||||||
|
vm->exec("a = [1, 2, 3]", "main.py", EXEC_MODE);
|
||||||
|
|
||||||
|
// Eval the sum of the list
|
||||||
|
PyObject* result = vm->exec("sum(a)", "<eval>", EVAL_MODE);
|
||||||
|
std::cout << CAST(int, result); // 6
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@ -49,114 +85,6 @@ Please see https://pocketpy.dev for details or try [Live Demo](https://pocketpy.
|
|||||||
| Generator | `yield i` | YES |
|
| Generator | `yield i` | YES |
|
||||||
| Decorator | `@cache` | YES |
|
| Decorator | `@cache` | YES |
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
#### C/C++
|
|
||||||
|
|
||||||
For C/C++ developers, you can download the `pocketpy.h` on our GitHub release page.
|
|
||||||
|
|
||||||
https://github.com/blueloveTH/pocketpy/releases/latest
|
|
||||||
|
|
||||||
Check [C-API](https://pocketpy.dev/c-api/vm/) for references. For further customization, you can use [C++ API](https://pocketpy.dev/getting-started/cpp/).
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
#include "pocketpy.h"
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
// Create a virtual machine
|
|
||||||
auto vm = pkpy_new_vm();
|
|
||||||
|
|
||||||
// Hello world!
|
|
||||||
pkpy_vm_exec(vm, "print('Hello world!')");
|
|
||||||
|
|
||||||
// Create a list
|
|
||||||
pkpy_vm_exec(vm, "a = [1, 2, 3]");
|
|
||||||
|
|
||||||
// Eval the sum of the list
|
|
||||||
char* result = pkpy_vm_eval(vm, "sum(a)");
|
|
||||||
printf("%s", result); // 6
|
|
||||||
|
|
||||||
// Free the resources
|
|
||||||
pkpy_delete(result);
|
|
||||||
pkpy_delete(vm);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Unity Engine
|
|
||||||
|
|
||||||
PocketPy for Unity can be installed via Unity Asset Store.
|
|
||||||
|
|
||||||
https://assetstore.unity.com/packages/slug/241120
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class Test01 : MonoBehaviour
|
|
||||||
{
|
|
||||||
// Start is called before the first frame update
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
// Create a virtual machine
|
|
||||||
pkpy.VM vm = new pkpy.VM();
|
|
||||||
|
|
||||||
// Create a list
|
|
||||||
vm.exec("a = [1, 2, 3]");
|
|
||||||
|
|
||||||
// Eval the sum of the list
|
|
||||||
string result = vm.eval("sum(a)");
|
|
||||||
Debug.Log(result); // 6
|
|
||||||
|
|
||||||
// Print to the standard output
|
|
||||||
vm.exec("print(a)");
|
|
||||||
pkpy.PyOutput o = vm.read_output();
|
|
||||||
Debug.Log(o.stdout); // [1, 2, 3]
|
|
||||||
|
|
||||||
// Create a binding
|
|
||||||
vm.bind("builtins", "test", (double x) => x+1);
|
|
||||||
Debug.Log(vm.eval("test(3.14)")); // '4.14'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Flutter
|
|
||||||
|
|
||||||
Run the following script to install this plugin.
|
|
||||||
|
|
||||||
```
|
|
||||||
flutter pub add pocketpy
|
|
||||||
```
|
|
||||||
|
|
||||||
See https://pocketpy.dev/getting-started/flutter/
|
|
||||||
|
|
||||||
#### Pre-compiled Libs
|
|
||||||
|
|
||||||
You can download `artifact.zip` from [Github Release](https://github.com/blueloveTH/pocketpy/releases/latest) page. In this archive, there are pre-compiled libraries for many platforms. The file structure is as follows.
|
|
||||||
|
|
||||||
```
|
|
||||||
- android/
|
|
||||||
- arm64-v8a/
|
|
||||||
- libpocketpy.so
|
|
||||||
- armeabi-v7a/
|
|
||||||
- libpocketpy.so
|
|
||||||
- x86_64/
|
|
||||||
- libpocketpy.so
|
|
||||||
- linux/
|
|
||||||
- x86_64/
|
|
||||||
- pocketpy
|
|
||||||
- pocketpy.so
|
|
||||||
- macos/
|
|
||||||
- pocketpy.bundle/
|
|
||||||
- web/
|
|
||||||
- lib/
|
|
||||||
- pocketpy.js
|
|
||||||
- pocketpy.wasm
|
|
||||||
- windows/
|
|
||||||
- x86_64/
|
|
||||||
- pocketpy.dll
|
|
||||||
- pocketpy.exe
|
|
||||||
```
|
|
||||||
|
|
||||||
## Contribution
|
## Contribution
|
||||||
|
|
||||||
All kinds of contributions are welcome.
|
All kinds of contributions are welcome.
|
||||||
@ -183,5 +111,5 @@ Check our [Coding Style Guide](https://pocketpy.dev/coding_style_guide/) if you
|
|||||||
|
|
||||||
## 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).
|
||||||
|
|
||||||
|
134
README_zh.md
134
README_zh.md
@ -1,4 +1,4 @@
|
|||||||
# PocketPy
|
# pocketpy: python interpreter in 1 file
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a title="Build" href="https://github.com/blueloveTH/pocketpy/actions/workflows" ><img src="https://github.com/blueloveTH/pocketpy/actions/workflows/main.yml/badge.svg" /></a>
|
<a title="Build" href="https://github.com/blueloveTH/pocketpy/actions/workflows" ><img src="https://github.com/blueloveTH/pocketpy/actions/workflows/main.yml/badge.svg" /></a>
|
||||||
@ -8,46 +8,16 @@
|
|||||||
<img alt="GitHub release" src="https://img.shields.io/github/release/blueloveth/pocketpy.svg"></a>
|
<img alt="GitHub release" src="https://img.shields.io/github/release/blueloveth/pocketpy.svg"></a>
|
||||||
<a title="Pub" href="https://pub.dev/packages/pocketpy" ><img src="https://img.shields.io/pub/v/pocketpy" /></a>
|
<a title="Pub" href="https://pub.dev/packages/pocketpy" ><img src="https://img.shields.io/pub/v/pocketpy" /></a>
|
||||||
</p>
|
</p>
|
||||||
|
pocketpy是一个轻量级的Python解释器,为嵌入至游戏引擎而设计,基于C++17和STL。
|
||||||
PocketPy是一个轻量级的Python解释器,为嵌入至游戏引擎而设计。
|
|
||||||
|
|
||||||
它包含一个编译器和基于字节码的虚拟机,以及交互式命令窗的实现。所有功能均集成在单个头文件`pocketpy.h`中,不包含外部依赖项,能很方便地嵌入至你的应用。
|
它包含一个编译器和基于字节码的虚拟机,以及交互式命令窗的实现。所有功能均集成在单个头文件`pocketpy.h`中,不包含外部依赖项,能很方便地嵌入至你的应用。
|
||||||
|
|
||||||
你可以 [在浏览器中体验](https://pocketpy.dev/static/web/) PocketPy的交互式界面(REPL)。
|
你可以 [在浏览器中体验](https://pocketpy.dev/static/web/) pocketpy的交互式界面(REPL)。
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 支持的语法特性
|
|
||||||
|
|
||||||
| 特性 | 示例 | 支持 |
|
|
||||||
| ------------ | ------------------------------- | ---- |
|
|
||||||
| 分支 | `if..else..elif` | YES |
|
|
||||||
| 循环 | `for/while/break/continue` | YES |
|
|
||||||
| 函数 | `def f(x,*args,y=1):` | YES |
|
|
||||||
| 类与继承 | `class A(B):` | YES |
|
|
||||||
| 列表 | `[1, 2, 'a']` | YES |
|
|
||||||
| 列表生成式 | `[i for i in range(5)]` | YES |
|
|
||||||
| 切片 | `a[1:2], a[:2], a[1:]` | YES |
|
|
||||||
| 元组 | `(1, 2, 'a')` | YES |
|
|
||||||
| 字典 | `{'a': 1, 'b': 2}` | YES |
|
|
||||||
| 格式化字符串 | `f'value is {x}'` | YES |
|
|
||||||
| 序列解包 | `a, b = 1, 2` | YES |
|
|
||||||
| 异常 | `raise/try..catch` | YES |
|
|
||||||
| 动态分发 | `eval()/exec()` | YES |
|
|
||||||
| 反射 | `hasattr()/getattr()/setattr()` | YES |
|
|
||||||
| 导入模块 | `import/from..import` | YES |
|
|
||||||
| 上下文管理器 | `with <expr> as <id>:` | YES |
|
|
||||||
| 类型标注 | `def f(a:int, b:float=1)` | YES |
|
|
||||||
| 生成器 | `yield i` | YES |
|
|
||||||
| 装饰器 | `@cache` | YES |
|
|
||||||
|
|
||||||
## 快速上手
|
## 快速上手
|
||||||
|
|
||||||
根据你所使用的语言和平台选择对应的插件。
|
你可以在 [Github Release](https://github.com/blueloveTH/pocketpy/releases/latest) 页面下载`pocketpy.h`,
|
||||||
|
并加入到你的工程中。请参阅 https://pocketpy.dev 以获取更详细的文档。
|
||||||
#### C/C++
|
|
||||||
|
|
||||||
你可以在 [Github Release](https://github.com/blueloveTH/pocketpy/releases/latest) 页面下载`pocketpy.h`,并加入到你的工程中。请参考[C-API](https://pocketpy.dev/c-api/vm/)相关的说明,对于C++,你也可以使用`VM`类的方法操作虚拟机。
|
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#include "pocketpy.h"
|
#include "pocketpy.h"
|
||||||
@ -73,79 +43,29 @@ int main(){
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Unity Engine
|
## 支持的语法特性
|
||||||
|
|
||||||
你可以在Unity资源商店下载PocketPy的C#插件,支持Windows/MacOS/Android/iOS平台。
|
|
||||||
|
|
||||||
https://assetstore.unity.com/packages/slug/241120
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class Test01 : MonoBehaviour
|
|
||||||
{
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
// 创建一个虚拟机
|
|
||||||
pkpy.VM vm = new pkpy.VM();
|
|
||||||
|
|
||||||
// 构造一个列表
|
|
||||||
vm.exec("a = [1, 2, 3]");
|
|
||||||
|
|
||||||
// 对列表进行求和
|
|
||||||
string result = vm.eval("sum(a)");
|
|
||||||
Debug.Log(result); // 6
|
|
||||||
|
|
||||||
// 打印变量`a`,并读取标准输出
|
|
||||||
vm.exec("print(a)");
|
|
||||||
pkpy.PyOutput o = vm.read_output();
|
|
||||||
Debug.Log(o.stdout); // [1, 2, 3]
|
|
||||||
|
|
||||||
// 构造一个函数绑定
|
|
||||||
vm.bind("builtins", "test", (double x) => x+1);
|
|
||||||
Debug.Log(vm.eval("test(3.14)")); // '4.14'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Flutter
|
|
||||||
|
|
||||||
使用下列命令安装pocketpy的[Flutter插件](https://pub.dev/packages/pocketpy),支持Windows/Android/iOS/Web平台。
|
|
||||||
|
|
||||||
```
|
|
||||||
flutter pub add pocketpy
|
|
||||||
```
|
|
||||||
|
|
||||||
详细配置请参考 https://pocketpy.dev/getting-started/flutter/
|
|
||||||
|
|
||||||
#### 预编译库
|
|
||||||
|
|
||||||
你可以在 [Github Release](https://github.com/blueloveTH/pocketpy/releases/latest) 页面下载`artifact.zip`,这个压缩包中包含了一套预编译库。结构如下。
|
|
||||||
|
|
||||||
```
|
|
||||||
- android/
|
|
||||||
- arm64-v8a/
|
|
||||||
- libpocketpy.so
|
|
||||||
- armeabi-v7a/
|
|
||||||
- libpocketpy.so
|
|
||||||
- x86_64/
|
|
||||||
- libpocketpy.so
|
|
||||||
- linux/
|
|
||||||
- x86_64/
|
|
||||||
- pocketpy
|
|
||||||
- pocketpy.so
|
|
||||||
- macos/
|
|
||||||
- pocketpy.bundle/
|
|
||||||
- web/
|
|
||||||
- lib/
|
|
||||||
- pocketpy.js
|
|
||||||
- pocketpy.wasm
|
|
||||||
- windows/
|
|
||||||
- x86_64/
|
|
||||||
- pocketpy.dll
|
|
||||||
- pocketpy.exe
|
|
||||||
```
|
|
||||||
|
|
||||||
|
| 特性 | 示例 | 支持 |
|
||||||
|
| ------------ | ------------------------------- | ---- |
|
||||||
|
| 分支 | `if..else..elif` | YES |
|
||||||
|
| 循环 | `for/while/break/continue` | YES |
|
||||||
|
| 函数 | `def f(x,*args,y=1):` | YES |
|
||||||
|
| 类与继承 | `class A(B):` | YES |
|
||||||
|
| 列表 | `[1, 2, 'a']` | YES |
|
||||||
|
| 列表生成式 | `[i for i in range(5)]` | YES |
|
||||||
|
| 切片 | `a[1:2], a[:2], a[1:]` | YES |
|
||||||
|
| 元组 | `(1, 2, 'a')` | YES |
|
||||||
|
| 字典 | `{'a': 1, 'b': 2}` | YES |
|
||||||
|
| 格式化字符串 | `f'value is {x}'` | YES |
|
||||||
|
| 序列解包 | `a, b = 1, 2` | YES |
|
||||||
|
| 异常 | `raise/try..catch` | YES |
|
||||||
|
| 动态分发 | `eval()/exec()` | YES |
|
||||||
|
| 反射 | `hasattr()/getattr()/setattr()` | YES |
|
||||||
|
| 导入模块 | `import/from..import` | YES |
|
||||||
|
| 上下文管理器 | `with <expr> as <id>:` | YES |
|
||||||
|
| 类型标注 | `def f(a:int, b:float=1)` | YES |
|
||||||
|
| 生成器 | `yield i` | YES |
|
||||||
|
| 装饰器 | `@cache` | YES |
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ icon: home
|
|||||||
label: Welcome
|
label: Welcome
|
||||||
---
|
---
|
||||||
|
|
||||||
# Welcome to PocketPy
|
# Welcome to pocketpy
|
||||||
|
|
||||||
pkpy is a lightweight(~8000 LOC) Python interpreter for game engine/apps.
|
pkpy is a lightweight(~8000 LOC) Python interpreter for game engine/apps.
|
||||||
|
|
||||||
|
BIN
docs/plugins.zip
Normal file
BIN
docs/plugins.zip
Normal file
Binary file not shown.
@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
icon: code
|
|
||||||
label: 'C'
|
|
||||||
order: 5
|
|
||||||
---
|
|
||||||
|
|
||||||
For C developers, you can download the `pocketpy.h` on our GitHub release page.
|
|
||||||
|
|
||||||
https://github.com/blueloveTH/pocketpy/releases/latest
|
|
||||||
|
|
||||||
## Basic Example
|
|
||||||
|
|
||||||
```c
|
|
||||||
#include "pocketpy.h"
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
// Create a virtual machine
|
|
||||||
auto vm = pkpy_new_vm();
|
|
||||||
|
|
||||||
// Hello world!
|
|
||||||
pkpy_vm_exec(vm, "print('Hello world!')");
|
|
||||||
|
|
||||||
// Create a list
|
|
||||||
pkpy_vm_exec(vm, "a = [1, 2, 3]");
|
|
||||||
|
|
||||||
// Eval the sum of the list
|
|
||||||
char* result = pkpy_vm_eval(vm, "sum(a)");
|
|
||||||
printf("%s", result); // 6
|
|
||||||
|
|
||||||
// Free the resources
|
|
||||||
pkpy_delete(result);
|
|
||||||
pkpy_delete(vm);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
```
|
|
@ -1,210 +0,0 @@
|
|||||||
---
|
|
||||||
icon: code
|
|
||||||
label: Flutter
|
|
||||||
order: 3
|
|
||||||
---
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a title="Pub" href="https://pub.dev/packages/pocketpy" ><img src="https://img.shields.io/pub/v/pocketpy" /></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
This plugin provides object-oriented interfaces including full functionality of PocketPy [C-API](https://pocketpy.dev/c-api/vm).
|
|
||||||
|
|
||||||
Run the following script to install this plugin.
|
|
||||||
|
|
||||||
```
|
|
||||||
flutter pub add pocketpy
|
|
||||||
```
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
#### For Android
|
|
||||||
|
|
||||||
You may need to set the Android NDK version to "21.4.7075529" or higher in `android/app/build.gradle`.
|
|
||||||
```
|
|
||||||
android {
|
|
||||||
ndkVersion "21.4.7075529"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### For iOS
|
|
||||||
|
|
||||||
It should work without any setup.
|
|
||||||
|
|
||||||
#### For Web
|
|
||||||
|
|
||||||
Download an artifact from https://github.com/blueloveTH/pocketpy/releases/latest.
|
|
||||||
|
|
||||||
Unzip it and copy `web/lib` into your root folder where `index.html` locates.
|
|
||||||
|
|
||||||
```
|
|
||||||
...
|
|
||||||
lib/pocketpy.js
|
|
||||||
lib/pocketpy.wasm
|
|
||||||
index.html
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
Then open `index.html` and add this line before `flutter.js` tag.
|
|
||||||
|
|
||||||
```
|
|
||||||
...
|
|
||||||
<!-- This script initializes WASM of pocketpy -->
|
|
||||||
<script src="./lib/pocketpy.js"></script>
|
|
||||||
|
|
||||||
<!-- This script adds the flutter initialization JS code -->
|
|
||||||
<script src="flutter.js" defer></script>
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
#### For Windows
|
|
||||||
|
|
||||||
VS2017 or higher is required to build the windows `.dll`.
|
|
||||||
Make sure you have C++ component installed.
|
|
||||||
|
|
||||||
|
|
||||||
## Basic Example
|
|
||||||
|
|
||||||
```dart
|
|
||||||
import 'package:pocketpy/pocketpy.dart' as pkpy;
|
|
||||||
|
|
||||||
// Create a virtual machine
|
|
||||||
pkpy.VM vm = pkpy.VM();
|
|
||||||
|
|
||||||
// Run a script
|
|
||||||
String code = 'print("Hello World!")';
|
|
||||||
vm.exec(code);
|
|
||||||
|
|
||||||
// Read the output
|
|
||||||
var _o = vm.read_output();
|
|
||||||
print(_o.stdout) // "Hello world!\n"
|
|
||||||
print(_o.stderr) // ""
|
|
||||||
|
|
||||||
// Create a binding
|
|
||||||
vm.bind<int>("builtins", "add", (int x, int y) => x + y);
|
|
||||||
vm.eval("add(1, 2)"); // '3'
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## REPL Widget Example
|
|
||||||
|
|
||||||
```dart
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:pocketpy/pocketpy.dart' as pkpy;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
runApp(const MaterialApp(home: MyApp()));
|
|
||||||
}
|
|
||||||
|
|
||||||
class MyApp extends StatefulWidget {
|
|
||||||
const MyApp({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<MyApp> createState() => _MyAppState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MyAppState extends State<MyApp> {
|
|
||||||
late final pkpy.VM vm;
|
|
||||||
late final pkpy.REPL repl;
|
|
||||||
bool needMoreLines = false;
|
|
||||||
|
|
||||||
final TextEditingController _controller = TextEditingController();
|
|
||||||
final StringBuffer buffer = StringBuffer();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
|
|
||||||
// create a pocketpy virtual machine
|
|
||||||
vm = pkpy.VM();
|
|
||||||
|
|
||||||
// create a REPL
|
|
||||||
repl = pkpy.REPL(vm);
|
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
|
||||||
refresh();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void addMessage(String text) {
|
|
||||||
setState(() {
|
|
||||||
buffer.write(text);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void submitCode() {
|
|
||||||
var text = _controller.text;
|
|
||||||
_controller.clear();
|
|
||||||
setState(() {
|
|
||||||
buffer.write(needMoreLines ? '... $text' : '>>> $text\n');
|
|
||||||
});
|
|
||||||
|
|
||||||
needMoreLines = repl.input(text);
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
void refresh() {
|
|
||||||
// ignore: no_leading_underscores_for_local_identifiers
|
|
||||||
var _o = vm.read_output();
|
|
||||||
if (_o.stdout.isNotEmpty) buffer.write(_o.stdout);
|
|
||||||
if (_o.stderr.isNotEmpty) buffer.write(_o.stderr);
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var style = const TextStyle(fontSize: 16);
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
title: const Text('Demo'),
|
|
||||||
),
|
|
||||||
body: Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
|
||||||
Expanded(
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
reverse: true,
|
|
||||||
child: Text(
|
|
||||||
buffer.toString(),
|
|
||||||
style: style,
|
|
||||||
textAlign: TextAlign.left,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 50,
|
|
||||||
child: TextFormField(
|
|
||||||
controller: _controller,
|
|
||||||
style: style,
|
|
||||||
maxLines: 1,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
border: OutlineInputBorder(),
|
|
||||||
hintText: 'Enter Python code',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
height: 60,
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
child: MaterialButton(
|
|
||||||
onPressed: submitCode,
|
|
||||||
color: Colors.blue,
|
|
||||||
textColor: Colors.white,
|
|
||||||
child: const Text('Run')),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
|||||||
---
|
|
||||||
icon: code
|
|
||||||
label: Unity Engine
|
|
||||||
order: 4
|
|
||||||
---
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
PocketPy for Unity can be installed via Unity Asset Store.
|
|
||||||
|
|
||||||
https://assetstore.unity.com/packages/slug/241120
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example 01
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class Test01 : MonoBehaviour
|
|
||||||
{
|
|
||||||
// Start is called before the first frame update
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
// Create a virtual machine
|
|
||||||
pkpy.VM vm = new pkpy.VM();
|
|
||||||
|
|
||||||
// Create a list
|
|
||||||
vm.exec("a = [1, 2, 3]");
|
|
||||||
|
|
||||||
// Eval the sum of the list
|
|
||||||
string result = vm.eval("sum(a)");
|
|
||||||
Debug.Log(result); // 6
|
|
||||||
|
|
||||||
// Print to the standard output
|
|
||||||
vm.exec("print(a)");
|
|
||||||
pkpy.PyOutput o = vm.read_output();
|
|
||||||
Debug.Log(o.stdout); // [1, 2, 3]
|
|
||||||
|
|
||||||
// Create a binding
|
|
||||||
vm.bind("builtins", "test", (double x) => x+1);
|
|
||||||
Debug.Log(vm.eval("test(3.14)")); // '4.14'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Example 02
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
public class Test02 : MonoBehaviour
|
|
||||||
{
|
|
||||||
Text text;
|
|
||||||
pkpy.VM vm;
|
|
||||||
|
|
||||||
// Start is called before the first frame update
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
text = GetComponent<Text>();
|
|
||||||
Application.targetFrameRate = 60;
|
|
||||||
vm = new pkpy.VM();
|
|
||||||
vm.exec("a = 0");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update is called once per frame
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
if(vm == null) return;
|
|
||||||
vm.exec("a += 1");
|
|
||||||
text.text = vm.eval("a");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
icon: code
|
icon: dot
|
||||||
label: 'Access attributes'
|
label: 'Access attributes'
|
||||||
order: 80
|
order: 80
|
||||||
---
|
---
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
icon: code
|
icon: dot
|
||||||
label: 'Bind native function'
|
label: 'Bind native function'
|
||||||
order: 60
|
order: 60
|
||||||
---
|
---
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
icon: code
|
icon: dot
|
||||||
label: 'Call Python function'
|
label: 'Call Python function'
|
||||||
order: 70
|
order: 70
|
||||||
---
|
---
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
icon: code
|
icon: dot
|
||||||
label: 'Execute Python code'
|
label: 'Execute Python code'
|
||||||
order: 93
|
order: 93
|
||||||
---
|
---
|
||||||
@ -17,7 +17,7 @@ Once you have a `VM` instance, you can execute python code by calling `exec` met
|
|||||||
If the execution is not successful, e.g. a syntax error or a runtime exception,
|
If the execution is not successful, e.g. a syntax error or a runtime exception,
|
||||||
the return value will be `nullptr`.
|
the return value will be `nullptr`.
|
||||||
|
|
||||||
#### Compile mode
|
### Compile mode
|
||||||
|
|
||||||
The `mode` parameter controls how the source code is compiled. There are 4 possible values:
|
The `mode` parameter controls how the source code is compiled. There are 4 possible values:
|
||||||
+ `EXEC_MODE`, this is the default mode. Just do normal execution.
|
+ `EXEC_MODE`, this is the default mode. Just do normal execution.
|
||||||
|
@ -1,22 +1,15 @@
|
|||||||
---
|
---
|
||||||
icon: code
|
icon: dot
|
||||||
label: 'Installation'
|
label: 'Installation'
|
||||||
order: 100
|
order: 100
|
||||||
---
|
---
|
||||||
|
|
||||||
You need to download `pocketpy.h` on our GitHub release page.
|
Download the `pocketpy.h` on our GitHub release page.
|
||||||
And `#include` it in your project.
|
And `#include` it in your project.
|
||||||
|
|
||||||
https://github.com/blueloveTH/pocketpy/releases/latest
|
https://github.com/blueloveTH/pocketpy/releases/latest
|
||||||
|
|
||||||
Alternatively, you can install it via vcpkg.io.
|
### Compile flags
|
||||||
(Will be available soon)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
vcpkg install pocketpy
|
|
||||||
```
|
|
||||||
|
|
||||||
## Compile flags
|
|
||||||
|
|
||||||
To compile it with your project, these flags must be set:
|
To compile it with your project, these flags must be set:
|
||||||
|
|
||||||
@ -28,7 +21,7 @@ To compile it with your project, these flags must be set:
|
|||||||
For maximum performance, we recommend to use `clang++` with `-O2` flag.
|
For maximum performance, we recommend to use `clang++` with `-O2` flag.
|
||||||
!!!
|
!!!
|
||||||
|
|
||||||
## Example
|
### Example
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#include "pocketpy.h"
|
#include "pocketpy.h"
|
||||||
@ -37,7 +30,7 @@ using namespace pkpy;
|
|||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
// Create a virtual machine
|
// Create a virtual machine
|
||||||
VM* vm = new VM(true);
|
VM* vm = new VM();
|
||||||
|
|
||||||
// Hello world!
|
// Hello world!
|
||||||
vm->exec("print('Hello world!')", "main.py", EXEC_MODE);
|
vm->exec("print('Hello world!')", "main.py", EXEC_MODE);
|
||||||
@ -51,3 +44,30 @@ int main(){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
pkpy's C++ interfaces are organized in an object-oriented way.
|
||||||
|
All classes are located in `pkpy` namespace.
|
||||||
|
|
||||||
|
The most important class is the `VM` class. A `VM` instance is a python virtual machine which holds all necessary runtime states, including callstacks, modules, variables, etc.
|
||||||
|
|
||||||
|
You need to use the C++ `new` operator to create a `VM` instance.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
VM* vm = new VM();
|
||||||
|
```
|
||||||
|
|
||||||
|
The constructor can take 2 extra parameters.
|
||||||
|
|
||||||
|
#### `VM(bool use_stdio=true, bool enable_os=true)`
|
||||||
|
|
||||||
|
+ `use_stdio`, if `true`, the `print()` function outputs string to `stdout`. Error messages will be send to `stderr`; If `false`, they will be sent to an internal buffer. In the latter case, you need to read them via `read_output` manually.
|
||||||
|
+ `enable_os`, whether to enable OS-related features or not. This setting controls the availability of some priviledged modules such os `io` and `os` as well as builtin function `open`.
|
||||||
|
|
||||||
|
|
||||||
|
When you are done with the `VM` instance, you need to use the C++ `delete` operator to free the memory.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
delete vm;
|
||||||
|
```
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
icon: code
|
icon: dot
|
||||||
label: 'Interop with PyObject'
|
label: 'Interop with PyObject'
|
||||||
order: 90
|
order: 90
|
||||||
---
|
---
|
||||||
@ -22,7 +22,7 @@ PyObject* i = VAR("abc");
|
|||||||
std::cout << CAST(Str, i); // abc
|
std::cout << CAST(Str, i); // abc
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Types
|
### Types
|
||||||
|
|
||||||
| python type | C type | note |
|
| python type | C type | note |
|
||||||
| ------------ | ---------------- | ---------------------- |
|
| ------------ | ---------------- | ---------------------- |
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
---
|
|
||||||
icon: code
|
|
||||||
label: 'Overview'
|
|
||||||
order: 95
|
|
||||||
---
|
|
||||||
|
|
||||||
pkpy's C++ interfaces are organized in an object-oriented way.
|
|
||||||
All classes are located in `pkpy` namespace.
|
|
||||||
|
|
||||||
The most important class is the `VM` class. A `VM` instance is a python virtual machine which holds all necessary runtime states, including callstacks, modules, variables, etc.
|
|
||||||
|
|
||||||
You need to use the C++ `new` operator to create a `VM` instance.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
VM* vm = new VM();
|
|
||||||
```
|
|
||||||
|
|
||||||
The constructor can take 2 extra parameters.
|
|
||||||
|
|
||||||
#### `VM(bool use_stdio=true, bool enable_os=true)`
|
|
||||||
|
|
||||||
+ `use_stdio`, if `true`, the `print()` function outputs string to `stdout`. Error messages will be send to `stderr`; If `false`, they will be sent to an internal buffer. In the latter case, you need to read them via `read_output` manually.
|
|
||||||
+ `enable_os`, whether to enable OS-related features or not. This setting controls the availability of some priviledged modules such os `io` and `os` as well as builtin function `open`.
|
|
||||||
|
|
||||||
|
|
||||||
When you are done with the `VM` instance, you need to use the C++ `delete` operator to free the memory.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
delete vm;
|
|
||||||
```
|
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
icon: code
|
icon: dot
|
||||||
label: 'Wrap native struct'
|
label: 'Wrap native struct'
|
||||||
order: 50
|
order: 50
|
||||||
---
|
---
|
||||||
@ -77,7 +77,7 @@ struct Vector2 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
VM* vm = new VM(true);
|
VM* vm = new VM();
|
||||||
// create a new module `test`
|
// create a new module `test`
|
||||||
PyObject* mod = vm->new_module("test");
|
PyObject* mod = vm->new_module("test");
|
||||||
// register `Vector2` to `test` module
|
// register `Vector2` to `test` module
|
||||||
|
@ -2,12 +2,12 @@ input: .
|
|||||||
output: .retype
|
output: .retype
|
||||||
url: https://pocketpy.dev
|
url: https://pocketpy.dev
|
||||||
branding:
|
branding:
|
||||||
title: PocketPy
|
title: pocketpy
|
||||||
label: v1.0
|
label: v1.0
|
||||||
logo: "./static/logo.png"
|
# logo: "./static/logo.png"
|
||||||
favicon: "./static/logo.png"
|
# favicon: "./static/logo.png"
|
||||||
meta:
|
meta:
|
||||||
title: " | A lightweight Python interpreter for game engines"
|
title: " | Open Source Python interpreter in 1 file"
|
||||||
links:
|
links:
|
||||||
- text: "Home"
|
- text: "Home"
|
||||||
icon: home
|
icon: home
|
||||||
|
BIN
docs/sample.png
BIN
docs/sample.png
Binary file not shown.
Before Width: | Height: | Size: 45 KiB |
BIN
docs/static/logo.png
vendored
BIN
docs/static/logo.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 13 KiB |
BIN
docs/static/logo_flat.png
vendored
BIN
docs/static/logo_flat.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 42 KiB |
4
src/vm.h
4
src/vm.h
@ -890,9 +890,7 @@ inline PyObject* VM::_py_call(PyObject** p0, PyObject* callable, ArgsView args,
|
|||||||
// if this function is simple, a.k.a, no kwargs and no *args and not a generator
|
// if this function is simple, a.k.a, no kwargs and no *args and not a generator
|
||||||
// we can use a fast path to avoid using buffer copy
|
// we can use a fast path to avoid using buffer copy
|
||||||
if(fn.is_simple){
|
if(fn.is_simple){
|
||||||
#if DEBUG_EXTRA_CHECK
|
if(args.size() > fn.decl->args.size()) TypeError("too many positional arguments");
|
||||||
for(PyObject** p=p0; p<args.begin(); p++) *p = nullptr;
|
|
||||||
#endif
|
|
||||||
int spaces = co->varnames.size() - fn.decl->args.size();
|
int spaces = co->varnames.size() - fn.decl->args.size();
|
||||||
for(int j=0; j<spaces; j++) PUSH(nullptr);
|
for(int j=0; j<spaces; j++) PUSH(nullptr);
|
||||||
callstack.emplace(&s_data, p0, co, _module, callable, FastLocals(co, args.begin()));
|
callstack.emplace(&s_data, p0, co, _module, callable, FastLocals(co, args.begin()));
|
||||||
|
@ -33,3 +33,23 @@ assert b == [2, 3, 4]
|
|||||||
a, *b = [1]
|
a, *b = [1]
|
||||||
assert a == 1
|
assert a == 1
|
||||||
assert b == []
|
assert b == []
|
||||||
|
|
||||||
|
# test perfect forwarding
|
||||||
|
def f0(a, b, *args):
|
||||||
|
return a + b + sum(args)
|
||||||
|
|
||||||
|
x = f0(1, 2, 3, 4)
|
||||||
|
assert x == 10
|
||||||
|
|
||||||
|
a = [1, 2, 3, 4]
|
||||||
|
x = f0(*a)
|
||||||
|
assert x == 10
|
||||||
|
|
||||||
|
def f1(a):
|
||||||
|
return a
|
||||||
|
|
||||||
|
try:
|
||||||
|
x = f1(*[1, 2, 3, 4])
|
||||||
|
exit(1)
|
||||||
|
except TypeError:
|
||||||
|
pass
|
Loading…
x
Reference in New Issue
Block a user