Lua

provides bindings for embedding Lua in Carp. It wraps the Lua C API directly, following its stack-based model: you push values onto a virtual stack, call Lua operations, and read results back from the stack.

All interaction starts with a Lua state. Use with-lua-do to create one, do work, and close it automatically. Call libs to make the Lua standard library available.

(Lua.with-lua-do
  (Lua.libs lua)
  (ignore (Lua.do-string lua (cstr "print('hello from lua')"))))

Values are passed between Carp and Lua through the stack. Push values with push-int, push-float, push-bool, push-carp-str, etc. Read them back with get-int, get-float, and so on, using negative indices to address from the top of the stack (-1 is the top element).

; push two values, read the top one
(Lua.push-int lua 42)
(Lua.push-float lua 3.14f)
(let [f (Lua.get-float lua -1)   ; 3.14
      i (Lua.get-int lua -2)]    ; 42
  (Lua.pop lua 2))

To call a Lua function at the low level, push the function, then its arguments, then use call with the argument and result counts. The result replaces the function and arguments on the stack.

(Lua.get-global lua (cstr "math"))
(ignore (Lua.get-field lua -1 (cstr "sqrt")))
(Lua.push-float lua 9.0f)
(ignore (Lua.call lua 1 1 0))
(IO.println &(str (Lua.get-float lua -1)))  ; 3.0
(Lua.pop lua 2)  ; pop result and math table

Tables are built by creating an empty table with create-table, setting fields with set-field, and optionally assigning the table to a global with set-global.

The module also provides convenience macros: fun defines a Lua function from inline source, and val evaluates a Lua expression into a global. For higher-level functions that handle type checking and error wrapping automatically, see Luax.

GC_ERROR

external

Int

Status code returned when the garbage collector metamethod fails.

HANDLER_ERROR

external

Int

Status code returned when the error handler itself fails.

MEMORY_ERROR

external

Int

Status code returned when a memory allocation fails.

OK

external

Int

Status code returned on success.

RUNTIME_ERROR

external

Int

Status code returned when a runtime error occurs.

TYPE_BOOLEAN

external

Int

Type constant for boolean values.

TYPE_FUNCTION

external

Int

Type constant for function values.

TYPE_NIL

external

Int

Type constant for nil values.

TYPE_NUMBER

external

Int

Type constant for numeric values (both integer and float).

TYPE_STRING

external

Int

Type constant for string values.

TYPE_TABLE

external

Int

Type constant for table values.

call

external

(Fn [(Ref Lua a), Int, Int, Int] Int)

Call a function on the stack with nargs arguments and nresults expected results. The last argument is the error handler stack index (0 for none). Returns a status code; use Luax.call-fn for a safer interface.

close

external

(Fn [(Ref Lua a)] ())

Close a Lua state and free all associated resources.

create-table

external

(Fn [(Ref Lua a), Int, Int] ())

Push a new empty table onto the stack. narr and nrec are size hints for the array and hash parts.

do-file

instantiate

(Fn [(Ref Lua a), (Ptr CChar)] Int)

Load and execute a Lua file. Returns a status code. Use eval-file for a version that returns Result.

do-string

external

(Fn [(Ref Lua a), (Ptr CChar)] Int)

Compile and execute a Lua string. Returns a status code. Use Luax.do-in for a version that returns Result.

eval-file

defn

(Fn [(Ref Lua a), (Ref String b)] (Result String String))

                        (eval-file lua path)
                    

Load and execute the Lua file at path. Returns (Success "") on success or (Error msg) with the Lua error message on failure.

evaluate

defn

(Fn [a] (Result String String))

                        (evaluate s)
                    

Create a temporary Lua state, evaluate the expression s, and return its string representation as a Result. Useful for one-off evaluations without managing a state manually.

(match (Lua.evaluate "1 + 2")
  (Result.Success v) (IO.println &v)
  (Result.Error e) (IO.errorln &e))

fun

macro

Macro

                        (fun lua name args body)
                    

Define a Lua function from a Carp macro call. name becomes a Lua global, args is a list of parameter names, and body is the Lua source.

(Lua.fun lua add [x y] "return x + y")

get-bool

external

(Fn [(Ref Lua a), Int] Bool)

Read the value at index as a boolean.

get-field

external

(Fn [(Ref Lua a), Int, (Ptr CChar)] Int)

Push the value of field name from the table at index onto the stack. Returns a type constant.

get-float

external

(Fn [(Ref Lua a), Int] Float)

Read the value at index as a float. Does not check the type—use Luax.maybe-get-float for a safe version.

get-global

external

(Fn [(Ref Lua a), (Ptr CChar)] ())

Push the value of the named global onto the stack.

get-int

external

(Fn [(Ref Lua a), Int] Int)

Read the value at index as an integer. Does not check the type—use Luax.maybe-get-int for a safe version.

get-string

external

(Fn [(Ref Lua a), Int] (Ptr CChar))

Read the value at index as a C string pointer. Returns a raw pointer; prefer Luax.get-carp-str or Luax.maybe-get-string for safe access.

get-string-global

defn

(Fn [(Ref Lua a), (Ref String b)] String)

                        (get-string-global lua name)
                    

Fetch the global name and return it as a Carp String. Returns an empty string if the global is nil or not a string. For a safe version returning Maybe, see Luax.get-string-global.

get-table

external

(Fn [(Ref Lua a), Int] Int)

Pop a key from the stack and push the corresponding value from the table at index. Returns a type constant.

get-top

external

(Fn [(Ref Lua a)] Int)

Return the index of the top element, which equals the number of elements on the stack.

get-user-data

external

(Fn [(Ref Lua a), Int] (Ptr ()))

Read the value at index as a userdata pointer.

global-exists?

defn

(Fn [(Ref Lua a), (Ref String b)] Bool)

                        (global-exists? lua name)
                    

Check whether the global name is defined (non-nil). Pushes and pops internally, leaving the stack unchanged.

libs

external

(Fn [(Ref Lua a)] ())

Open all standard Lua libraries in the given state.

load-buffer

external

(Fn [(Ref Lua a), (Ptr CChar), Int, (Ptr CChar)] Int)

Load a Lua chunk from a buffer without executing it. Returns a status code.

new

external

(Fn [] (Ref Lua a))

Create a new Lua state. Must be closed with close when done, or use with-lua-do to manage the lifecycle automatically.

next

external

(Fn [(Ref Lua a), Int] Int)

Pop a key and push the next key-value pair from the table at index. Returns 0 when there are no more entries. Used for iterating tables with push-nil as the initial key.

pop

external

(Fn [(Ref Lua a), Int] ())

Remove n elements from the top of the stack.

push-bool

external

(Fn [(Ref Lua a), Bool] ())

Push a boolean onto the stack.

push-carp-str

defn

(Fn [(Ref Lua a), (Ref String b)] ())

                        (push-carp-str lua s)
                    

Push a Carp String reference onto the Lua stack. Wraps push-string with automatic cstr conversion.

push-copy

external

(Fn [(Ref Lua a), Int] ())

Push a copy of the element at index onto the top of the stack.

push-float

external

(Fn [(Ref Lua a), Float] ())

Push a float (Lua number) onto the stack.

push-global-table

external

(Fn [(Ref Lua a)] ())

Push the global table onto the stack.

push-int

external

(Fn [(Ref Lua a), Int] ())

Push an integer onto the stack.

push-light-user-data

external

(Fn [(Ref Lua a), (Ptr ())] ())

Push a light userdata pointer onto the stack.

push-nil

external

(Fn [(Ref Lua a)] ())

Push nil onto the stack.

push-string

instantiate

(Fn [(Ref Lua a), (Ptr CChar)] (Ptr CChar))

Push a C string onto the stack. For Carp strings, use push-carp-str instead.

push-thread

external

(Fn [(Ref Lua a)] ())

Push the current thread onto the stack.

set-field

external

(Fn [(Ref Lua a), Int, (Ptr CChar)] ())

Pop the top value and set it as field name on the table at index. Note: pushing a value shifts relative stack indices, so if the table is at -1, use -2 as the index after pushing. See Luax.set-int-field and friends for a safer interface.

set-global

external

(Fn [(Ref Lua a), (Ptr CChar)] ())

Pop the top value from the stack and set it as the named global.

set-string-global

defn

(Fn [(Ref Lua a), (Ref String b), (Ref String c)] ())

                        (set-string-global lua name s)
                    

Push s and assign it to the global name. For other types, see Luax.set-int-global and friends.

set-table

external

(Fn [(Ref Lua a), Int] ())

Pop a key and value from the stack and set them on the table at index. The value must be on top, with the key below it.

setup

dynamic

Dynamic

                        (setup location :rest cflag)
                    

Set up Lua includes and linking. location is the include path (e.g. "lua" or "lua5.4"). An optional second argument overrides the library name for linking (defaults to "lua").

table-length

defn

(Fn [(Ref Lua a), Int] Int)

                        (table-length lua index)
                    

Count the entries in the table at index by iterating with next. Returns -1 if the value at index is not a table. Leaves the stack unchanged.

to-string

instantiate

(Fn [(Ref Lua a), Int] (Ptr CChar))

Read the value at index as a C string pointer. Low-level alias; prefer Luax.get-carp-str.

type-of

external

(Fn [(Ref Lua a), Int] Int)

Return the type constant of the value at index. Compare against TYPE_NIL, TYPE_NUMBER, etc.

val

defn

(Fn [(Ref Lua a), (Ref String b), c] Int)

                        (val lua name value)
                    

Evaluate the Lua expression value and assign the result to the global name. Returns OK on success.

(Lua.val lua "pi" "3.14159")

with-lua

macro

Macro

                        (with-lua body)
                    

Like with-lua-as but binds the state to lua.

with-lua-as

macro

Macro

                        (with-lua-as name body)
                    

Create a Lua state bound to name, evaluate body, then close the state. Returns the result of body.

(Lua.with-lua-as L
  (do (Lua.libs L) (Lua.do-string L (cstr "print('hi')"))))

with-lua-do

macro

Macro

                        (with-lua-do :rest body)
                    

Like with-lua but wraps multiple body forms in a do block. This is the most common entry point.

(Lua.with-lua-do
  (Lua.libs lua)
  (Lua.push-int lua 42)
  (IO.println &(str (Lua.get-int lua -1))))