Lua
This article introduce the programming language Lua.
Overview
What is Lua?
Lua is a powerful, efficient, lightweight, embeddable scripting language. It supports procedural programming, object-oriented programming, functional programming, data-driven programming, and data description.
Lua combines simple procedural syntax with powerful data description constructs based on associative arrays and extensible semantics. Lua is dynamically typed, runs by interpreting bytecode with a register-based virtual machine, and has automatic memory management with incremental garbage collection, making it ideal for configuration, scripting, and rapid prototyping.
Where does Lua come from?
Lua is designed, implemented, and maintained by a team at PUC-Rio, the Pontifical Catholic University of Rio de Janeiro in Brazil. Lua was born and raised in Tecgraf, formerly the Computer Graphics Technology Group of PUC-Rio. Lua is now housed at LabLua, a laboratory of the Department of Computer Science of PUC-Rio.
What’s in a name?
“Lua” (pronounced LOO-ah) means “Moon” in Portuguese. As such, it is neither an acronym nor an abbreviation, but a noun. More specifically, “Lua” is a name, the name of the Earth’s moon and the name of the language. Like most names, it should be written in lower case with an initial capital, that is, “Lua”. Please do not write it as “LUA”, which is both ugly and confusing, because then it becomes an acronym with different meanings for different people. So, please, write Lua right!
Showcase
Lua is used in many products and projects around the world. And here are some highlights.
Lua Tutorial
Refer to the following links:
- Lua Getting Started
- Programming in Lua (1st edition) [local pdf]
- Programming in Lua (2nd edition)
- Programming in Lua (3rd edition)
- Lua Documentation
- Lua 5.3 Reference Manual
- lua-users
- Lua Tutorial on RUNOOB.com
- Lua API Introduction [local pdf]
Keywords
Identifiers in Lua can be any string of letters, digits, and underscores, not beginning with a digit.
You should avoid identifiers starting with an underscore followed by one or more uppercase letters (e.g., _VERSION
); they are reserved for special uses in Lua. Usually, I reserve the identifier _
(a single underscore) for a dummy variable.
The following words are reserved; we cannot use them as identifiers:
and break do else elseif
end false for function if
in local nil not or
repeat return then true until
while
Lua is case-sensitive: and
is a reserved word, but And
and AND
are two other different identifiers.
Operators
Arithmetic Operators
Lua supports the usual arithmetic operators:
- the binary:
+
(addition),-
(subtraction),*
(multiplication),/
(division) - the unary:
-
(negation)
All of them operate on real numbers.
Lua also offers partial support for ^
(exponentiation).
Relational operators
< > <= >= == ~=
All these operators always result in true
or false
.
Logical Operators
The logical operators are and
, or
, and not
:
- All logical operators consider
false
andnil
as false and anything else as true. - The operator
and
returns its first argument if it is false; otherwise, it returns its second argument. - The operator
or
returns its first argument if it is not false; otherwise, it returns its second argument.
print(4 and 5) --> 5
print(nil and 13) --> nil
print(false and 13) --> false
print(4 or 5) --> 4
print(false or 5) --> 5
Concatenation
Lua denotes the string concatenation operator by ..
(two dots). If any of its operands is a number, Lua converts that number to a string.
print("Hello " .. "World") --> Hello World
print(0 .. 1) --> 01
Operator Precedence
According to Lua 5.4 Operator Precedence, the operator precedence in Lua follows the table below, from lower to higher priority:
or
and
< > <= >= ~= ==
|
~
&
<< >>
..
+ -
* / // %
unary operators (not # - ~)
^
All binary operators are left associative, except for ^
(exponentiation) and ..
(concatenation), which are right associative.
Comments
A comment starts anywhere with a double hyphen --
and runs until the end of the line. Lua also offers block comments, which start with --[[
and run until the corresponding ]]
. A common trick, when we want to comment out a piece of code, is to write the following:
--[[
print(10) -- no action (comment)
--]]
Now, if we add a single hyphen to the first line, the code is in again:
---[[
print(10) --> 10
--]]
Variables
Variables are places that store values. There are three kinds of variables in Lua:
- Global variables: Any variable name is assumed to be global unless explicitly declared as a
local
. - Local variables: Local variables are lexically scoped: local variables can be freely accessed by functions defined inside their scope.
- Table fields: This is a special type of variable that can hold anything except nil including functions.
Global Variables
Lua keeps all its global variables in a regular table, called the environment. Lua stores the environment itself in a global variable _G
. The following code prints the names of all global variables defined in the current environment:
for n in pairs(_G) do
print(n)
end
Take lua5.3 for instance:
chenwx@chenwx:~ $ lua5.3
Lua 5.3.3 Copyright (C) 1994-2016 Lua.org, PUC-Rio
> for n in pairs(_G) do print(n) end
next
tostring
rawget
rawset
dofile
print
rawlen
xpcall
_G
utf8
pairs
error
table
load
rawequal
setmetatable
pcall
collectgarbage
tonumber
bit32
package
select
assert
io
type
loadfile
arg
debug
require
math
getmetatable
os
string
ipairs
coroutine
_VERSION
Local Variable
It is good programming style to use local variables whenever possible. Local variables help you avoid cluttering the global environment with unnecessary names. Moreover, the access to local variables is faster than to global ones.
Control Structures
if-then-else-end
if op == "+" then
r = a + b
elseif op == "-" then
r = a - b
elseif op == "*" then
r = a*b
elseif op == "/" then
r = a/b
else
error("invalid operation")
end
while-do-end
local i = 1
while a[i] do
print(a[i])
i = i + 1
end
repeat-until
The test is done after the body, so the body is always executed at least once.
-- print the first non-empty line
repeat
line = os.read()
until line ~= ""
print(line)
for
The for
statement has two variants: the numeric for and the generic for.
Numeric for
A numeric for has the following syntax:
for var=exp1,exp2,exp3 do
something
end
That loop will execute something for each value of var from exp1 to exp2, using exp3 as the step to increment var. This third expression is optional; when absent, Lua assumes one as the step value. As typical examples of such loops, we have
for i=1,f(x) do
print(i)
end
for i=10,1,-1 do
print(i)
end
The for
loop has some subtleties that you should learn in order to make good use of it.
-
First, all three expressions are evaluated once, before the loop starts. For instance, in the first example, f(x) is called only once.
-
Second, the control variable is a local variable automatically declared by the
for
statement and is visible only inside the loop. A typical mistake is to assume that the variable still exists after the loop ends:
for i=1,10 do
print(i)
end
max = i -- probably wrong! 'i' here is global
- Third, you should never change the value of the control variable: The effect of such changes is unpredictable. If you want to break a for loop before its normal termination, use
break
.
Generic for
The generic for loop allows you to traverse all values returned by an iterator function. For each step in below code, i gets an index, while v gets the value associated with that index:
-- print all values of array 'a'
for i,v in ipairs(a) do
print(v)
end
The generic loop shares two properties with the numeric loop: The loop variables are local to the loop body and you should never assign any value to the loop variables.
Functions
If the function call has no arguments, we must write an empty list ()
to indicate the call. There is a special case to this rule: If the function has one single argument and this argument is either a literal string or a table constructor, then the parentheses are optional:
print "Hello World" <--> print("Hello World")
dofile 'a.lua' <--> dofile ('a.lua')
print [[a multi-line <--> print([[a multi-line
message]] message]])
f{x=10, y=20} <--> f({x=10, y=20})
type{} <--> type({})
Lua also offers a special syntax for object-oriented calls, the colon operator. An expression like o:foo(x)
is just another way to write o.foo(o, x)
, that is, to call o.foo
adding o as a first extra argument.
Functions used by a Lua program can be defined both in Lua and in C (or in any other language used by the host application).
-- add all elements of array `a'
function add (a)
local sum = 0
for i,v in ipairs(a) do
sum = sum + v
end
return sum
end
You can call a function with a number of arguments different from its number of parameters. Lua adjusts the number of arguments to the number of parameters, as it does in a multiple assignment: Extra arguments are thrown away; extra parameters get nil. For instance, if we have a function like:
function f(a, b)
return a or b
end
we will have the following mapping from arguments to parameters:
CALL PARAMETERS
f(3) a=3, b=nil
f(3, 4) a=3, b=4
f(3, 4, 5) a=3, b=4 (5 is discarded)
Although this behavior can lead to programming errors (easily spotted at run time), it is also useful, especially for default arguments. For instance, consider the following function, to increment a global counter.
function incCount (n)
n = n or 1
count = count + n
end
This function has 1 as its default argument; that is, the call incCount()
, without arguments, increments count by one. When you call incCount()
, Lua first initializes n with nil; the or results in its second operand; and as a result Lua assigns a default 1 to n.
Multiple Results
An unconventional, but quite convenient feature of Lua is that functions may return multiple results. Functions written in Lua also can return multiple results, by listing them all after the return keyword.
In a multiple assignment, a function call as the last (or only) expression produces as many results as needed to match the variables.
If a function has no results, or not as many results as we need, Lua produces nils.
A function call that is not the last element in the list always produces one result.
When a function call is the last (or the only) argument to another call, all results from the first call go as arguments.
You can force a call to return exactly one result by enclosing it in an extra pair of parentheses.
A special function with multiple returns is unpack. It receives an array and returns as results all elements from the array, starting from index 1.
Variable Number of Arguments
The three dots ...
in the parameter list indicate that the function has a variable number of arguments. When this function is called, all its arguments are collected in a single table, which the function accesses as a hidden parameter named arg
. Besides those arguments, the arg
table has an extra field, n
, with the actual number of arguments collected.
function print (...)
print(arg[n] .. " elements in input parameter arg:")
for i,v in ipairs(arg) do
print(tostring(i) .. tostring(v) .. "\n")
end
end
When we write a function that returns multiple values into an expression, only its first result is used. However, sometimes we want another result. A typical solution is to use dummy variables; for instance, if we want only the second result from string.find, we may write the following code:
local _, x = string.find(s, p)
-- now use `x'
...
An alternative solution is to define a select
function, which selects a specific return from a function:
print(string.find("hello hello", " hel")) --> 6 9
print(select(1, string.find("hello hello", " hel"))) --> 6
print(select(2, string.find("hello hello", " hel"))) --> 9
More about Functions
Functions in Lua are first-class values with proper lexical scoping:
-
first-class values means that, in Lua, a function is a value with the same rights as conventional values like numbers and strings. Functions can be stored in variables (both global and local) and in tables, can be passed as arguments, and can be returned by other functions.
-
lexical scoping means that functions can access variables of its enclosing functions. (It also means that Lua contains the lambda calculus properly.)
A somewhat difficult notion in Lua is that functions, like all other values, are anonymous; they do not have names. When we talk about a function name, say print
, we are actually talking about a variable that holds that function. Like any other variable holding any other value, we can manipulate such variables in many ways.
In fact, the usual way to write a function in Lua, like:
function foo (x) return 2*x end
is just an instance of what we call syntactic sugar; in other words, it is just a pretty way to write:
foo = function (x) return 2*x end
That is, a function definition is in fact a statement (an assignment, more specifically) that assigns a value of type function
to a variable. We can see the expression function (x) ... end
as a function constructor, just as {}
is a table constructor. We call the result of such function constructors an anonymous function. Although we usually assign functions to global names, giving them something like a name, there are several occasions when functions remain anonymous.
A function that gets another function as an argument, such as sort, is what we call a higher-order function. Higher-order functions are a powerful programming mechanism and the use of anonymous functions to create their function arguments is a great source of flexibility. But remember that higher-order functions have no special rights; they are a simple consequence of the ability of Lua to handle functions as first-class values.
Data Structures
- Lua数据结构: TValue [local pdf]
- Lua数据结构: TString [local pdf]
- Lua数据结构: Table [local pdf]
- Lua数据结构: 闭包 [local pdf]
- Lua数据结构: Udata [local pdf]
- Lua数据结构: lua_State [local pdf]
Install Lua on LinuxMint
Install Lua via APT
One way to install Lua on LinuxMint is using apt
to install it in binary:
chenwx@chenwx:~ $ sudo apt install lua
[sudo] password for chenwx:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package lua is a virtual package provided by:
lua50 5.0.3-8
lua5.3 5.3.3-1
lua5.2 5.2.4-1.1build1
lua5.1 5.1.5-8.1build2
You should explicitly select one to install.
E: Package 'lua' has no installation candidate
chenwx@chenwx:~ $ sudo apt install lua5.3
Reading package lists... Done
Building dependency tree
Reading state information... Done
lua5.3 is already the newest version (5.3.3-1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
chenwx@chenwx:~ $ which lua5.3
/usr/bin/lua5.3
chenwx@chenwx:~ $ lua5.3 -v
Lua 5.3.3 Copyright (C) 1994-2016 Lua.org, PUC-Rio
Build Lua from Source Code
Lua is free software distributed in source code. So, it’s possible to download Lua’s source code and build it from scratch:
chenwx@chenwx:~ $ mkdir lua
chenwx@chenwx:~ $ cd lua
chenwx@chenwx:~/lua $ curl -R -O http://www.lua.org/ftp/lua-5.3.1.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 275k 100 275k 0 0 36275 0 0:00:07 0:00:07 --:--:-- 66151
chenwx@chenwx:~/lua $ tar zxf lua-5.3.1.tar.gz
chenwx@chenwx:~/lua $ cd lua-5.3.1
chenwx@chenwx:~/lua/lua-5.3.1 $ make linux test
cd src && make linux
make[1]: Entering directory '/home/chenwx/lua/lua-5.3.1/src'
make all SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
make[2]: Entering directory '/home/chenwx/lua/lua-5.3.1/src'
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lapi.o lapi.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lcode.o lcode.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lctype.o lctype.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldebug.o ldebug.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldo.o ldo.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldump.o ldump.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lfunc.o lfunc.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lgc.o lgc.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o llex.o llex.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lmem.o lmem.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lobject.o lobject.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lopcodes.o lopcodes.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lparser.o lparser.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lstate.o lstate.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lstring.o lstring.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ltable.o ltable.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ltm.o ltm.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lundump.o lundump.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lvm.o lvm.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lzio.o lzio.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lauxlib.o lauxlib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lbaselib.o lbaselib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lbitlib.o lbitlib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lcorolib.o lcorolib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldblib.o ldblib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o liolib.o liolib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lmathlib.o lmathlib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o loslib.o loslib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lstrlib.o lstrlib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ltablib.o ltablib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lutf8lib.o lutf8lib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o loadlib.o loadlib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o linit.o linit.c
ar rcu liblua.a lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o
ar: `u' modifier ignored since `D' is the default (see `U')
ranlib liblua.a
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lua.o lua.c
gcc -std=gnu99 -o lua lua.o liblua.a -lm -Wl,-E -ldl -lreadline
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o luac.o luac.c
gcc -std=gnu99 -o luac luac.o liblua.a -lm -Wl,-E -ldl -lreadline
make[2]: Leaving directory '/home/chenwx/lua/lua-5.3.1/src'
make[1]: Leaving directory '/home/chenwx/lua/lua-5.3.1/src'
src/lua -v
Lua 5.3.1 Copyright (C) 1994-2015 Lua.org, PUC-Rio
chenwx@chenwx:~/lua/lua-5.3.1 $ ll src/lua src/luac
-rwxr-xr-x 1 chenwx chenwx 254K Jan 8 22:23 src/lua
-rwxr-xr-x 1 chenwx chenwx 167K Jan 8 22:23 src/luac
chenwx@chenwx:~/lua/lua-5.3.1 $ ./src/lua -v
Lua 5.3.1 Copyright (C) 1994-2015 Lua.org, PUC-Rio
chenwx@chenwx:~/lua/lua-5.3.1 $ ./src/luac -v
Lua 5.3.1 Copyright (C) 1994-2015 Lua.org, PUC-Rio
Usage of Lua Interpreter
man page of Lua interpreter:
chenwx@chenwx:~ $ which lua5.3
/usr/bin/lua5.3
chenwx@chenwx:~ $ man lua
LUA5.3(1) General Commands Manual LUA5.3(1)
NAME
lua - Lua interpreter
SYNOPSIS
lua [ options ] [ script [ args ] ]
DESCRIPTION
lua is the standalone Lua interpreter. It loads and executes Lua
programs, either in textual source form or in precompiled binary
form. (Precompiled binaries are output by luac, the Lua compiler.)
lua can be used as a batch interpreter and also interactively.
The given options are handled in order and then the Lua program in
file script is loaded and executed. The given args are available to
script as strings in a global table named arg. If no options or
arguments are given, then -v -i is assumed when the standard input is
a terminal; otherwise, - is assumed.
In interactive mode, lua prompts the user, reads lines from the stan-
dard input, and executes them as they are read. If the line contains
an expression or list of expressions, then the line is evaluated and
the results are printed. If a line does not contain a complete
statement, then a secondary prompt is displayed and lines are read
until a complete statement is formed or a syntax error is found.
At the very start, before even handling the command line, lua checks
the contents of the environment variables LUA_INIT_5_3 or LUA_INIT,
in that order. If the contents is of the form '@filename', then
filename is executed. Otherwise, the string is assumed to be a Lua
statement and is executed.
OPTIONS
-e stat
execute statement stat.
-i enter interactive mode after executing script.
-l name
execute the equivalent of name=require('name') before execut-
ing script.
-v show version information.
-E ignore environment variables.
-- stop handling options.
- stop handling options and execute the standard input as a
file.
SEE ALSO
luac(1)
The documentation at lua.org, especially section 7 of the reference
manual.
DIAGNOSTICS
Error messages should be self explanatory.
AUTHORS
R. Ierusalimschy, L. H. de Figueiredo, W. Celes
$Date: 2014/12/10 15:55:45 $ LUA5.3(1)
Usage of Lua Compiler
man page of Lua compiler:
chenwx@chenwx:~ $ which luac5.3
/usr/bin/luac5.3
chenwx@chenwx:~ $ man lua
LUAC5.3(1) General Commands Manual LUAC5.3(1)
NAME
luac - Lua compiler
SYNOPSIS
luac [ options ] [ filenames ]
DESCRIPTION
luac is the Lua compiler. It translates programs written in the Lua
programming language into binary files containing precompiled chunks
that can be later loaded and executed.
The main advantages of precompiling chunks are: faster loading, pro-
tecting source code from accidental user changes, and off-line syntax
checking. Precompiling does not imply faster execution because in
Lua chunks are always compiled into bytecodes before being executed.
luac simply allows those bytecodes to be saved in a file for later
execution. Precompiled chunks are not necessarily smaller than the
corresponding source. The main goal in precompiling is faster load-
ing.
In the command line, you can mix text files containing Lua source and
binary files containing precompiled chunks. luac produces a single
output file containing the combined bytecodes for all files given.
Executing the combined file is equivalent to executing the given
files. By default, the output file is named luac.out, but you can
change this with the -o option.
Precompiled chunks are not portable across different architectures.
Moreover, the internal format of precompiled chunks is likely to
change when a new version of Lua is released. Make sure you save the
source files of all Lua programs that you precompile.
OPTIONS
-l produce a listing of the compiled bytecode for Lua's virtual
machine. Listing bytecodes is useful to learn about Lua's
virtual machine. If no files are given, then luac loads
luac.out and lists its contents. Use -l -l for a full list-
ing.
-o file
output to file, instead of the default luac.out. (You can use
'-' for standard output, but not on platforms that open stan-
dard output in text mode.) The output file may be one of the
given files because all files are loaded before the output
file is written. Be careful not to overwrite precious files.
-p load files but do not generate any output file. Used mainly
for syntax checking and for testing precompiled chunks: cor-
rupted files will probably generate errors when loaded. If no
files are given, then luac loads luac.out and tests its con-
tents. No messages are displayed if the file loads without
errors.
-s strip debug information before writing the output file. This
saves some space in very large chunks, but if errors occur
when running a stripped chunk, then the error messages may not
contain the full information they usually do. In particular,
line numbers and names of local variables are lost.
-v show version information.
-- stop handling options.
- stop handling options and process standard input.
SEE ALSO
lua(1)
The documentation at lua.org.
DIAGNOSTICS
Error messages should be self explanatory.
AUTHORS
R. Ierusalimschy, L. H. de Figueiredo, W. Celes
$Date: 2011/11/16 13:53:40 $ LUAC5.3(1)
Compile Lua Code to Bytecode
The Lua compiler luac
translates programs written in the Lua programming language into binary files containing precompiled chunks that can be later loaded and executed. Refer to luac man page for details.
chenwx@chenwx:~/lua $ cat hello.lua
function max(num1, num2)
if (num1 > num2) then
result = num1;
else
result = num2;
end
return result;
end
print("max value is ", max(10,4))
print("max value is ", max(5,6))
chenwx@chenwx:~/lua $ luac5.3 hello.lua
chenwx@chenwx:~/lua $ ll
-rw-r--r-- 1 chenwx chenwx 201 Jan 8 23:10 hello.lua
drwxr-xr-x 4 chenwx chenwx 4.0K Jun 10 2015 lua-5.3.1
-rw-r--r-- 1 chenwx chenwx 435 Jan 8 23:10 luac.out
drwxr-xr-x 18 chenwx chenwx 4.0K Jan 8 23:06 luadec
chenwx@chenwx:~/lua $ hexdump -C luac.out
00000000 1b 4c 75 61 53 00 19 93 0d 0a 1a 0a 04 08 04 08 |.LuaS...........|
00000010 08 78 56 00 00 00 00 00 00 00 00 00 00 00 28 77 |.xV...........(w|
00000020 40 01 0b 40 68 65 6c 6c 6f 2e 6c 75 61 00 00 00 |@..@hello.lua...|
00000030 00 00 00 00 00 00 01 05 11 00 00 00 2c 00 00 00 |............,...|
00000040 08 00 00 80 06 40 40 00 41 80 00 00 86 00 40 00 |.....@@.A.....@.|
00000050 c1 c0 00 00 01 01 01 00 a4 00 80 01 24 40 00 00 |............$@..|
00000060 06 40 40 00 41 80 00 00 86 00 40 00 c1 40 01 00 |.@@.A.....@..@..|
00000070 01 81 01 00 a4 00 80 01 24 40 00 00 26 00 80 00 |........$@..&...|
00000080 07 00 00 00 04 04 6d 61 78 04 06 70 72 69 6e 74 |......max..print|
00000090 04 0e 6d 61 78 20 76 61 6c 75 65 20 69 73 20 13 |..max value is .|
000000a0 0a 00 00 00 00 00 00 00 13 04 00 00 00 00 00 00 |................|
000000b0 00 13 05 00 00 00 00 00 00 00 13 06 00 00 00 00 |................|
000000c0 00 00 00 01 00 00 00 01 00 01 00 00 00 00 01 00 |................|
000000d0 00 00 0a 00 00 00 02 00 03 08 00 00 00 20 00 80 |............. ..|
000000e0 00 1e 40 00 80 08 00 00 80 1e 00 00 80 08 40 00 |..@...........@.|
000000f0 80 86 00 40 00 a6 00 00 01 26 00 80 00 01 00 00 |...@.....&......|
00000100 00 04 07 72 65 73 75 6c 74 01 00 00 00 00 00 00 |...result.......|
00000110 00 00 00 08 00 00 00 03 00 00 00 03 00 00 00 04 |................|
00000120 00 00 00 04 00 00 00 06 00 00 00 09 00 00 00 09 |................|
00000130 00 00 00 0a 00 00 00 02 00 00 00 05 6e 75 6d 31 |............num1|
00000140 00 00 00 00 08 00 00 00 05 6e 75 6d 32 00 00 00 |.........num2...|
00000150 00 08 00 00 00 01 00 00 00 05 5f 45 4e 56 11 00 |.........._ENV..|
00000160 00 00 0a 00 00 00 01 00 00 00 0c 00 00 00 0c 00 |................|
00000170 00 00 0c 00 00 00 0c 00 00 00 0c 00 00 00 0c 00 |................|
00000180 00 00 0c 00 00 00 0d 00 00 00 0d 00 00 00 0d 00 |................|
00000190 00 00 0d 00 00 00 0d 00 00 00 0d 00 00 00 0d 00 |................|
000001a0 00 00 0d 00 00 00 00 00 00 00 01 00 00 00 05 5f |..............._|
000001b0 45 4e 56 |ENV|
000001b3
chenwx@chenwx:~/lua $ lua5.3 luac.out
max value is 10
max value is 6
Encode/Decode Lua Bytecode via Base64
The Lua bytecode can be encoded or decoded by tool base64:
chenwx@chenwx:~/lua $ base64 --help
Usage: base64 [OPTION]... [FILE]
Base64 encode or decode FILE, or standard input, to standard output.
With no FILE, or when FILE is -, read standard input.
Mandatory arguments to long options are mandatory for short options too.
-d, --decode decode data
-i, --ignore-garbage when decoding, ignore non-alphabet characters
-w, --wrap=COLS wrap encoded lines after COLS character (default 76).
Use 0 to disable line wrapping
--help display this help and exit
--version output version information and exit
The data are encoded as described for the base64 alphabet in RFC 4648.
When decoding, the input may contain newlines in addition to the bytes of
the formal base64 alphabet. Use --ignore-garbage to attempt to recover
from any other non-alphabet bytes in the encoded stream.
GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Report base64 translation bugs to <http://translationproject.org/team/>
Full documentation at: <http://www.gnu.org/software/coreutils/base64>
or available locally via: info '(coreutils) base64 invocation'
chenwx@chenwx:~/lua $ base64 luac.out > luac.out.encode
chenwx@chenwx:~/lua $ cat luac.out.encode
G0x1YVMAGZMNChoKBAgECAh4VgAAAAAAAAAAAAAAKHdAAQtAaGVsbG8ubHVhAAAAAAAAAAAAAQUR
AAAALAAAAAgAAIAGQEAAQYAAAIYAQADBwAAAAQEBAKQAgAEkQAAABkBAAEGAAACGAEAAwUABAAGB
AQCkAIABJEAAACYAgAAHAAAABARtYXgEBnByaW50BA5tYXggdmFsdWUgaXMgEwoAAAAAAAAAEwQA
AAAAAAAAEwUAAAAAAAAAEwYAAAAAAAAAAQAAAAEAAQAAAAABAAAACgAAAAIAAwgAAAAgAIAAHkAA
gAgAAIAeAACACEAAgIYAQACmAAABJgCAAAEAAAAEB3Jlc3VsdAEAAAAAAAAAAAAIAAAAAwAAAAMA
AAAEAAAABAAAAAYAAAAJAAAACQAAAAoAAAACAAAABW51bTEAAAAACAAAAAVudW0yAAAAAAgAAAAB
AAAABV9FTlYRAAAACgAAAAEAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADQAAAA0AAAAN
AAAADQAAAA0AAAANAAAADQAAAA0AAAAAAAAAAQAAAAVfRU5W
chenwx@chenwx:~/lua $ base64 -d luac.out.encode > luac.out.decode
chenwx@chenwx:~/lua $ hexdump -C luac.out.decode
00000000 1b 4c 75 61 53 00 19 93 0d 0a 1a 0a 04 08 04 08 |.LuaS...........|
00000010 08 78 56 00 00 00 00 00 00 00 00 00 00 00 28 77 |.xV...........(w|
00000020 40 01 0b 40 68 65 6c 6c 6f 2e 6c 75 61 00 00 00 |@..@hello.lua...|
00000030 00 00 00 00 00 00 01 05 11 00 00 00 2c 00 00 00 |............,...|
00000040 08 00 00 80 06 40 40 00 41 80 00 00 86 00 40 00 |.....@@.A.....@.|
00000050 c1 c0 00 00 01 01 01 00 a4 00 80 01 24 40 00 00 |............$@..|
00000060 06 40 40 00 41 80 00 00 86 00 40 00 c1 40 01 00 |.@@.A.....@..@..|
00000070 01 81 01 00 a4 00 80 01 24 40 00 00 26 00 80 00 |........$@..&...|
00000080 07 00 00 00 04 04 6d 61 78 04 06 70 72 69 6e 74 |......max..print|
00000090 04 0e 6d 61 78 20 76 61 6c 75 65 20 69 73 20 13 |..max value is .|
000000a0 0a 00 00 00 00 00 00 00 13 04 00 00 00 00 00 00 |................|
000000b0 00 13 05 00 00 00 00 00 00 00 13 06 00 00 00 00 |................|
000000c0 00 00 00 01 00 00 00 01 00 01 00 00 00 00 01 00 |................|
000000d0 00 00 0a 00 00 00 02 00 03 08 00 00 00 20 00 80 |............. ..|
000000e0 00 1e 40 00 80 08 00 00 80 1e 00 00 80 08 40 00 |..@...........@.|
000000f0 80 86 00 40 00 a6 00 00 01 26 00 80 00 01 00 00 |...@.....&......|
00000100 00 04 07 72 65 73 75 6c 74 01 00 00 00 00 00 00 |...result.......|
00000110 00 00 00 08 00 00 00 03 00 00 00 03 00 00 00 04 |................|
00000120 00 00 00 04 00 00 00 06 00 00 00 09 00 00 00 09 |................|
00000130 00 00 00 0a 00 00 00 02 00 00 00 05 6e 75 6d 31 |............num1|
00000140 00 00 00 00 08 00 00 00 05 6e 75 6d 32 00 00 00 |.........num2...|
00000150 00 08 00 00 00 01 00 00 00 05 5f 45 4e 56 11 00 |.........._ENV..|
00000160 00 00 0a 00 00 00 01 00 00 00 0c 00 00 00 0c 00 |................|
00000170 00 00 0c 00 00 00 0c 00 00 00 0c 00 00 00 0c 00 |................|
00000180 00 00 0c 00 00 00 0d 00 00 00 0d 00 00 00 0d 00 |................|
00000190 00 00 0d 00 00 00 0d 00 00 00 0d 00 00 00 0d 00 |................|
000001a0 00 00 0d 00 00 00 00 00 00 00 01 00 00 00 05 5f |..............._|
000001b0 45 4e 56 |ENV|
000001b3
chenwx@chenwx:~/lua $ diff luac.out luac.out.decode
chenwx@chenwx:~/lua $
chenwx@chenwx:~/lua $ ./lua-5.3.1/src/lua luac.out.decode
max value is 10
max value is 6
Decode Lua Bytecode
Lua bytecode has format as specified on Lua 5.3 Bytecode Reference. It’s possible to use LuaDec to decode Lua bytecode:
chenwx@chenwx:~/lua $ git clone https://github.com/viruscamp/luadec
Cloning into 'luadec'...
remote: Enumerating objects: 2117, done.
remote: Total 2117 (delta 0), reused 0 (delta 0), pack-reused 2117
Receiving objects: 100% (2117/2117), 2.65 MiB | 56.00 KiB/s, done.
Resolving deltas: 100% (1308/1308), done.
chenwx@chenwx:~/lua $ cd luadec/
chenwx@chenwx:~/lua/luadec $ git submodule update --init lua-5.3
Submodule 'lua-5.3' (https://github.com/viruscamp/lua5) registered for path 'lua-5.3'
Cloning into '/home/chenwx/lua/luadec/lua-5.3'...
Submodule path 'lua-5.3': checked out 'f9785d609d20af8d28b05a05a757dad5ed770852'
chenwx@chenwx:~/lua/luadec $ cd lua-5.3
chenwx@chenwx:~/lua/luadec/lua-5.3 $ git lhg -10
* f9785d609d20 2016-09-22 VirusCamp (HEAD, tag: 5.3.3) lua-5.3.3 2016-05-30
* 36ebdad2ed40 2016-09-22 VirusCamp (tag: 5.3.2) lua-5.3.2 2015-11-25
* 8071eaea5ad7 2016-09-22 VirusCamp (tag: 5.3.1) lua-5.3.1 2015-06-10
* 23c9a0ef6222 2015-03-28 VirusCamp (tag: 5.3.0) lua-5.3.0 2015-01-06
* 06b0e58ae7f2 2014-11-12 VirusCamp lua-5.3.0-beta 2014-10-23
* 267b4bd00ed6 2014-11-12 VirusCamp lua-5.3.0-alpha 2014-07-31
* 680bf808e382 2014-11-12 VirusCamp lua-5.3.0-work3 2014-06-19
* 47cf35766408 2014-11-12 VirusCamp lua-5.3.0-work2 2014-03-21
* 184a12c4a46d 2014-11-12 VirusCamp lua-5.3.0-work1 2013-07-06
* 5a39d6da6297 2014-10-18 viruscamp (tag: 5.2.3) lua-5.2.3 2013-11-11
chenwx@chenwx:~/lua/luadec/lua-5.3 $ git co 5.3.1
Previous HEAD position was f9785d609d20 lua-5.3.3 2016-05-30
HEAD is now at 8071eaea5ad7 lua-5.3.1 2015-06-10
chenwx@chenwx:~/lua/luadec/lua-5.3 $ cd ../
chenwx@chenwx:~/lua/luadec $ git submodule status
-e496bc6df2e49ea0beebb26f216aca3821a2b28e LuaAssemblyTools
-c9ef6799113e71d89d629b29b266d1eba4105038 ilua
-cdcfa70f2f731409046374e797a62314b4924b77 lua-5.1
-0137406b0635f22f5c9b894e0da1d15abdb036bc lua-5.2
+8071eaea5ad72343d6873ade47d947c42d76bae9 lua-5.3 (5.3.1)
-79c86d1b258b13dc0d1a2a66f28aadc0f6e23944 memwatch
chenwx@chenwx:~/lua/luadec $ cd lua-5.3/
chenwx@chenwx:~/lua/luadec/lua-5.3 $ make linux
cd src && make linux
make[1]: Entering directory '/home/chenwx/lua/luadec/lua-5.3/src'
make all SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
make[2]: Entering directory '/home/chenwx/lua/luadec/lua-5.3/src'
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lapi.o lapi.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lcode.o lcode.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lctype.o lctype.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldebug.o ldebug.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldo.o ldo.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldump.o ldump.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lfunc.o lfunc.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lgc.o lgc.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o llex.o llex.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lmem.o lmem.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lobject.o lobject.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lopcodes.o lopcodes.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lparser.o lparser.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lstate.o lstate.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lstring.o lstring.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ltable.o ltable.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ltm.o ltm.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lundump.o lundump.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lvm.o lvm.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lzio.o lzio.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lauxlib.o lauxlib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lbaselib.o lbaselib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lbitlib.o lbitlib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lcorolib.o lcorolib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldblib.o ldblib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o liolib.o liolib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lmathlib.o lmathlib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o loslib.o loslib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lstrlib.o lstrlib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ltablib.o ltablib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lutf8lib.o lutf8lib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o loadlib.o loadlib.c
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o linit.o linit.c
ar rcu liblua.a lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o
ar: `u' modifier ignored since `D' is the default (see `U')
ranlib liblua.a
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lua.o lua.c
gcc -std=gnu99 -o lua lua.o liblua.a -lm -Wl,-E -ldl -lreadline
gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o luac.o luac.c
gcc -std=gnu99 -o luac luac.o liblua.a -lm -Wl,-E -ldl -lreadline
make[2]: Leaving directory '/home/chenwx/lua/luadec/lua-5.3/src'
make[1]: Leaving directory '/home/chenwx/lua/luadec/lua-5.3/src'
chenwx@chenwx:~/lua/luadec/lua-5.3 $ cd ../luadec
chenwx@chenwx:~/lua/luadec/luadec $ make LUAVER=5.3
gcc -O2 -Wall -DSRCVERSION=\"895d92313fab\" -I../lua-5.3/src -c -o guess.o guess.c
...
gcc -o luaopswap luaopswap.o ../lua-5.3/src/liblua.a -lm
chenwx@chenwx:~/lua/luadec/luadec $ cd ../..
chenwx@chenwx:~/lua $ ll
-rw-r--r-- 1 chenwx chenwx 201 Jan 8 23:10 hello.lua
drwxr-xr-x 4 chenwx chenwx 4.0K Jun 10 2015 lua-5.3.1
-rw-r--r-- 1 chenwx chenwx 435 Jan 8 23:10 luac.out
-rw-r--r-- 1 chenwx chenwx 435 Jan 9 21:19 luac.out.decode
-rw-r--r-- 1 chenwx chenwx 588 Jan 9 21:19 luac.out.encode
drwxr-xr-x 18 chenwx chenwx 4.0K Jan 8 23:06 luadec
chenwx@chenwx:~/lua $ ./luadec/luadec/luadec luac.out
-- Decompiled using luadec 2.2 rev: 895d92313fab for Lua 5.3 from https://github.com/viruscamp/luadec
-- Command line: luac.out
-- params : ...
-- function num : 0 , upvalues : _ENV
max = function(num1, num2)
-- function num : 0_0 , upvalues : _ENV
if num2 < num1 then
result = num1
else
result = num2
end
return result
end
print("max value is ", max(10, 4))
print("max value is ", max(5, 6))
chenwx@chenwx:~/lua $ ./luadec/luadec/luadec luac.out.decode
-- Decompiled using luadec 2.2 rev: 895d92313fab for Lua 5.3 from https://github.com/viruscamp/luadec
-- Command line: luac.out.decode
-- params : ...
-- function num : 0 , upvalues : _ENV
max = function(num1, num2)
-- function num : 0_0 , upvalues : _ENV
if num2 < num1 then
result = num1
else
result = num2
end
return result
end
print("max value is ", max(10, 4))
print("max value is ", max(5, 6))
Projects
LuatOS
Examples
Example 1: Print global variables
local g_str_key = "key : "
local g_str_type = "type : "
local g_str_len = "length : "
local g_str_value = "value : "
local g_str_prefix = " "
local g_max_layer = 10
function print_table(table, num_of_layer)
local type_of_table = type(table)
if type_of_table ~= "table" then
return
end
local str_prefix = string.rep(g_str_prefix, num_of_layer)
-- loop all elements in this table
for key, value in pairs(table) do
str_tmp = string.format("\n%s%s%s", str_prefix, g_str_key, key)
print(str_tmp)
local type_of_value = type(value)
str_tmp = string.format("%s%s%s", str_prefix, g_str_type, type_of_value)
print(str_tmp)
if type_of_value == "string" then
str_tmp = string.format("%s%s%s", str_prefix, g_str_value, value)
print(str_tmp)
elseif (type_of_value == "table") and -- loop next table
(key ~= "_G") and -- exclude table _G
(num_of_layer <= g_max_layer) then -- limit number of layers
local len_of_table = 0
for _, _ in pairs(value) do
len_of_table = len_of_table + 1
end
str_tmp = string.format("%s%s%s", str_prefix, g_str_len, len_of_table)
print(str_tmp)
print_table(value, num_of_layer + 1)
end
end
end
-- print table _G
function print_G()
local num_of_layer = 0
local str_prefix = string.rep(g_str_prefix, num_of_layer)
local str_tmp = string.format("%s%s%s", str_prefix, g_str_key, "_G")
print(str_tmp)
local type_of_value = type(_G)
str_tmp = string.format("%s%s%s", str_prefix, g_str_type, type_of_value)
print(str_tmp)
local len_of_table = 0
for _, _ in pairs(_G) do
len_of_table = len_of_table + 1
end
str_tmp = string.format("%s%s%s", str_prefix, g_str_len, len_of_table)
print(str_tmp)
print_table(_G, 0)
end
-- main entry
print_G()
Example 2: Print boolean variables
function print_boolean(arg)
print(arg and "true" or "false")
end
print_boolean(true)
print_boolean(false)
Example 3: Get length of table
Lua code:
function get_len(t)
local len = 0
for k, v in pairs(t) do
len = len + 1
end
return len
end
function print_table(t)
print("{")
for k, v in pairs(t) do
print(" [" .. k .. "] = " .. v .. ",")
end
print("}")
end
t = { [1] = 11, [2] = 22, [4] = 44 }
print("get_len(t) = " .. get_len(t))
print("#t = " .. #t)
-- print("table.concat(t) = " .. table.concat(t))
print_table(t)
t = { 11, 22, 44 }
print("get_len(t) = " .. get_len(t))
print("#t = " .. #t)
print("table.concat(t, ', ') = " .. table.concat(t, ', '))
print_table(t)
Output:
get_len(t) = 3
#t = 4
{
[1] = 11,
[2] = 22,
[4] = 44,
}
get_len(t) = 3
#t = 3
table.concat(t, ', ') = 11, 22, 44
{
[1] = 11,
[2] = 22,
[3] = 44,
}
References
- Lua Offical Site
- Lua on Wikipedia
- Lua Getting Started
- Lua Documentation
- Lua cheatsheet
- Lua Tutorial on RUNOOB.com
- Lua Reference on RUNOOB.com
- Lua Demo
- LuatOS Emulator