Forked and more actively developed tengo version

Max Kuznetsov c461a7fe60 Fix: stop execution when trying to slice an unsupported type (#443) hai 6 meses
.github 55f2519b16 update go version to fix goreleaser (#422) hai 1 ano
cmd 4ed75764ce enable relative imports (#285) %!s(int64=4) %!d(string=hai) anos
docs 47062da36a Add `os.arch` and `os.platform` (#437) hai 6 meses
examples d8b50efec5 add interoperability example (#266) %!s(int64=4) %!d(string=hai) anos
parser e9b03930ce fix the import expr string output (#440) hai 6 meses
require d5b24138d3 add go module v2 (#244) %!s(int64=4) %!d(string=hai) anos
stdlib 47062da36a Add `os.arch` and `os.platform` (#437) hai 6 meses
testdata 4846cf5243 add custom extension support for importing source file (#350) %!s(int64=2) %!d(string=hai) anos
token a9a233a750 fix internal package issue (#241) %!s(int64=4) %!d(string=hai) anos
.gitignore 47062da36a Add `os.arch` and `os.platform` (#437) hai 6 meses
.goreleaser.yml 6fb0df750b updated goreleaser config (#249) %!s(int64=4) %!d(string=hai) anos
LICENSE fbbec8853b Create LICENSE %!s(int64=5) %!d(string=hai) anos
Makefile 4ed75764ce enable relative imports (#285) %!s(int64=4) %!d(string=hai) anos
README.md 818d6dc687 vim syntax highlighter (#383) %!s(int64=2) %!d(string=hai) anos
builtins.go 885830428b PR: builtin range function #326 (#328) %!s(int64=3) %!d(string=hai) anos
builtins_test.go 885830428b PR: builtin range function #326 (#328) %!s(int64=3) %!d(string=hai) anos
bytecode.go d1dd01499f fix a bug in bytecode optimization code (#292) %!s(int64=4) %!d(string=hai) anos
bytecode_test.go d5b24138d3 add go module v2 (#244) %!s(int64=4) %!d(string=hai) anos
compiler.go e338512259 fix: do not invert token.Less to token.Greater in compiler (#391) %!s(int64=2) %!d(string=hai) anos
compiler_test.go 18b953c7be increase size of jump operands (#438) hai 9 meses
doc.go a9a233a750 fix internal package issue (#241) %!s(int64=4) %!d(string=hai) anos
errors.go 885830428b PR: builtin range function #326 (#328) %!s(int64=3) %!d(string=hai) anos
eval.go ac805806f8 add Eval function (#338) %!s(int64=3) %!d(string=hai) anos
eval_test.go ac805806f8 add Eval function (#338) %!s(int64=3) %!d(string=hai) anos
example_test.go d5b24138d3 add go module v2 (#244) %!s(int64=4) %!d(string=hai) anos
formatter.go c88a5f506e some code clean up (#237) %!s(int64=4) %!d(string=hai) anos
go.mod d5b24138d3 add go module v2 (#244) %!s(int64=4) %!d(string=hai) anos
go.sum 7cb058b564 fix go.sum (#238) %!s(int64=4) %!d(string=hai) anos
instructions.go 18b953c7be increase size of jump operands (#438) hai 9 meses
iterator.go c88a5f506e some code clean up (#237) %!s(int64=4) %!d(string=hai) anos
modules.go 3b65ddf2b8 Extract ModuleGetter interface for dynamic imports (#349) %!s(int64=2) %!d(string=hai) anos
objects.go 0afdfdeb2f Fix copying user functions (#366) %!s(int64=2) %!d(string=hai) anos
objects_test.go d5b24138d3 add go module v2 (#244) %!s(int64=4) %!d(string=hai) anos
script.go f980e7e724 Downgrade exclusive lock to shared lock when cloning a script (#400) hai 1 ano
script_test.go dfcfd6661c Use Object.Copy when cloning globals in Compiled (#393) %!s(int64=2) %!d(string=hai) anos
symbol_table.go 2565e0553d fix issues with symbols in global scope blocks (#318) %!s(int64=4) %!d(string=hai) anos
symbol_table_test.go 15494e1691 fix local symbol resolution bug (#316) %!s(int64=4) %!d(string=hai) anos
tengo.go 4846cf5243 add custom extension support for importing source file (#350) %!s(int64=2) %!d(string=hai) anos
tengo_test.go d5b24138d3 add go module v2 (#244) %!s(int64=4) %!d(string=hai) anos
variable.go c88a5f506e some code clean up (#237) %!s(int64=4) %!d(string=hai) anos
variable_test.go d5b24138d3 add go module v2 (#244) %!s(int64=4) %!d(string=hai) anos
vm.go c461a7fe60 Fix: stop execution when trying to slice an unsupported type (#443) hai 6 meses
vm_test.go c461a7fe60 Fix: stop execution when trying to slice an unsupported type (#443) hai 6 meses

README.md

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