Tengo

一种用于 Go 的快速脚本语言。(A fast script language for Go)

Github星跟蹤圖

Tengo 语言

Tengo 是一种小型、动态、快速、安全的 Go 脚本语言。

Tengo 是快速和安全的,因为它是以字节码的形式在基于堆栈的虚拟机上编译/执行的,而虚拟机是用原生 Go 编写的。

/* The Tengo Language */
fmt := import("fmt")
each := func(seq, fn) {
    for x in seq { fn(x) }
}
sum := func(init, seq) {
    each(seq, func(x) { init += x })
    return init
}
fmt.println(sum(0, [1, 2, 3]))   // "6"
fmt.println(sum("", [1, 2, 3]))  // "123"

Tengo Playground 中测试这个 Tengo 代码。

特性

  • 简单且高度可读的语法
  • 动态类型化与类型强制
  • 高阶函数和闭合
  • 不可更改的价值
  • 可安全嵌入扩展
  • 用原生 Go 编写的编译器/运行时(没有外部 deps 或 cgo)。
  • 可作为独立语言执行 / REPL
  • 使用案例:规则引擎、状态机、数据管道、transpiler

基准测试

fib(35) fibt(35) 语言(类型)
Tengo 2,931ms 4ms Tengo (VM)
go-lua 4,824ms 4ms Lua (VM)
GopherLua 5,365ms 4ms Lua (VM)
goja 5,533ms 5ms JavaScript (VM)
starlark-go 11,495ms 5ms Starlark (Interpreter)
Yaegi 15,645ms 12ms Yaegi (Interpreter)
gpython 16,322ms 5ms Python (Interpreter)
otto 73,093ms 10ms JavaScript (Interpreter)
Anko 79,809ms 8ms Anko (Interpreter)
- - - -
Go 53ms 3ms Go (Native)
Lua 1,612ms 3ms Lua (Native)
Python 2,632ms 23ms Python 2 (Native)

* fib(35): Fibonacci(35)
* fibt(35): tail-call version of Fibonacci(35)
* Go does not read the source code from file, while all other cases do
* See here for commands/codes used

快速入门

go get github.com/d5/tengo/v2

一个简单的 Go 示例代码,它可以编译/运行带有一些输入/输出值的 Tengo 脚本代码。

package main
import (
    "context"
    "fmt"
    "github.com/d5/tengo/v2"
)
func main() {
    // Tengo script code
    src := `
each := func(seq, fn) {
    for x in seq { fn(x) }
}
sum := 0
mul := 1
each([a, b, c, d], func(x) {
    sum += x
    mul *= x
})`
    // create a new Script instance
    script := tengo.NewScript([]byte(src))
    // set values
    _ = script.Add("a", 1)
    _ = script.Add("b", 9)
    _ = script.Add("c", 8)
    _ = script.Add("d", 4)
    // run the script
    compiled, err := script.RunContext(context.Background())
    if err != nil {
        panic(err)
    }
    // retrieve values
    sum := compiled.Get("sum")
    mul := compiled.Get("mul")
    fmt.Println(sum, mul) // "22 288"
}

参考文献

(The first version translated by vz on 2020.08.22)

主要指標

概覽
名稱與所有者d5/tengo
主編程語言Go
編程語言Makefile (語言數: 2)
平台Linux, Mac, Windows
許可證MIT License
所有者活动
創建於2019-01-09 07:17:17
推送於2025-05-24 16:25:43
最后一次提交2025-05-24 17:13:24
發布數103
最新版本名稱v3.0.0 (發布於 )
第一版名稱v0.9.1 (發布於 2019-01-30 00:58:45)
用户参与
星數3.7k
關注者數59
派生數315
提交數343
已啟用問題?
問題數226
打開的問題數66
拉請求數182
打開的拉請求數18
關閉的拉請求數36
项目设置
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?

The Tengo Language

GoDoc
test
Go Report Card

Tengo is a small, dynamic, fast, secure script language for Go.

Tengo is fast and secure because it's compiled/executed as
bytecode on stack-based VM that's written in native Go.

/* The Tengo Language */
fmt := import("fmt")

each := func(seq, fn) {
    for x in seq { fn(x) }
}

sum := func(init, seq) {
    each(seq, func(x) { init += x })
    return init
}

fmt.println(sum(0, [1, 2, 3]))   // "6"
fmt.println(sum("", [1, 2, 3]))  // "123"

Test this Tengo code in the
Tengo Playground

Features

Benchmark

fib(35) fibt(35) Language (Type)
Tengo 2,315ms 3ms Tengo (VM)
go-lua 4,028ms 3ms Lua (VM)
GopherLua 4,409ms 3ms Lua (VM)
goja 5,194ms 4ms JavaScript (VM)
starlark-go 6,954ms 3ms Starlark (Interpreter)
gpython 11,324ms 4ms Python (Interpreter)
Yaegi 11,715ms 10ms Yaegi (Interpreter)
otto 48,539ms 6ms JavaScript (Interpreter)
Anko 52,821ms 6ms Anko (Interpreter)
- - - -
Go 47ms 2ms Go (Native)
Lua 756ms 2ms Lua (Native)
Python 1,907ms 14ms Python2 (Native)

* fib(35):
Fibonacci(35)

* fibt(35):
tail-call version of Fibonacci(35)

* Go does not read the source code from file, while all other cases do
* See here for commands/codes used

Quick Start

go get github.com/d5/tengo/v2

A simple Go example code that compiles/runs Tengo script code with some input/output values:

package main

import (
	"context"
	"fmt"

	"github.com/d5/tengo/v2"
)

func main() {
	// create a new Script instance
	script := tengo.NewScript([]byte(
`each := func(seq, fn) {
    for x in seq { fn(x) }
}

sum := 0
mul := 1
each([a, b, c, d], func(x) {
    sum += x
    mul *= x
})`))

	// set values
	_ = script.Add("a", 1)
	_ = script.Add("b", 9)
	_ = script.Add("c", 8)
	_ = script.Add("d", 4)

	// run the script
	compiled, err := script.RunContext(context.Background())
	if err != nil {
		panic(err)
	}

	// retrieve values
	sum := compiled.Get("sum")
	mul := compiled.Get("mul")
	fmt.Println(sum, mul) // "22 288"
}

Or, if you need to evaluate a simple expression, you can use Eval function instead:

res, err := tengo.Eval(ctx,
	`input ? "success" : "fail"`,
	map[string]interface{}{"input": 1})
if err != nil {
	panic(err)
}
fmt.Println(res) // "success"

References