# 扩展开发

## 功能

BT 扩展系统用于把项目目录中的 `.bts` 扩展包加载到当前 VM。扩展包放在项目根目录的 `extensions/` 下，启动时按文件名顺序扫描，校验 `manifest.json` 和 `bindings.json` 后，把公开入口注入到用户全局环境。

当前版本处于扩展系统开发阶段：已经完成 `.bts` 包校验、扩展注册表、VM 全局入口注入、扩展函数值、扩展对象值、对象方法分发和 `kind=bt / bts-bt-1` 纯 BT Runner。`kind=wasm / bts-wasi-1` 执行后端仍在后续开发中。

## 语法

项目结构：

```text
project/
├── main.bt
└── extensions/
    └── calc.bts
```

脚本中直接调用扩展公开入口：

```bt
result = calc(1).add(2).value()

// 输出：3
print result
```

## 参数

扩展入口和方法的参数由扩展包内 `bindings.json` 声明。

`bindings.json` 第一版支持的参数类型：

```text
empty
null
bool
int
float
string
bytes
array
object
```

参数 `role` 当前用于声明宿主侧预处理语义：

```text
value
path_read
path_write
path_dir
```

路径角色会校验扩展 manifest 中对应的文件权限声明；真实路径转换和 WASI 预打开目录会在后续路径阶段完成。

## 返回值

扩展入口可以返回普通 BT 数据，也可以返回扩展对象。扩展对象的方法继续通过点号链式调用。

```bt
value = calc(10).add(5).value()

// 输出：15
print value
```

扩展入口属于用户全局环境：

```bt
result = [has_env('calc'), has_envs('calc')]

// 输出：[true,false]
print result
```

## 代码示例

示例 `manifest.json`：

```json
{
    "format": "bts",
    "format_version": 1,
    "name": "calc_pkg",
    "version": "1.0.0",
    "kind": "bt",
    "abi": "bts-bt-1",
    "bt_min_version": "1.1.0",
    "api_version": 1,
    "entry": "src/lib.bt",
    "bindings": "bindings.json",
    "permissions": {
        "fs_read": false,
        "fs_write": false,
        "net": false,
        "http": false,
        "process": false,
        "env": false
    }
}
```

示例 `bindings.json`：

```json
{
    "api_version": 1,
    "functions": [
        {
            "name": "calc",
            "id": 1,
            "params": [
                { "name": "value", "type": "int" }
            ],
            "returns": "Calc"
        }
    ],
    "objects": [
        {
            "name": "Calc",
            "type_id": 1,
            "methods": [
                {
                    "name": "add",
                    "id": 2,
                    "params": [
                        { "name": "value", "type": "int" }
                    ],
                    "returns": "Calc"
                },
                {
                    "name": "value",
                    "id": 3,
                    "params": [],
                    "returns": "int"
                }
            ]
        }
    ]
}
```

示例 `src/lib.bt`：

```bt
class Calc {
    value_num: 0

    new(value) {
        this.value_num = value
        this
    }

    pub add(value) {
        this.value_num = this.value_num + value
        this
    }

    pub value() {
        this.value_num
    }
}

fn calc(value) {
    Calc::new(value)
}
```

BT 调用：

```bt
result = calc(1).add(2).value()

// 输出：3
print result
```

## 注意事项

- 当前构建必须启用 `extensions` feature 才能加载项目 `extensions/` 目录；未启用时，如果项目存在 `extensions/`，启动会报错。
- 扩展入口注入后是全局常量，脚本不能重新赋值。
- `env('calc')` 可以读取扩展入口，`has_env('calc')` 返回 `true`。
- `envs('calc')` 和 `has_envs('calc')` 只表示系统函数和系统常量，不会把扩展入口当作系统能力。
- 纯 BT 扩展加载阶段只解析、校验和编译入口源码，不会执行入口顶层代码。
- 纯 BT 入口顶层只允许 `fn`、`class`、空语句和大写常量的字面量初始化；不要在顶层写 `include`、普通赋值、循环、I/O 调用、`return` 或 `throw`。
- 纯 BT 扩展返回 bindings 对象类型时，应返回普通对象或类实例；对象方法由 Runner 内部 VM 执行。
- `kind=wasm` 扩展包可以通过 manifest/bindings 校验，但当前版本尚未实现 WASM Runner，调用时会报错。
- 扩展对象第一版不支持进入 `task()` 快照。
