Lua is a very simple scripting lanaguage. It has many quirks, such as:
local
keyword.print("Hello, World!") -- prints to stdout do -- a new scope (like { statements; } in C) global_var = 4319 -- Will be present in the whole program local local_var = 3043 -- Will only be present in this scope end print(global_var) --> 4319 print(local_var) --> nil local x, y = 12, 903.44 -- numbers can be floating-point local a, b, c = 'together', "c and", [[ see plus plus!!! ]] -- multiline string literal
-- In lua, if you don't specify table keys, they start at 1, and get incremented. local table_as_arr = {43, 12, "lua", 32.49} print(table_as_arr[1]) --> 43 print(table_as_arr[4]) --> 32.49 print(#table_as_arr) --> 4 -- Iterate over the table with `ipairs` to get all integer keys. for k, v in ipairs(table_as_arr) do print(k, v) end -- This table has string and number keys that are stated. -- It behaves like a hashmap (ex: an object in JS). local table_as_obj = {key = "val", foo = 98, [0.32] = "a", [".?ex="] = "b"} -- Iterate over the table with `pairs` to get all keys. for k, v in pairs(table_as_obj) do print(k, v) end
-- Lua has functions. function add(a, b) return a + b end print(add(1, 2)) --> 3 -- functions are first-class. local p = add print(p(1, 2)) --> 3 function run(cb) print(cb("hello", 1, 2)) end run(function(s, a, b) return string.format("a, b, s = %s, %d, %d", a, b, s) end) --> a, b, s = 1, 2, hello
Lua is a very small language, so although there is a lot left to cover, there is not too much. You can learn more about the Lua language by scouring the Web.
Lua is widely used as a configuration language, since it can easily be embedded into other programs. Lua is actually a library, and the interpreter is just a program that uses that library. Your program can also use that library in order to interface with a script for configuration. Some programs which embed Lua:
There are many versions of Lua, like 5.1, 5.2, 5.3, and 5.4. Unlike JavaScript, there is not a big push to use the latest version of Lua. I will be using Lua 5.1 for this tutorial because of LuaJIT, which I will explain right now.
LuaJIT has a C API just like regular Lua, and it models Lua 5.1's API. This means that if you write code that interfaces with Lua 5.1, you can link with LuaJIT instead of Lua 5.1 and get a much faster performance! This is why I am going to teach Lua 5.1's API for this tutorial.
To compile the program, link with either Lua 5.1 or LuaJIT:
gcc test.c `pkg-config --cflags --libs luajit` # compile with LuaJIT gcc test.c -I/path/to/luajit -lluajit # if you don't have pkg-config gcc test.c `pkg-config --cflags --libs lua5.1` # compile with regular Lua 5.1
The following program will run a file test.lua
in the same way that you would do lua test.lua
.
#include <lua.h> #include <lauxlib.h> #include <lualib.h> int main() { lua_State* L = luaL_newstate(); // This state will be passed around a lot luaL_openlibs(L); // Open the standard libraries luaL_dofile(L, "test.lua"); // Run the Lua file lua_close(L); // Free the state }
After compiling the executable, put print('hello')
in test.lua
.
Run the executable, and it should print hello
.
Now, let's learn how to pass data in and out of a Lua script.
You can get global variables from a Lua script with lua_getglobal()
.
lua_getglobal(L, "my_global"); double x = lua_tonumber(L, -1); printf("x is %f\n", x);
Since global functions are just global variables, you can call functions like this.
lua_getglobal(L, "print"); lua_pushstring(L, "Hello, World!"); // The first argument is the number of args, // The second argument is the number of returns, // The third argument is weird. lua_pcall(L, 1, LUA_MULTRET, 0);