Skip to content

xiaozuhui/aether-go

Repository files navigation

Aether Go 绑定

Aether DSL 语言的 Go 语言绑定。

安装

1. 安装 Go 模块

go get github.com/xiaozuhui/aether-go@latest

2. 下载预编译库

macOS 用户

首次使用时,在你的项目目录中运行以下命令下载预编译库:

go run github.com/xiaozuhui/aether-go/cmd/fetch@latest

该命令会:

  • 自动检测你的 macOS 架构(Apple Silicon 或 Intel)
  • 从 GitHub Releases 下载对应的预编译库
  • 将库文件保存到项目的 lib/ 目录

支持的平台:

  • macOS (Apple Silicon - arm64)
  • macOS (Intel - amd64)

其他平台用户

目前仅提供 macOS 平台的预编译库。如果你使用 Linux 或 Windows,需要从源码编译 Aether Rust 库:

# 1. 克隆 Aether 仓库
git clone https://github.com/xiaozuhui/aether.git
cd aether

# 2. 构建 Rust 库
cargo build --release

# 3. 复制到你的 Go 项目
mkdir -p lib/
cp target/release/libaether.a /path/to/your/project/lib/

下载或编译完成后,即可在代码中使用 aether-go。

3. 在代码中使用

import aether "github.com/xiaozuhui/aether-go"

func main() {
    engine := aether.New()
    defer engine.Close()

    result, err := engine.Eval("Set X 10\n(X + 20)")
    if err != nil {
        panic(err)
    }
    fmt.Println(result) // 30
}

构建依赖说明

此包需要 Aether Rust 静态库(libaether.a 文件)。有两种方式获取:

方式 1: 使用 fetch 工具(推荐,仅限 macOS)

go run github.com/xiaozuhui/aether-go/cmd/fetch@latest

支持的平台:

  • ✅ macOS (Apple Silicon - arm64)
  • ✅ macOS (Intel - amd64)
  • ❌ Linux (需要自行编译)
  • ❌ Windows (需要自行编译)

方式 2: 从源码构建

如果你使用 Linux 或 Windows,或者想要自定义编译选项,可以从源码构建:

# 克隆 Aether 仓库
git clone https://github.com/xiaozuhui/aether.git
cd aether

# 构建 Rust 库
cargo build --release

# 复制到项目 lib 目录
mkdir -p lib/
cp target/release/libaether.a lib/

注意: Windows 系统构建的文件名通常是 aether.lib 而不是 libaether.a

特性

线程安全: 完全的并发安全,使用 sync.RWMutex 保护 ✅ 变量操作: 从 Go 设置/获取变量 ✅ 追踪与调试: 结构化日志和执行追踪 ✅ 执行限制: 控制资源使用 ✅ 缓存控制: AST 缓存与统计 ✅ 优化: 可配置的优化选项 ✅ 易于集成: 简洁、符合 Go 习惯的 API

快速开始

基本示例

package main

import (
    "fmt"
    "log"

    "github.com/xiaozuhui/aether-go"
)

func main() {
    // 创建一个新的 Aether 引擎
    engine := aether.New()
    defer engine.Close()

    // 执行一些代码
    code := `
        Set X 10
        Set Y 20
        (X + Y)
    `

    result, err := engine.Eval(code)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("结果:", result) // 输出: 结果: 30
}

启用 IO 权限

// 创建启用 IO 权限的引擎
engine := aether.NewWithPermissions()
defer engine.Close()

code := `
    Set DATA (READ_FILE("data.txt"))
    Print "数据:", DATA
`

_, err := engine.Eval(code)
if err != nil {
    log.Fatal(err)
}

函数和控制流

code := `
    Func FACTORIAL (N) {
        If (N <= 1) {
            Return 1
        }
        Return (N * FACTORIAL(N - 1))
    }

    FACTORIAL(5)
`

result, _ := engine.Eval(code)
fmt.Println(result) // 输出: 120

高级用法

变量操作

engine := aether.New()
defer engine.Close()

// 从 Go 设置变量
engine.SetGlobal("name", "Alice")

// 在 Aether 中使用
result, _ := engine.Eval(`"Hello, " + name`)
fmt.Println(result) // Hello, Alice

// 获取变量值
value, _ := engine.GetGlobal("name")
fmt.Println(value) // Alice

// 设置复杂类型
engine.SetGlobal("config", map[string]interface{}{
    "host": "localhost",
    "port": 8080,
})

追踪与调试

engine := aether.New()
defer engine.Close()

// 执行带 TRACE 的代码
engine.Eval(`
    TRACE_DEBUG("api", "请求开始")
    Set X 42
    TRACE_INFO("calc", "X = ", X)
`)

// 获取追踪
traces, _ := engine.TakeTrace()
for _, trace := range traces {
    fmt.Println(trace)
}

// 获取结构化记录
records, _ := engine.TraceRecords()
for _, record := range records {
    fmt.Printf("[%s] %s: %v\n",
        record.Level, record.Category, record.Values)
}

// 获取统计
stats, _ := engine.TraceStats()
fmt.Printf("总追踪数: %d\n", stats.TotalEntries)

执行限制

engine := aether.New()
defer engine.Close()

// 设置限制
engine.SetExecutionLimits(aether.Limits{
    MaxSteps:          10000,
    MaxRecursionDepth: 100,
    MaxDurationMs:     5000,
})

// 获取限制
limits, _ := engine.GetExecutionLimits()
fmt.Printf("最大步数: %d\n", limits.MaxSteps)

缓存控制

engine := aether.New()
defer engine.Close()

// 多次执行代码(第二次使用缓存)
code := "Set X 10\n(X + 20)"
for i := 0; i < 10; i++ {
    engine.Eval(code)
}

// 获取缓存统计
stats, _ := engine.CacheStats()
fmt.Printf("缓存命中: %d, 未命中: %d\n",
    stats.Hits, stats.Misses)

// 清除缓存
engine.ClearCache()

环境重置

engine := aether.New()
defer engine.Close()

// 执行设置变量的代码
engine.Eval("Set X 42\nSet Y 100")

// 重置环境(清除所有变量)
engine.ResetEnv()

// 变量现在已清除
_, err := engine.Eval("X")
// 错误: 未定义的变量: X

线程安全

引擎完全线程安全,可以并发使用:

engine := aether.New()
defer engine.Close()

var wg sync.WaitGroup

// 并发运行 100 个 goroutine
for i := 0; i < 100; i++ {
    wg.Add(1)
    go func(n int) {
        defer wg.Done()

        code := fmt.Sprintf("Set X %d\n(X * 2)", n)
        result, err := engine.Eval(code)
        if err != nil {
            log.Printf("错误: %v", err)
            return
        }
        log.Printf("结果: %s", result)
    }(i)
}

wg.Wait()

API 参考

类型

  • Engine: 线程安全的 Aether DSL 引擎
  • Limits: 执行限制配置
  • CacheStats: 缓存统计
  • TraceStats: 追踪统计
  • TraceEntry: 结构化追踪条目

函数

引擎创建

  • New() *Engine: 创建禁用 IO 的引擎
  • NewWithPermissions() *Engine: 创建启用所有 IO 权限的引擎
  • Version() string: 获取 Aether 版本

执行

  • Eval(code string) (string, error): 执行 Aether 代码

变量

  • SetGlobal(name string, value interface{}) error: 设置全局变量
  • GetGlobal(name string) (interface{}, error): 获取全局变量
  • ResetEnv() error: 重置环境(清除所有变量)

追踪与调试

  • TakeTrace() ([]string, error): 获取所有追踪条目
  • TraceRecords() ([]TraceEntry, error): 获取结构化追踪
  • TraceStats() (*TraceStats, error): 获取追踪统计
  • ClearTrace() error: 清除追踪缓冲区

执行控制

  • SetExecutionLimits(Limits) error: 设置执行限制
  • GetExecutionLimits() (*Limits, error): 获取当前限制

缓存

  • CacheStats() (*CacheStats, error): 获取缓存统计
  • ClearCache() error: 清除 AST 缓存

优化

  • SetOptimization(constantFolding, deadCode, tailRecursion bool) error: 设置优化选项

生命周期

  • Close(): 释放引擎资源(幂等)

构建和测试

从源码构建

# 构建 Rust 库(在主仓库)
cd ../..
cargo build --release

# 复制库文件到 lib 目录
mkdir -p lib/
cp target/release/libaether.a lib/

# 运行 Go 测试
cd bindings/go
go test -v

运行测试

# 运行所有测试
make test

# 运行基准测试
make benchmark

# 运行示例
make example

示例

参见 examples/ 目录中的更多示例:

  • examples/enhanced/main.go: 完整的功能演示

性能

在 Apple M1 上的基准测试结果:

BenchmarkBasicEval-8             1000000    1023 ns/op
BenchmarkConcurrentEval-8         5000000     423 ns/op
BenchmarkSetGetGlobal-8           3000000     567 ns/op

错误处理

所有函数都返回错误。始终检查错误:

result, err := engine.Eval(code)
if err != nil {
    // 处理错误
    if strings.Contains(err.Error(), "Parse error") {
        // 语法错误
    } else if strings.Contains(err.Error(), "Runtime error") {
        // 运行时错误
    }
}

安全性

默认模式(受限)

IO 操作默认禁用以保证安全:

engine := aether.New()
// 文件操作将失败
_, err := engine.Eval(`READ_FILE("/etc/passwd")`)
// 错误: Runtime error: File IO is disabled

启用权限

仅对可信代码启用 IO:

engine := aether.NewWithPermissions()
// 文件操作现在可用
content, err := engine.Eval(`READ_FILE("/tmp/data.txt")`)

许可证

GPL-3.0

发布指南

版本发布

  1. 更新代码并提交:

    git add .
    git commit -m "描述你的更改"
    git push origin main
  2. 创建版本标签:

    git tag v1.0.0
    git push origin v1.0.0
  3. 验证发布:

用户安装

发布后,用户可以通过以下方式安装:

# 获取最新版本

go get github.com/xiaozuhui/aether-go@latest

# 获取特定版本

go get github.com/xiaozuhui/aether-go@v1.0.0

详细的发布指南请参考 RELEASE.md

About

Aether DSL 的 Golang 绑定

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •