LuaJIT-to-Go/DOCS.md
2025-06-03 17:01:56 -05:00

11 KiB

API Documentation

State Management

New() *State

New creates a new Lua state with optional standard libraries; true if not specified

L := luajit.New() // or luajit.New(false)
defer L.Close()
defer L.Cleanup()

Close()

Closes the Lua state and frees associated resources.

L.Close()

Cleanup()

Cleans up the function registry and other internal resources.

L.Cleanup()

Stack Operations

GetTop() int

Returns the index of the top element in the stack.

top := L.GetTop()  // 0 for empty stack

SetTop(index int)

Sets the stack top to a specific index.

L.SetTop(2)  // Truncate stack to 2 elements

PushCopy(index int)

Pushes a copy of the value at the given index onto the stack.

L.PushCopy(-1)  // Duplicate the top element

Pop(n int)

Removes n elements from the stack.

L.Pop(1)  // Remove top element
L.Pop(2)  // Remove top two elements

Remove(index int)

Removes the element at the given index.

L.Remove(-1)  // Remove top element
L.Remove(1)   // Remove first element

Type Checks

GetType(index int) LuaType

Returns the type of the value at the given index.

if L.GetType(-1) == TypeString {
    // Handle string
}

IsNil(index int) bool

IsBoolean(index int) bool

IsNumber(index int) bool

IsString(index int) bool

IsTable(index int) bool

IsFunction(index int) bool

Type checking functions for specific Lua types.

if L.IsTable(-1) {
    table, err := L.ToTable(-1)
}

Value Retrieval

ToString(index int) string

Converts the value at the given index to a string.

str := L.ToString(-1)

ToNumber(index int) float64

Converts the value to a number.

num := L.ToNumber(-1)

ToBoolean(index int) bool

Converts the value to a boolean.

bool := L.ToBoolean(-1)

ToValue(index int) (any, error)

Converts any Lua value to its Go equivalent with automatic type detection.

val, err := L.ToValue(-1)
if err != nil {
    return err
}

ToTable(index int) (any, error)

Converts a Lua table to optimal Go type; arrays or map[string]any.

table, err := L.ToTable(-1)
if err != nil {
    return nil, err
}

GetTableLength(index int) int

Returns the length of a table at the given index.

length := L.GetTableLength(-1)

Value Pushing

PushNil()

PushBoolean(b bool)

PushNumber(n float64)

PushString(str string)

Basic value pushing functions.

L.PushString("hello")
L.PushNumber(42)
L.PushBoolean(true)
L.PushNil()

PushValue(v any) error

Pushes any Go value onto the stack with comprehensive type support.

// Supports: primitives, slices, maps with various type combinations
err := L.PushValue(map[string]any{
    "key": "value",
    "numbers": []float64{1, 2, 3},
})

Table Operations

CreateTable(narr, nrec int)

Creates a new table with pre-allocated space.

L.CreateTable(10, 5)  // Space for 10 array elements, 5 records

NewTable()

Creates a new empty table and pushes it onto the stack.

L.NewTable()

GetTable(index int)

Gets a table field (t[k]) where t is at the given index and k is at the top of the stack.

L.PushString("key")
L.GetTable(-2)  // Gets table["key"]

SetTable(index int)

Sets a table field (t[k] = v) where t is at the given index, k is at -2, and v is at -1.

L.PushString("key")
L.PushString("value")
L.SetTable(-3)  // table["key"] = "value"

GetField(index int, key string)

Gets a table field t[k] and pushes it onto the stack.

L.GetField(-1, "name")  // gets table.name

SetField(index int, key string)

Sets a table field t[k] = v, where v is the value at the top of the stack.

L.PushString("value")
L.SetField(-2, "key")  // table.key = "value"

Next(index int) bool

Pops a key from the stack and pushes the next key-value pair from the table.

L.PushNil()  // Start iteration
for L.Next(-2) {
    // Stack now has key at -2 and value at -1
    key := L.ToString(-2)
    value := L.ToString(-1)
    L.Pop(1)  // Remove value, keep key for next iteration
}

GetFieldString/Number/Bool/Table(index int, key string, default T) T

Get typed fields from tables with default values.

name := L.GetFieldString(-1, "name", "unknown")
age := L.GetFieldNumber(-1, "age", 0)
active := L.GetFieldBool(-1, "active", false)
config, ok := L.GetFieldTable(-1, "config")

ForEachTableKV(index int, fn func(key, value string) bool)

ForEachArray(index int, fn func(i int, state *State) bool)

Convenient iteration helpers.

L.ForEachTableKV(-1, func(key, value string) bool {
    fmt.Printf("%s: %s\n", key, value)
    return true  // continue iteration
})

Function Registration and Calling

GoFunction

Type definition for Go functions callable from Lua.

type GoFunction func(*State) int

PushGoFunction(fn GoFunction) error

Wraps a Go function and pushes it onto the Lua stack.

adder := func(s *luajit.State) int {
    sum := s.ToNumber(1) + s.ToNumber(2)
    s.PushNumber(sum)
    return 1
}
err := L.PushGoFunction(adder)

RegisterGoFunction(name string, fn GoFunction) error

Registers a Go function as a global Lua function.

err := L.RegisterGoFunction("add", adder)

UnregisterGoFunction(name string)

Removes a previously registered function.

L.UnregisterGoFunction("add")

Call(nargs, nresults int) error

Calls a function with the given number of arguments and results.

L.GetGlobal("myfunction")
L.PushNumber(1)
L.PushNumber(2)
err := L.Call(2, 1)  // Call with 2 args, expect 1 result

CallGlobal(name string, args ...any) ([]any, error)

Calls a global function with arguments and returns all results.

results, err := L.CallGlobal("myfunction", 1, 2, "hello")

Global Operations

GetGlobal(name string)

Gets a global variable and pushes it onto the stack.

L.GetGlobal("myGlobal")

SetGlobal(name string)

Sets a global variable from the value at the top of the stack.

L.PushNumber(42)
L.SetGlobal("answer")  // answer = 42

Code Execution

LoadString(code string) error

Loads a Lua chunk from a string without executing it.

err := L.LoadString("return 42")

LoadFile(filename string) error

Loads a Lua chunk from a file without executing it.

err := L.LoadFile("script.lua")

DoString(code string) error

Executes a string of Lua code.

err := L.DoString(`
    local x = 40
    local y = 2
    result = x + y
`)

DoFile(filename string) error

Executes a Lua file.

err := L.DoFile("script.lua")

Execute(code string) (int, error)

Executes a Lua string and returns the number of results left on the stack.

nresults, err := L.Execute("return 1, 2, 3")
// nresults would be 3

ExecuteWithResult(code string) (any, error)

Executes a Lua string and returns the first result.

result, err := L.ExecuteWithResult("return 'hello'")
// result would be "hello"

BatchExecute(statements []string) error

Executes multiple statements as a single batch.

err := L.BatchExecute([]string{
    "x = 10",
    "y = 20",
    "result = x + y",
})

Bytecode Operations

CompileBytecode(code string, name string) ([]byte, error)

Compiles a Lua chunk to bytecode without executing it.

bytecode, err := L.CompileBytecode("return 42", "test")

LoadBytecode(bytecode []byte, name string) error

Loads precompiled bytecode without executing it.

err := L.LoadBytecode(bytecode, "test")

RunBytecode() error

Executes previously loaded bytecode with 0 results.

err := L.RunBytecode()

RunBytecodeWithResults(nresults int) error

Executes bytecode and keeps nresults on the stack.

err := L.RunBytecodeWithResults(1)

LoadAndRunBytecode(bytecode []byte, name string) error

Loads and executes bytecode.

err := L.LoadAndRunBytecode(bytecode, "test")

LoadAndRunBytecodeWithResults(bytecode []byte, name string, nresults int) error

Loads and executes bytecode, preserving results.

err := L.LoadAndRunBytecodeWithResults(bytecode, "test", 1)

CompileAndRun(code string, name string) error

Compiles and immediately executes Lua code.

err := L.CompileAndRun("answer = 42", "test")

Package Path Operations

SetPackagePath(path string) error

Sets the Lua package.path.

err := L.SetPackagePath("./?.lua;/usr/local/share/lua/5.1/?.lua")

AddPackagePath(path string) error

Adds a path to package.path.

err := L.AddPackagePath("./modules/?.lua")

Metatable Operations

SetMetatable(index int)

Sets the metatable for the value at the given index.

L.SetMetatable(-1)

GetMetatable(index int) bool

Gets the metatable for the value at the given index.

if L.GetMetatable(-1) {
    // Metatable is now on stack
    L.Pop(1)
}

Error Handling

LuaError

Enhanced error type with detailed context information.

type LuaError struct {
    Code       int
    Message    string
    File       string
    Line       int
    StackTrace string
    Context    string
}

GetStackTrace() string

Gets the current Lua stack trace.

trace := L.GetStackTrace()
fmt.Println(trace)

GetErrorInfo(context string) *LuaError

Extracts detailed error information from the Lua stack.

err := L.GetErrorInfo("MyFunction")

CreateLuaError(code int, context string) *LuaError

Creates a LuaError with full context information.

err := L.CreateLuaError(status, "DoString")

PushError(format string, args ...any) int

Pushes an error string and returns -1.

return s.PushError("invalid argument: %v", arg)

Validation

CheckArgs(specs ...ArgSpec) error

Validates function arguments against specifications.

err := s.CheckArgs(
    ArgSpec{Name: "name", Type: "string", Required: true, Check: CheckString},
    ArgSpec{Name: "age", Type: "number", Required: false, Check: CheckNumber},
)

CheckMinArgs/CheckExactArgs(n int) error

Argument count validation.

if err := s.CheckMinArgs(2); err != nil {
    return s.PushError(err.Error())
}

SafeToString/Number/Table(index int) (T, error)

Safe value conversion with error handling.

str, err := s.SafeToString(1)
if err != nil {
    return s.PushError(err.Error())
}

Table Building

NewTableBuilder() *TableBuilder

Creates a new table builder for fluent table construction.

L.NewTableBuilder().
    SetString("name", "John").
    SetNumber("age", 30).
    SetBool("active", true).
    Build()

Thread Safety Notes

  • The function registry is thread-safe
  • Individual Lua states are not thread-safe
  • Create separate states for concurrent operations
  • Use the function registry to share functions between states

Memory Management

Always pair state creation with cleanup:

L := luajit.New()
defer L.Close()
defer L.Cleanup()

Stack management requires manual attention:

L.PushString("hello")
// ... use the string
L.Pop(1)  // Clean up when done