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.
call
(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.
create-table
(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
(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
(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
(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
(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
(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-field
(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
(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
(Fn [(Ref Lua a), (Ptr CChar)] ())
Push the value of the named global onto the stack.
get-int
(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
(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
(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
(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
(Fn [(Ref Lua a)] Int)
Return the index of the top element, which equals the number of elements on the stack.
get-user-data
(Fn [(Ref Lua a), Int] (Ptr ()))
Read the value at index as a userdata pointer.
global-exists?
(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.
load-buffer
(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
(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
(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.
push-carp-str
(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
(Fn [(Ref Lua a), Int] ())
Push a copy of the element at index onto the top of the stack.
push-light-user-data
(Fn [(Ref Lua a), (Ptr ())] ())
Push a light userdata pointer onto the stack.
push-string
(Fn [(Ref Lua a), (Ptr CChar)] (Ptr CChar))
Push a C string onto the stack. For Carp strings, use
push-carp-str instead.
set-field
(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
(Fn [(Ref Lua a), (Ptr CChar)] ())
Pop the top value from the stack and set it as the named global.
set-string-global
(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
(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
(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
(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
(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
(Fn [(Ref Lua a), Int] Int)
Return the type constant of the value at index. Compare against
TYPE_NIL, TYPE_NUMBER, etc.
val
(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-as
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
(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))))