Created
November 3, 2023 19:57
-
-
Save mymmrac/c2aa79a4b33db5aff0ef9345b68599c4 to your computer and use it in GitHub Desktop.
Go, Lua and JS interpreters in Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module interpreters | |
go 1.21 | |
require ( | |
github.com/dop251/goja v0.0.0-20231027120936-b396bb4c349d | |
github.com/mymmrac/x v0.0.0-20231103184157-cf259b37ba38 | |
github.com/traefik/yaegi v0.15.1 | |
github.com/yuin/gopher-lua v1.1.0 | |
) | |
require ( | |
github.com/dlclark/regexp2 v1.10.0 // indirect | |
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect | |
github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 // indirect | |
golang.org/x/text v0.13.0 // indirect | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"io" | |
"os" | |
"reflect" | |
"github.com/dop251/goja" | |
"github.com/mymmrac/x" | |
"github.com/traefik/yaegi/interp" | |
"github.com/traefik/yaegi/stdlib" | |
lua "github.com/yuin/gopher-lua" | |
) | |
const fileName = "hello" | |
func main() { | |
mainGo() | |
mainLua() | |
mainJS() | |
} | |
// ==== // ==== // | |
// https://github.com/traefik/yaegi | |
func mainGo() { | |
i := interp.New(interp.Options{}) | |
i.Use(stdlib.Symbols) | |
_, err := i.Eval(`import "os"`) | |
x.Assert(err == nil, err) | |
err = i.Use(map[string]map[string]reflect.Value{ | |
"my/": { | |
"FileName": reflect.ValueOf(filenameGo), | |
}, | |
}) | |
x.Assert(err == nil, err) | |
i.ImportUsed() | |
_, err = i.Eval(`file, err := os.Open(my.FileName("` + fileName + `"))`) | |
x.Assert(err == nil, err) | |
g := i.Globals() | |
x.Assert(len(g) != 0) | |
file := g["file"].Interface().(*os.File) | |
if !g["err"].IsNil() { | |
err = g["err"].Interface().(error) | |
} | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
data, err := io.ReadAll(file) | |
x.Assert(err == nil, err) | |
fmt.Println(string(data)) | |
} | |
func filenameGo(name string) string { | |
return name + ".go.txt" | |
} | |
// ==== // ==== // | |
// https://github.com/yuin/gopher-lua | |
func mainLua() { | |
L := lua.NewState() | |
defer L.Close() | |
L.SetGlobal("file_name", L.NewFunction(filenameLua)) | |
err := L.DoString(` | |
local file = assert(io.open(file_name("` + fileName + `"), "r")) | |
content = file:read("*all") | |
file:close() | |
`) | |
x.Assert(err == nil, err) | |
fmt.Println(L.GetGlobal("content").String()) | |
} | |
func filenameLua(L *lua.LState) int { | |
name := L.ToString(1) | |
L.Push(lua.LString(name + ".lua.txt")) | |
return 1 | |
} | |
// ==== // ==== // | |
// https://github.com/dop251/goja | |
func mainJS() { | |
vm := goja.New() | |
err := vm.Set("fileName", filenameJS) | |
x.Assert(err == nil, err) | |
v, err := vm.RunString(`fileName("` + fileName + `")`) | |
x.Assert(err == nil, err) | |
fileName := v.Export().(string) | |
file, err := os.Open(fileName) | |
x.Assert(err == nil, err) | |
data, err := io.ReadAll(file) | |
x.Assert(err == nil, err) | |
fmt.Println(string(data)) | |
} | |
func filenameJS(call goja.FunctionCall, vm *goja.Runtime) goja.Value { | |
name := call.Argument(0).Export().(string) | |
return vm.ToValue(name + ".js.txt") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment