GitHub - d5/tengo: A fast script language for Go (original) (raw)

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 theTengo 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