1
0
blueloveTH 2 жил өмнө
parent
commit
d513a3b459

+ 36 - 0
.github/workflows/website.yml

@@ -0,0 +1,36 @@
+name: website
+
+on:
+  push:
+    branches: [ main ]
+  pull_request:
+    branches: [ main ]
+
+jobs:
+  build_web:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v3
+    ###################################################
+    - uses: actions/setup-node@v3.1.1
+    - name: Retype build
+      run: |
+        npm install retypeapp --global
+        retype build
+    ###################################################
+    - name: Setup emsdk
+      uses: mymindstorm/setup-emsdk@v12
+      with:
+        version: 3.1.25
+        actions-cache-folder: 'emsdk-cache'
+    - name: Compile
+      run: |
+        python3 build.py web
+        mv web .retype/static
+    ###################################################
+    - uses: crazy-max/ghaction-github-pages@v3
+      with:
+        target_branch: gh-pages
+        build_dir: .retype
+      env:
+        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

+ 13 - 0
docs/C-API/general.md

@@ -0,0 +1,13 @@
+---
+title: General
+icon: dot
+order: 7
+---
+#### `void pkpy_delete(void* p)`
+
+Delete a pointer allocated by `pkpy_xxx_xxx`.
+It can be `VM*`, `REPL*`, `char*`, etc.
+
+!!!
+If the pointer is not allocated by `pkpy_xxx_xxx`, the behavior is undefined.
+!!!

+ 3 - 0
docs/C-API/index.yml

@@ -0,0 +1,3 @@
+label: C-API
+icon: code
+order: 1

+ 12 - 0
docs/C-API/repl.md

@@ -0,0 +1,12 @@
+---
+title: REPL
+icon: dot
+order: 8
+---
+#### `REPL* pkpy_new_repl(VM* vm)`
+
+Create a REPL, using the given virtual machine as the backend.
+
+#### `bool pkpy_repl_input(REPL* r, const char* line)`
+
+Input a source line to an interactive console. Return true if need more lines.

+ 38 - 0
docs/C-API/vm.md

@@ -0,0 +1,38 @@
+---
+title: VM
+icon: dot
+order: 10
+---
+#### `VM* pkpy_new_vm(bool use_stdio)`
+
+Create a virtual machine.
+
+#### `void pkpy_vm_add_module(VM* vm, const char* name, const char* source)`
+
+Add a source module into a virtual machine.
+
+#### `char* pkpy_vm_eval(VM* vm, const char* source)`
+
+Evaluate an expression.
+
+Return `__repr__` of the result.
+If there is any error, return `nullptr`.
+
+#### `void pkpy_vm_exec(VM* vm, const char* source)`
+
+Run a given source on a virtual machine.
+
+#### `char* pkpy_vm_get_global(VM* vm, const char* name)`
+
+Get a global variable of a virtual machine.
+
+Return `__repr__` of the result.
+If the variable is not found, return `nullptr`.
+
+#### `char* pkpy_vm_read_output(VM* vm)`
+
+Read the standard output and standard error as string of a virtual machine.
+The `vm->use_stdio` should be `false`.
+After this operation, both stream will be cleared.
+
+Return a json representing the result.

+ 99 - 0
docs/coding_style_guide.md

@@ -0,0 +1,99 @@
+---
+icon: book
+order: 2
+label: Coding Style Guide
+---
+
+# Coding Style Guide
+
+## Naming rules
+
+For class names, always use **PascalCase**
+
+```cpp
+// Correct
+class FooBar {};
+
+// Wrong
+class fooBar {};
+class foo_bar {};
+```
+
+For function and methods, use **snake_case**
+
+```cpp
+// Correct
+int test_func(int x) { return x+1; }
+
+// Wrong
+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.
+
+```cpp
+auto x = vm->None;
+vm->SyntaxError(...);
+vm->TypeError(...);
+vm->call(obj, __repr__);
+```
+
+For global constants, use **k** prefix with **PascalCase**
+
+```cpp
+const int kMaxCount = 10;
+const float kMinValue = 1.0;
+```
+
+For macros, use **SNAKE_CASE**
+
+```cpp
+#define FOO_BAR 1
+#define TEST(x) x+1
+```
+
+## 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.
+
+Use a single `_` as prefix to indicate a function or variable is for internal use.
+
+```cpp
+class FooBar {
+public:
+    int _count;
+    int inc() { _count+=1; }
+    void _clear() { _count=0; }
+}
+```
+
+`_` prefix is just a warning to remind you to use such members carefully.
+
+It does not forbid users to access internal members.
+
+## Use compact style
+
+Try to make the code compact if it does not affect readability.
+
+```cpp
+// Correct
+if(x == 1) break;
+
+// Wrong
+if(x == 1){
+	break;
+}
+```
+
+## For `shared_ptr<T>`
+
+Use a `_` suffix to indicate a type is a shared pointer.
+
+```cpp
+typedef shared_ptr<CodeObject> CodeObject_;
+CodeObject_ co = make_shared<CodeObject>();
+```
+

+ 32 - 0
docs/features/basic.md

@@ -0,0 +1,32 @@
+---
+icon: dot
+order: 100
+---
+
+# basic
+
+The following table shows the basic features of PocketPy 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.
+
+| Name            | Example                         | Supported |
+| --------------- | ------------------------------- | --------- |
+| If Else         | `if..else..elif`                | YES       |
+| Loop            | `for/while/break/continue`      | YES       |
+| Function        | `def f(x,*args,y=1):`           | YES       |
+| Subclass        | `class A(B):`                   | YES       |
+| List            | `[1, 2, 'a']`                   | YES       |
+| ListComp        | `[i for i in range(5)]`         | YES       |
+| Slice           | `a[1:2], a[:2], a[1:]`          | YES       |
+| Tuple           | `(1, 2, 'a')`                   | YES       |
+| Dict            | `{'a': 1, 'b': 2}`              | YES       |
+| F-String        | `f'value is {x}'`               | YES       |
+| Unpacking       | `a, b = 1, 2`                   | YES       |
+| Star Unpacking  | `a, *b = [1, 2, 3]`             | YES       |
+| Exception       | `raise/try..catch`              | YES       |
+| Dynamic Code    | `eval()/exec()`                 | YES       |
+| Reflection      | `hasattr()/getattr()/setattr()` | YES       |
+| Import          | `import/from..import`           | YES       |
+| Context Block   | `with <expr> as <id>:`          | YES       |
+| Type Annotation | `def  f(a:int, b:float=1)`      | YES       |
+| Generator       | `yield i`                       | YES       |
+| Decorator       | `@cache`                        | YES       |

+ 31 - 0
docs/features/goto.md

@@ -0,0 +1,31 @@
+---
+icon: dot
+---
+
+# goto/label
+
+PocketPy supports `goto` and `label` just like C. You are allowed to change the control flow unconditionally.
+
+## Syntax
+
+Labels are named a dot `.` and an identifier.
+
+```
+goto .<identifier>
+label .<identifier>
+```
+
+## Example
+
+```python
+for i in range(10):
+  for j in range(10):
+    for k in range(10):
+      goto .exit
+
+label .exit
+```
+
+!!!
+If we detect an illegal divert, you will get an `UnexpectedError` or the behaviour is undefined.
+!!!

+ 3 - 0
docs/features/index.yml

@@ -0,0 +1,3 @@
+icon: cpu
+order: 16
+label: "Features"

+ 30 - 0
docs/features/ternary.md

@@ -0,0 +1,30 @@
+---
+icon: dot
+---
+
+# ternary op
+
+Ternary operator is a short hand `if...else`.
+PocketPy supports both C and Python style ternary.
+
+
+## Syntax
+
+```
+<condition> ? <true_expr> : <false_expr>
+```
+
+```
+<true_expr> if <condition> else <false_expr>
+```
+
+## Example
+
+```python
+a = 1
+s = a == 1 ? "a is 1" : "a is not 1"
+print(s)    # a is 1
+
+# which equals to
+s = "a is 1" if a == 1 else "a is not 1"
+```

+ 35 - 0
docs/getting-started/c.md

@@ -0,0 +1,35 @@
+---
+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(true);
+    
+    // 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;
+}
+```

+ 151 - 0
docs/getting-started/cpp.md

@@ -0,0 +1,151 @@
+---
+icon: code
+label: 'C++'
+order: 10
+---
+
+For C++ developers, you can download the `pocketpy.h` on our GitHub release page.
+
+https://github.com/blueloveTH/pocketpy/releases/latest
+
+## Example
+
+```cpp
+#include "pocketpy.h"
+
+using namespace pkpy;
+
+int main(){
+    // Create a virtual machine
+    VM* vm = new VM(true);
+    
+    // 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 << py_cast<i64>(vm, result);   // 6
+    return 0;
+}
+```
+
+## Interop with `PyObject*`
+
+In PkPy, any python object is represented by a `PyObject*`.
+
++  `VAR(...)`,
+create a `PyObject*` from a C type
++ `CAST(T, ...)`,
+cast a `PyObject*` to a C type
++ `_CAST(T, ...)`,
+cast a `PyObject*` to a C type, without type check
+
+```cpp
+PyObject* x = VAR(12);		// cast a C int to PyObject*
+int y = CAST(int, x);		// cast a PyObject* to C int
+
+PyObject* i = VAR("abc");
+std::cout << CAST(Str, i);	// abc
+```
+
+#### Types
+
+| `PyObject` type | C type           | note                   |
+| ------------ | ---------------- | ---------------------- |
+| `int`        | `i64`            | 62 bits integer |
+| `float`      | `f64`            | 62 bits floating point |
+| `str`        | `pkpy::Str`      |                        |
+| `bool`       | `bool`           |                        |
+| `list`       | `pkpy::List`     |                        |
+| `tuple`      | `pkpy::Tuple`    |                        |
+| `function`   | `pkpy::Function` |                        |
+| ...          | ...              | ...                    |
+
+## Bind a Native Function
+
+In `VM` class, there are 4 methods to bind native function.
+
++ `VM::bind_func<ARGC>`
++ `VM::bind_builtin_func<ARGC>`
++ `VM::bind_method<ARGC>`
++ `VM::bind_static_method<ARGC>`
+
+They are all template methods, the template argument is a `int` number, indicating the argument count. For variadic arguments, use `-1`. For methods, `ARGC` do not include `self`.
+
+!!!
+
+Native functions do not support keyword arguments.
+
+!!!
+
+PkPy uses a universal C function pointer for native functions:
+
+```cpp
+typedef PyObject* (*NativeFuncC)(VM*, ArgsView);
+```
+
+The first argument is the pointer of `VM` instance.
+
+The second argument is a view of an array. You can use `[]` operator to get the element. If you have specified `ARGC` other than `-1`, the interpreter will ensure `args.size() == ARGC`. No need to do size check.
+
+The return value is a `PyObject*`, which should not be `nullptr`. If there is no return value, return `vm->None`.
+
+This is an example of binding the `input()` function to the `builtins` module.
+
+```cpp
+VM* vm = pkpy_new_vm(true);
+vm->bind_builtin_func<0>("input", [](VM* vm, ArgsView args){
+    static std::string line;
+    std::getline(std::cin, line);
+    return VAR(line);
+});
+
+//                        vvv function name
+vm->bind_builtin_func<2>("add", [](VM* vm, ArgsView args){
+    //                ^ argument count
+	i64 lhs = CAST(i64, args[0]);
+    i64 rhs = CAST(i64, args[1]);
+    return VAR(lhs + rhs);
+});
+```
+
+## Call a Python Function
+
+Use these to call a python function.
+
++ `PyObject* VM::call(PyObject* obj, ...)`
++ `PyObject* VM::call_method(PyObject* obj, StrName name, ...)`
+
+For example, to create a `dict` object,
+
+```cpp
+PyObject* tp = vm->builtins->attr("dict");
+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* ret = vm->call(obj, "__getitem__", VAR("a"));
+std::cout << CAST(int, ret) << std::endl; // 5
+```
+
+## Attribute Access
+
+There are 3 methods for this.
+
++ `PyObject* VM::getattr(PyObject*, StrName)`
++ `void VM::setattr(PyObject*, StrName, PyObject*)`
++ `PyObject* VM::get_unbound_method(PyObject*, StrName, PyObject**)`
+
+## Wrapping a `struct` as `PyObject`
+
+!!!
+
+This feature is unstable.
+
+!!!

+ 210 - 0
docs/getting-started/flutter.md

@@ -0,0 +1,210 @@
+---
+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')),
+          ),
+        ]),
+      ),
+    );
+  }
+}
+```
+

+ 39 - 0
docs/getting-started/godot.md

@@ -0,0 +1,39 @@
+---
+icon: code
+label: Godot Engine
+order: 2
+---
+
+## Introduction
+
+PocketPy for Godot is integrated via [GDExtension](https://godotengine.org/article/introducing-gd-extensions).
+
+!!!
+GDExtension is a Godot 4.0 feature. Godot 3.x won't work.
+!!!
+
+Please see https://github.com/blueloveTH/godot-cpp/tree/master/pocketpy for details.
+
+## Example
+
+```gdscript
+# main.gd
+
+extends Node
+
+func _ready():
+	# Create a virtual machine
+	var vm = pkpy.new_vm(false)
+
+	# Run a script
+	pkpy.vm_exec(vm, "print('Hello World!')")
+
+	# Read the output
+	var _o = pkpy.vm_read_output(vm)
+
+	# Parse the output
+	var res = JSON.parse_string(_o)
+
+	# Print the output
+	print(res["stdout"])    # "Hello World!\n"
+```

+ 3 - 0
docs/getting-started/index.yml

@@ -0,0 +1,3 @@
+icon: rocket
+expanded: true
+order: 20

+ 78 - 0
docs/getting-started/unity.md

@@ -0,0 +1,78 @@
+---
+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");
+    }
+}
+```
+

+ 41 - 0
docs/index.md

@@ -0,0 +1,41 @@
+---
+icon: home
+label: Welcome
+---
+
+# Welcome to PocketPy
+
+PocketPy is a lightweight(~8000 LOC) Python interpreter for game engines.
+
+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.
+
+## What it looks like
+
+```python
+def is_prime(x):
+  if x < 2:
+    return False
+  for i in range(2, x):
+    if x % i == 0:
+      return False
+  return True
+
+primes = [i for i in range(2, 20) if is_prime(i)]
+print(primes)
+# [2, 3, 5, 7, 11, 13, 17, 19]
+```
+
+## Source Integration
+
+We recommend to use our pre-built `pocketpy.h` in [Github Release](https://github.com/blueloveTH/pocketpy/releases/latest) page.
+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
+
+!!!
+You can use `g++`, `cl.exe` or `clang++` to compile your project.
+For maximum performance, we recommend to `clang++` with `-O2` flag.
+`clang++` can produce faster binary than `g++` or `cl.exe`.
+!!!

+ 33 - 0
docs/license.md

@@ -0,0 +1,33 @@
+---
+icon: verified
+order: 0
+label: License
+---
+
+# License
+
+PocketPy is licensed under the [MIT License](http://opensource.org/licenses/MIT).
+
+```
+MIT License
+
+Copyright (c) 2022 blueloveTH
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+```

+ 24 - 0
docs/modules/bisect.md

@@ -0,0 +1,24 @@
+---
+icon: package
+label: bisect
+---
+
+### `bisect.bisect_left(a, x)`
+
+Return the index where to insert item `x` in list `a`, assuming `a` is sorted.
+
+### `bisect.bisect_right(a, x)`
+
+Return the index where to insert item `x` in list `a`, assuming `a` is sorted.
+
+### `bisect.insort_left(a, x)`
+
+Insert item `x` in list `a`, and keep it sorted assuming `a` is sorted.
+
+If x is already in a, insert it to the left of the leftmost x.
+
+### `bisect.insort_right(a, x)`
+
+Insert item `x` in list `a`, and keep it sorted assuming `a` is sorted.
+
+If x is already in a, insert it to the right of the rightmost x.

+ 13 - 0
docs/modules/collections.md

@@ -0,0 +1,13 @@
+---
+icon: package
+label: collections
+---
+
+
+### `collections.Counter(iterable)`
+
+Return a `dict` containing the counts of each element in `iterable`.
+
+### `collections.deque`
+
+A double-ended queue.

+ 9 - 0
docs/modules/gc.md

@@ -0,0 +1,9 @@
+---
+icon: package
+label: gc
+---
+
+
+### `gc.collect()`
+
+Invoke the garbage collector.

+ 24 - 0
docs/modules/heapq.md

@@ -0,0 +1,24 @@
+---
+icon: package
+label: heapq
+---
+
+### `heapq.heappush(heap, item)`
+
+Push the value `item` onto the heap, maintaining the heap invariant.
+
+### `heapq.heappop(heap)`
+
+Pop and return the smallest item from the heap, maintaining the heap invariant. If the heap is empty, IndexError is raised. To access the smallest item without popping it, use `heap[0]`.
+
+### `heapq.heapify(x)`
+
+Transform list `x` into a heap, in-place, in linear time.
+
+### `heapq.heappushpop(heap, item)`
+
+Push `item` on the heap, then pop and return the smallest item from the heap. The combined action runs more efficiently than `heappush()` followed by a separate `heappop()`.
+
+### `heapq.heapreplace(heap, item)`
+
+Pop and return the smallest item from the heap, and also push the new item. The heap size doesn’t change. If the heap is empty, IndexError is raised.

+ 2 - 0
docs/modules/index.yml

@@ -0,0 +1,2 @@
+icon: package
+order: 10

+ 21 - 0
docs/modules/json.md

@@ -0,0 +1,21 @@
+---
+icon: package
+label: json
+---
+
+### `json.loads(s)`
+
+Decode a JSON string into a PocketPy object.
+
+It is supported by the `eval()` function.
+
+### `json.dumps(obj)`
+
+Encode a PocketPy object into a JSON string.
+
+It is supported by the compiler with `JSON_MODE` enabled.
+
+!!!
+There is a special method `__json__()` for object.
+If it is defined, it will be called when `json.dumps()` is called.
+!!!

+ 60 - 0
docs/modules/math.md

@@ -0,0 +1,60 @@
+---
+icon: package
+label: math
+---
+
+### `math.e`
+
+2.718281828459045
+
+### `math.pi`
+
+3.141592653589793
+
+### `math.log(x)`
+
+Return the natural logarithm of `x`.
+
+### `math.log10(x)`
+
+Return the base-10 logarithm of `x`.
+
+### `math.log2(x)`
+
+Return the base-2 logarithm of `x`.
+
+### `math.sin(x)`
+
+Return the sine of `x`.
+
+### `math.cos(x)`
+
+Return the cosine of `x`.
+
+### `math.tan(x)`
+
+Return the tangent of `x`.
+
+### `math.isnan(x)`
+
+Return `True` if `x` is a NaN (not a number), and `False` otherwise.
+
+### `math.isinf(x)`
+
+Return `True` if `x` is positive or negative infinity, and `False` otherwise.
+
+### `math.fabs(x)`
+
+Return the absolute value of `x`.
+
+### `math.floor(x)`
+
+Return the largest integer value less than or equal to `x`.
+
+### `math.ceil(x)`
+
+Return the smallest integer value greater than or equal to `x`.
+
+### `math.sqrt(x)`
+
+Return the square root of `x`.

+ 40 - 0
docs/modules/os.md

@@ -0,0 +1,40 @@
+---
+icon: package
+label: os
+---
+
+!!!
+This module is optional to be compiled.
+!!!
+
+### `os.getcwd()`
+
+Returns the current working directory.
+
+### `os.chdir(path: str)`
+
+Changes the current working directory to the given path.
+
+### `os.listdir(path: str)`
+
+Returns a list of files and directories in the given path.
+
+### `os.remove(path: str)`
+
+Removes the file at the given path.
+
+### `os.mkdir(path: str)`
+
+Creates a directory at the given path.
+
+### `os.rmdir(path: str)`
+
+Removes the directory at the given path.
+
+### `os.path.join(*paths: str)`
+
+Joins the given paths together.
+
+### `os.path.exists(path: str)`
+
+Check if the given path exists.

+ 28 - 0
docs/modules/random.md

@@ -0,0 +1,28 @@
+---
+icon: package
+label: random
+---
+
+### `random.seed(a)`
+
+Set the random seed.
+
+### `random.random()`
+
+Return a random float number in the range [0.0, 1.0).
+
+### `random.randint(a, b)`
+
+Return a random integer in the range [a, b].
+
+### `random.uniform(a, b)`
+
+Return a random float number in the range [a, b).
+
+### `random.choice(seq)`
+
+Return a random element from a sequence.
+
+### `random.shuffle(seq)`
+
+Shuffle a sequence inplace.

+ 21 - 0
docs/modules/re.md

@@ -0,0 +1,21 @@
+---
+icon: package
+label: re
+---
+
+### `re.match(pattern, string)`
+
+Return a match object if the string matches the pattern, and `None` otherwise. (force match at the beginning of the string)
+
+### `re.search(pattern, string)`
+
+Return a match object if the string matches the pattern, and `None` otherwise.
+
+### `re.split(pattern, string)`
+
+Split the string by the occurrences of the pattern.
+
+### `re.sub(pattern, repl, string)`
+
+Return a copy of the string with all occurrences of the pattern replaced by the replacement string.
+

+ 9 - 0
docs/modules/sys.md

@@ -0,0 +1,9 @@
+---
+icon: package
+label: sys
+---
+
+### `sys.version`
+
+The version of PocketPy.
+

+ 8 - 0
docs/modules/time.md

@@ -0,0 +1,8 @@
+---
+icon: package
+label: time
+---
+
+### `time.time()`
+
+Returns the current time in seconds since the epoch as a floating point number.

+ 48 - 0
docs/performance.md

@@ -0,0 +1,48 @@
+---
+icon: zap
+order: 1
+label: Performance
+---
+
+# Performance
+
+Currently, PocketPy is almost~ fast as CPython 3.8. Here is a benchmark result of a special commit.
+
+Benchmark files are located in `benchmarks/`.
+
+https://github.com/blueloveTH/pocketpy/actions/runs/4729609975/jobs/8392313856
+
+
+```
+Testing directory: benchmarks/
+> benchmarks/fib.py
+  cpython:  0.686955s (100%)
+  pocketpy: 0.652851s (95.04%)
+> benchmarks/loop_0.py
+  cpython:  0.315438s (100%)
+  pocketpy: 0.205589s (65.18%)
+> benchmarks/loop_1.py
+  cpython:  0.621474s (100%)
+  pocketpy: 0.347335s (55.89%)
+> benchmarks/loop_2.py
+  cpython:  0.842779s (100%)
+  pocketpy: 0.465181s (55.20%)
+> benchmarks/loop_3.py
+  cpython:  3.069278s (100%)
+  pocketpy: 1.455937s (47.44%)
+> benchmarks/primes.py
+  cpython:  6.848963s (100%)
+  pocketpy: 13.592313s (198.46%)
+> benchmarks/recursive.py
+  cpython:  0.020444s (100%)
+  pocketpy: 0.004801s (23.48%)
+> benchmarks/simple.py
+  cpython:  0.372713s (100%)
+  pocketpy: 0.273696s (73.43%)
+> benchmarks/sort.py
+  cpython:  0.324214s (100%)
+  pocketpy: 0.464951s (143.41%)
+> benchmarks/sum.py
+  cpython:  0.019418s (100%)
+  pocketpy: 0.004817s (24.80%)
+```

+ 32 - 0
docs/retype.yml

@@ -0,0 +1,32 @@
+input: .
+output: .retype
+url: https://pocketpy.dev
+branding:
+  title: PocketPy
+  label: v1.0
+  logo: "./static/logo.png"
+favicon: "./static/logo.png"
+meta:
+  title: " | A lightweight Python interpreter for game engines"
+links:
+  - text: "Home"
+    icon: home
+    link: ""
+  - text: "Live Demo"
+    icon: play
+    link: "./static/web/index.html"
+    target: blank
+  - text: "Github"
+    icon: mark-github
+    link: https://github.com/blueloveth/pocketpy
+    target: blank
+  - text: Issues
+    link: https://github.com/blueloveth/pocketpy/issues
+    icon: issue-opened
+    target: blank
+  - text: Discord
+    link: https://discord.gg/WWaq72GzXv
+    icon: comment-discussion
+    target: blank
+footer:
+  copyright: "&copy; Copyright {{ year }} - [blueloveTH](https://github.com/blueloveTH) - All rights reserved."

BIN
docs/static/logo.afphoto


BIN
docs/static/logo.png


BIN
docs/static/logo_flat.png