How to Embed Lua in Go (gopher-lua)

You can embed Lua in Go using the `gopher-lua` library, which provides a pure Go implementation of the Lua 5.1 interpreter without external dependencies.

You can embed Lua in Go using the gopher-lua library, which provides a pure Go implementation of the Lua 5.1 interpreter without external dependencies. Initialize a state machine, load your Lua script, and execute it directly within your Go application, passing data between the two languages via the VM's registry or function arguments.

First, install the library with go get -u github.com/yuin/gopher-lua. Here is a minimal example showing how to run a script and pass Go values into Lua:

package main

import (
	"fmt"
	"github.com/yuin/gopher-lua"
)

func main() {
	L := lua.NewState()
	defer L.Close()

	// Load and run a Lua script
	if err := L.DoString(`
		function greet(name)
			return "Hello, " .. name
		end
	`); err != nil {
		panic(err)
	}

	// Call the Lua function from Go
	if err := L.CallByParam(lua.P{
		Fn:      L.GetGlobal("greet"),
		NRet:    1,
		Protect: true,
	}, lua.LString("Gopher")); err != nil {
		panic(err)
	}

	// Retrieve the result
	result := L.Get(-1)
	L.Pop(1)
	fmt.Println(result.String()) // Output: Hello, Gopher
}

For more complex interactions, you can register Go functions to be called from Lua. This allows your Lua scripts to invoke Go logic directly. Use L.SetGlobal to expose a Go function:

func main() {
	L := lua.NewState()
	defer L.Close()

	// Register a Go function as a Lua global
	L.SetGlobal("add", L.NewFunction(func(L *lua.LState) int {
		a := L.CheckInt(1)
		b := L.CheckInt(2)
		L.Push(lua.LNumber(a + b))
		return 1
	}))

	// Execute Lua code that calls the Go function
	L.DoString(`
		local sum = add(10, 20)
		print("Sum is: " .. sum)
	`)
}

When handling errors, always use Protect: true in CallByParam or check L.GetTop() after execution to ensure the stack remains clean. If a Lua script throws an error, gopher-lua returns a Go error, allowing you to handle it gracefully without crashing your application. Remember that gopher-lua implements Lua 5.1, so avoid using features specific to Lua 5.2 or later unless you are using a fork that supports them. This setup is ideal for configuration files, plugin systems, or scripting game logic where you need the safety of Go with the flexibility of Lua.