添加Anko脚本语法指南及完善拦截器文档
This commit is contained in:
parent
92c958c9c4
commit
ae43530608
|
|
@ -0,0 +1,110 @@
|
||||||
|
# go-lang-anko 脚本语法指南
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
`anko` 是一个用 Go 编写的轻量级脚本引擎,支持动态执行 Go 风格的脚本代码。它适用于需要嵌入脚本功能的 Go 应用程序。
|
||||||
|
|
||||||
|
## 基本语法
|
||||||
|
|
||||||
|
### 变量声明与赋值
|
||||||
|
```go
|
||||||
|
// 声明变量并赋值
|
||||||
|
x = 42
|
||||||
|
name = "anko"
|
||||||
|
|
||||||
|
// 多变量赋值
|
||||||
|
a, b = 1, 2
|
||||||
|
```
|
||||||
|
|
||||||
|
### 控制结构
|
||||||
|
#### if 语句
|
||||||
|
```go
|
||||||
|
if x > 0 {
|
||||||
|
println("x is positive")
|
||||||
|
} else {
|
||||||
|
println("x is non-positive")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### for 循环
|
||||||
|
```go
|
||||||
|
// 类似 Go 的 for 循环
|
||||||
|
for i = 0; i < 10; i++ {
|
||||||
|
println(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 类似 while 的循环
|
||||||
|
for x < 100 {
|
||||||
|
x *= 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### switch 语句
|
||||||
|
```go
|
||||||
|
switch x {
|
||||||
|
case 1:
|
||||||
|
println("one")
|
||||||
|
case 2:
|
||||||
|
println("two")
|
||||||
|
default:
|
||||||
|
println("unknown")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 函数定义与调用
|
||||||
|
```go
|
||||||
|
// 定义函数
|
||||||
|
func add(a, b) {
|
||||||
|
return a + b
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用函数
|
||||||
|
result = add(3, 4)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 内置函数和标准库
|
||||||
|
`anko` 支持部分 Go 标准库函数,例如:
|
||||||
|
```go
|
||||||
|
// 字符串操作
|
||||||
|
s = "hello"
|
||||||
|
println(len(s)) // 输出 5
|
||||||
|
|
||||||
|
// 数学函数
|
||||||
|
println(math.Pi)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 错误处理
|
||||||
|
```go
|
||||||
|
// 使用 try-catch 捕获错误
|
||||||
|
try {
|
||||||
|
x = 1 / 0
|
||||||
|
} catch(err) {
|
||||||
|
println("Error:", err)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 示例代码
|
||||||
|
|
||||||
|
### 计算斐波那契数列
|
||||||
|
```go
|
||||||
|
func fib(n) {
|
||||||
|
if n <= 1 {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
return fib(n-1) + fib(n-2)
|
||||||
|
}
|
||||||
|
|
||||||
|
println(fib(10)) // 输出 55
|
||||||
|
```
|
||||||
|
|
||||||
|
### 文件操作
|
||||||
|
```go
|
||||||
|
// 读取文件内容
|
||||||
|
content = file.Read("example.txt")
|
||||||
|
println(content)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
1. **性能**:`anko` 是解释执行的,性能不如原生 Go 代码。
|
||||||
|
2. **安全性**:避免执行不可信的脚本代码。
|
||||||
|
3. **限制**:不支持 Go 的所有特性(如指针、接口等)。
|
||||||
|
4. **调试**:使用 `println` 或 `try-catch` 进行简单调试。
|
||||||
|
|
@ -35,8 +35,19 @@ func NewAnkointerceptor(ankoEnv *env.Env) *Ankointerceptor {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exec executes the specified script within the Anko environment.
|
||||||
|
// It sets up the environment with necessary variables and methods,
|
||||||
|
// reads the script file, and executes it, returning the result or an error.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - script: Path to the script file to be executed.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - interface{}: The result of the script execution.
|
||||||
|
// - error: An error if the script file cannot be read or execution fails.
|
||||||
func (a *Ankointerceptor) Exec(script string) (interface{}, error) {
|
func (a *Ankointerceptor) Exec(script string) (interface{}, error) {
|
||||||
e := a.ankoEnv.Copy()
|
e := a.ankoEnv.Copy()
|
||||||
|
// Configure the Anko environment with required variables and methods
|
||||||
e.Define("Require", a.genRequireMethod(script))
|
e.Define("Require", a.genRequireMethod(script))
|
||||||
e.Define("__filename", script)
|
e.Define("__filename", script)
|
||||||
e.Define("__dirname", filepath.Dir(script))
|
e.Define("__dirname", filepath.Dir(script))
|
||||||
|
|
@ -45,6 +56,7 @@ func (a *Ankointerceptor) Exec(script string) (interface{}, error) {
|
||||||
return nil, frr
|
return nil, frr
|
||||||
}
|
}
|
||||||
scriptcode := string(scriptbytes)
|
scriptcode := string(scriptbytes)
|
||||||
|
// Execute the script code in the prepared environment
|
||||||
result, err := vm.Execute(e, nil, scriptcode)
|
result, err := vm.Execute(e, nil, scriptcode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|
@ -53,17 +65,28 @@ func (a *Ankointerceptor) Exec(script string) (interface{}, error) {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// genRequireMethod 创建模块解析闭包函数
|
||||||
|
// 该函数用于处理模块路径解析和缓存机制:
|
||||||
|
// 1. 优先从importMap缓存中查找已加载模块
|
||||||
|
// 2. 对相对路径自动转换为基于basePath的绝对路径
|
||||||
|
// 3. 执行模块加载后自动缓存结果
|
||||||
|
// 参数:
|
||||||
|
// basePath - 模块基础路径,用于解析相对路径
|
||||||
|
// 返回:
|
||||||
|
// 闭包函数,接收模块路径s,返回解析后的模块对象
|
||||||
func (a *Ankointerceptor) genRequireMethod(basePath string) interface{} {
|
func (a *Ankointerceptor) genRequireMethod(basePath string) interface{} {
|
||||||
return func(s string) interface{} {
|
return func(s string) interface{} {
|
||||||
if r, ok := a.importMap[s]; ok {
|
if r, ok := a.importMap[s]; ok {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
// 将相对路径转换为基于basePath的绝对路径
|
||||||
if !filepath.IsAbs(s) {
|
if !filepath.IsAbs(s) {
|
||||||
s = filepath.Join(filepath.Dir(basePath), s)
|
s = filepath.Join(filepath.Dir(basePath), s)
|
||||||
}
|
}
|
||||||
if _, ok := a.importMap[s]; ok {
|
if _, ok := a.importMap[s]; ok {
|
||||||
return a.importMap[s]
|
return a.importMap[s]
|
||||||
}
|
}
|
||||||
|
// 执行模块加载并将结果缓存
|
||||||
result, err := a.Exec(s)
|
result, err := a.Exec(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue