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:
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:
1and break do else elseif
2end false for function if
3in local nil not or
4repeat return then true until
5while
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
1< > <= >= == ~=
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.
1print(4 and 5) --> 5
2print(nil and 13) --> nil
3print(false and 13) --> false
4print(4 or 5) --> 4
5print(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.
1print("Hello " .. "World") --> Hello World
2print(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:
1or
2and
3< > <= >= ~= ==
4|
5~
6&
7<< >>
8..
9+ -
10* / // %
11unary operators (not # - ~)
12^
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:
1--[[
2print(10) -- no action (comment)
3--]]
Now, if we add a single hyphen to the first line, the code is in again:
1---[[
2print(10) --> 10
3--]]
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:
1for n in pairs(_G) do
2 print(n)
3end
Take lua5.3 for instance:
1chenwx@chenwx:~ $ lua5.3
2Lua 5.3.3 Copyright (C) 1994-2016 Lua.org, PUC-Rio
3> for n in pairs(_G) do print(n) end
4next
5tostring
6rawget
7rawset
8dofile
9print
10rawlen
11xpcall
12_G
13utf8
14pairs
15error
16table
17load
18rawequal
19setmetatable
20pcall
21collectgarbage
22tonumber
23bit32
24package
25select
26assert
27io
28type
29loadfile
30arg
31debug
32require
33math
34getmetatable
35os
36string
37ipairs
38coroutine
39_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
1if op == "+" then
2 r = a + b
3elseif op == "-" then
4 r = a - b
5elseif op == "*" then
6 r = a*b
7elseif op == "/" then
8 r = a/b
9else
10 error("invalid operation")
11end
while-do-end
1local i = 1
2
3while a[i] do
4 print(a[i])
5 i = i + 1
6end
repeat-until
The test is done after the body, so the body is always executed at least once.
1-- print the first non-empty line
2repeat
3 line = os.read()
4until line ~= ""
5
6print(line)
for
The for
statement has two variants: the numeric for and the generic for.
Numeric for
A numeric for has the following syntax:
1for var=exp1,exp2,exp3 do
2 something
3end
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
1for i=1,f(x) do
2 print(i)
3end
4
5for i=10,1,-1 do
6 print(i)
7end
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:
1for i=1,10 do
2 print(i)
3end
4
5max = 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:
1-- print all values of array 'a'
2for i,v in ipairs(a) do
3 print(v)
4end
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:
1print "Hello World" <--> print("Hello World")
2dofile 'a.lua' <--> dofile ('a.lua')
3print [[a multi-line <--> print([[a multi-line
4message]] message]])
5f{x=10, y=20} <--> f({x=10, y=20})
6type{} <--> 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).
1-- add all elements of array `a'
2function add (a)
3 local sum = 0
4 for i,v in ipairs(a) do
5 sum = sum + v
6 end
7 return sum
8end
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:
1function f(a, b)
2 return a or b
3end
we will have the following mapping from arguments to parameters:
1CALL PARAMETERS
2
3f(3) a=3, b=nil
4f(3, 4) a=3, b=4
5f(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.
1function incCount (n)
2 n = n or 1
3 count = count + n
4end
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.
1function print (...)
2 print(arg[n] .. " elements in input parameter arg:")
3 for i,v in ipairs(arg) do
4 print(tostring(i) .. tostring(v) .. "\n")
5 end
6end
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:
1local _, x = string.find(s, p)
2-- now use `x'
3...
An alternative solution is to define a select
function, which selects a specific return from a function:
1print(string.find("hello hello", " hel")) --> 6 9
2print(select(1, string.find("hello hello", " hel"))) --> 6
3print(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:
1function 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:
1foo = 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:
1chenwx@chenwx:~ $ sudo apt install lua
2[sudo] password for chenwx:
3Reading package lists... Done
4Building dependency tree
5Reading state information... Done
6Package lua is a virtual package provided by:
7 lua50 5.0.3-8
8 lua5.3 5.3.3-1
9 lua5.2 5.2.4-1.1build1
10 lua5.1 5.1.5-8.1build2
11You should explicitly select one to install.
12
13E: Package 'lua' has no installation candidate
14
15chenwx@chenwx:~ $ sudo apt install lua5.3
16Reading package lists... Done
17Building dependency tree
18Reading state information... Done
19lua5.3 is already the newest version (5.3.3-1).
200 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
21
22chenwx@chenwx:~ $ which lua5.3
23/usr/bin/lua5.3
24
25chenwx@chenwx:~ $ lua5.3 -v
26Lua 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:
1chenwx@chenwx:~ $ mkdir lua
2chenwx@chenwx:~ $ cd lua
3
4chenwx@chenwx:~/lua $ curl -R -O http://www.lua.org/ftp/lua-5.3.1.tar.gz
5 % Total % Received % Xferd Average Speed Time Time Time Current
6 Dload Upload Total Spent Left Speed
7100 275k 100 275k 0 0 36275 0 0:00:07 0:00:07 --:--:-- 66151
8
9chenwx@chenwx:~/lua $ tar zxf lua-5.3.1.tar.gz
10chenwx@chenwx:~/lua $ cd lua-5.3.1
11
12chenwx@chenwx:~/lua/lua-5.3.1 $ make linux test
13cd src && make linux
14make[1]: Entering directory '/home/chenwx/lua/lua-5.3.1/src'
15make all SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
16make[2]: Entering directory '/home/chenwx/lua/lua-5.3.1/src'
17gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lapi.o lapi.c
18gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lcode.o lcode.c
19gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lctype.o lctype.c
20gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldebug.o ldebug.c
21gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldo.o ldo.c
22gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldump.o ldump.c
23gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lfunc.o lfunc.c
24gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lgc.o lgc.c
25gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o llex.o llex.c
26gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lmem.o lmem.c
27gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lobject.o lobject.c
28gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lopcodes.o lopcodes.c
29gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lparser.o lparser.c
30gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lstate.o lstate.c
31gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lstring.o lstring.c
32gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ltable.o ltable.c
33gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ltm.o ltm.c
34gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lundump.o lundump.c
35gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lvm.o lvm.c
36gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lzio.o lzio.c
37gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lauxlib.o lauxlib.c
38gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lbaselib.o lbaselib.c
39gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lbitlib.o lbitlib.c
40gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lcorolib.o lcorolib.c
41gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldblib.o ldblib.c
42gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o liolib.o liolib.c
43gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lmathlib.o lmathlib.c
44gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o loslib.o loslib.c
45gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lstrlib.o lstrlib.c
46gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ltablib.o ltablib.c
47gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lutf8lib.o lutf8lib.c
48gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o loadlib.o loadlib.c
49gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o linit.o linit.c
50ar 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
51ar: `u' modifier ignored since `D' is the default (see `U')
52ranlib liblua.a
53gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lua.o lua.c
54gcc -std=gnu99 -o lua lua.o liblua.a -lm -Wl,-E -ldl -lreadline
55gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o luac.o luac.c
56gcc -std=gnu99 -o luac luac.o liblua.a -lm -Wl,-E -ldl -lreadline
57make[2]: Leaving directory '/home/chenwx/lua/lua-5.3.1/src'
58make[1]: Leaving directory '/home/chenwx/lua/lua-5.3.1/src'
59src/lua -v
60Lua 5.3.1 Copyright (C) 1994-2015 Lua.org, PUC-Rio
61
62chenwx@chenwx:~/lua/lua-5.3.1 $ ll src/lua src/luac
63-rwxr-xr-x 1 chenwx chenwx 254K Jan 8 22:23 src/lua
64-rwxr-xr-x 1 chenwx chenwx 167K Jan 8 22:23 src/luac
65
66chenwx@chenwx:~/lua/lua-5.3.1 $ ./src/lua -v
67Lua 5.3.1 Copyright (C) 1994-2015 Lua.org, PUC-Rio
68
69chenwx@chenwx:~/lua/lua-5.3.1 $ ./src/luac -v
70Lua 5.3.1 Copyright (C) 1994-2015 Lua.org, PUC-Rio
Usage of Lua Interpreter
man page of Lua interpreter:
1chenwx@chenwx:~ $ which lua5.3
2/usr/bin/lua5.3
3
4chenwx@chenwx:~ $ man lua
1LUA5.3(1) General Commands Manual LUA5.3(1)
2
3NAME
4 lua - Lua interpreter
5
6SYNOPSIS
7 lua [ options ] [ script [ args ] ]
8
9DESCRIPTION
10 lua is the standalone Lua interpreter. It loads and executes Lua
11 programs, either in textual source form or in precompiled binary
12 form. (Precompiled binaries are output by luac, the Lua compiler.)
13 lua can be used as a batch interpreter and also interactively.
14
15 The given options are handled in order and then the Lua program in
16 file script is loaded and executed. The given args are available to
17 script as strings in a global table named arg. If no options or
18 arguments are given, then -v -i is assumed when the standard input is
19 a terminal; otherwise, - is assumed.
20
21 In interactive mode, lua prompts the user, reads lines from the stan-
22 dard input, and executes them as they are read. If the line contains
23 an expression or list of expressions, then the line is evaluated and
24 the results are printed. If a line does not contain a complete
25 statement, then a secondary prompt is displayed and lines are read
26 until a complete statement is formed or a syntax error is found.
27
28 At the very start, before even handling the command line, lua checks
29 the contents of the environment variables LUA_INIT_5_3 or LUA_INIT,
30 in that order. If the contents is of the form '@filename', then
31 filename is executed. Otherwise, the string is assumed to be a Lua
32 statement and is executed.
33
34OPTIONS
35 -e stat
36 execute statement stat.
37
38 -i enter interactive mode after executing script.
39
40 -l name
41 execute the equivalent of name=require('name') before execut-
42 ing script.
43
44 -v show version information.
45
46 -E ignore environment variables.
47
48 -- stop handling options.
49
50 - stop handling options and execute the standard input as a
51 file.
52
53SEE ALSO
54 luac(1)
55 The documentation at lua.org, especially section 7 of the reference
56 manual.
57
58DIAGNOSTICS
59 Error messages should be self explanatory.
60
61AUTHORS
62 R. Ierusalimschy, L. H. de Figueiredo, W. Celes
63
64 $Date: 2014/12/10 15:55:45 $ LUA5.3(1)
Usage of Lua Compiler
man page of Lua compiler:
1chenwx@chenwx:~ $ which luac5.3
2/usr/bin/luac5.3
3
4chenwx@chenwx:~ $ man lua
1 LUAC5.3(1) General Commands Manual LUAC5.3(1)
2
3NAME
4 luac - Lua compiler
5
6SYNOPSIS
7 luac [ options ] [ filenames ]
8
9DESCRIPTION
10 luac is the Lua compiler. It translates programs written in the Lua
11 programming language into binary files containing precompiled chunks
12 that can be later loaded and executed.
13
14 The main advantages of precompiling chunks are: faster loading, pro-
15 tecting source code from accidental user changes, and off-line syntax
16 checking. Precompiling does not imply faster execution because in
17 Lua chunks are always compiled into bytecodes before being executed.
18 luac simply allows those bytecodes to be saved in a file for later
19 execution. Precompiled chunks are not necessarily smaller than the
20 corresponding source. The main goal in precompiling is faster load-
21 ing.
22
23 In the command line, you can mix text files containing Lua source and
24 binary files containing precompiled chunks. luac produces a single
25 output file containing the combined bytecodes for all files given.
26 Executing the combined file is equivalent to executing the given
27 files. By default, the output file is named luac.out, but you can
28 change this with the -o option.
29
30 Precompiled chunks are not portable across different architectures.
31 Moreover, the internal format of precompiled chunks is likely to
32 change when a new version of Lua is released. Make sure you save the
33 source files of all Lua programs that you precompile.
34
35OPTIONS
36 -l produce a listing of the compiled bytecode for Lua's virtual
37 machine. Listing bytecodes is useful to learn about Lua's
38 virtual machine. If no files are given, then luac loads
39 luac.out and lists its contents. Use -l -l for a full list-
40 ing.
41
42 -o file
43 output to file, instead of the default luac.out. (You can use
44 '-' for standard output, but not on platforms that open stan-
45 dard output in text mode.) The output file may be one of the
46 given files because all files are loaded before the output
47 file is written. Be careful not to overwrite precious files.
48
49 -p load files but do not generate any output file. Used mainly
50 for syntax checking and for testing precompiled chunks: cor-
51 rupted files will probably generate errors when loaded. If no
52 files are given, then luac loads luac.out and tests its con-
53 tents. No messages are displayed if the file loads without
54 errors.
55
56 -s strip debug information before writing the output file. This
57 saves some space in very large chunks, but if errors occur
58 when running a stripped chunk, then the error messages may not
59 contain the full information they usually do. In particular,
60 line numbers and names of local variables are lost.
61
62 -v show version information.
63
64 -- stop handling options.
65
66 - stop handling options and process standard input.
67
68SEE ALSO
69 lua(1)
70 The documentation at lua.org.
71
72DIAGNOSTICS
73 Error messages should be self explanatory.
74
75AUTHORS
76 R. Ierusalimschy, L. H. de Figueiredo, W. Celes
77
78 $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.
1chenwx@chenwx:~/lua $ cat hello.lua
2function max(num1, num2)
3
4 if (num1 > num2) then
5 result = num1;
6 else
7 result = num2;
8 end
9
10 return result;
11end
12
13print("max value is ", max(10,4))
14print("max value is ", max(5,6))
15
16chenwx@chenwx:~/lua $ luac5.3 hello.lua
17chenwx@chenwx:~/lua $ ll
18-rw-r--r-- 1 chenwx chenwx 201 Jan 8 23:10 hello.lua
19drwxr-xr-x 4 chenwx chenwx 4.0K Jun 10 2015 lua-5.3.1
20-rw-r--r-- 1 chenwx chenwx 435 Jan 8 23:10 luac.out
21drwxr-xr-x 18 chenwx chenwx 4.0K Jan 8 23:06 luadec
22
23chenwx@chenwx:~/lua $ hexdump -C luac.out
2400000000 1b 4c 75 61 53 00 19 93 0d 0a 1a 0a 04 08 04 08 |.LuaS...........|
2500000010 08 78 56 00 00 00 00 00 00 00 00 00 00 00 28 77 |.xV...........(w|
2600000020 40 01 0b 40 68 65 6c 6c 6f 2e 6c 75 61 00 00 00 |@..@hello.lua...|
2700000030 00 00 00 00 00 00 01 05 11 00 00 00 2c 00 00 00 |............,...|
2800000040 08 00 00 80 06 40 40 00 41 80 00 00 86 00 40 00 |.....@@.A.....@.|
2900000050 c1 c0 00 00 01 01 01 00 a4 00 80 01 24 40 00 00 |............$@..|
3000000060 06 40 40 00 41 80 00 00 86 00 40 00 c1 40 01 00 |.@@.A.....@..@..|
3100000070 01 81 01 00 a4 00 80 01 24 40 00 00 26 00 80 00 |........$@..&...|
3200000080 07 00 00 00 04 04 6d 61 78 04 06 70 72 69 6e 74 |......max..print|
3300000090 04 0e 6d 61 78 20 76 61 6c 75 65 20 69 73 20 13 |..max value is .|
34000000a0 0a 00 00 00 00 00 00 00 13 04 00 00 00 00 00 00 |................|
35000000b0 00 13 05 00 00 00 00 00 00 00 13 06 00 00 00 00 |................|
36000000c0 00 00 00 01 00 00 00 01 00 01 00 00 00 00 01 00 |................|
37000000d0 00 00 0a 00 00 00 02 00 03 08 00 00 00 20 00 80 |............. ..|
38000000e0 00 1e 40 00 80 08 00 00 80 1e 00 00 80 08 40 00 |..@...........@.|
39000000f0 80 86 00 40 00 a6 00 00 01 26 00 80 00 01 00 00 |...@.....&......|
4000000100 00 04 07 72 65 73 75 6c 74 01 00 00 00 00 00 00 |...result.......|
4100000110 00 00 00 08 00 00 00 03 00 00 00 03 00 00 00 04 |................|
4200000120 00 00 00 04 00 00 00 06 00 00 00 09 00 00 00 09 |................|
4300000130 00 00 00 0a 00 00 00 02 00 00 00 05 6e 75 6d 31 |............num1|
4400000140 00 00 00 00 08 00 00 00 05 6e 75 6d 32 00 00 00 |.........num2...|
4500000150 00 08 00 00 00 01 00 00 00 05 5f 45 4e 56 11 00 |.........._ENV..|
4600000160 00 00 0a 00 00 00 01 00 00 00 0c 00 00 00 0c 00 |................|
4700000170 00 00 0c 00 00 00 0c 00 00 00 0c 00 00 00 0c 00 |................|
4800000180 00 00 0c 00 00 00 0d 00 00 00 0d 00 00 00 0d 00 |................|
4900000190 00 00 0d 00 00 00 0d 00 00 00 0d 00 00 00 0d 00 |................|
50000001a0 00 00 0d 00 00 00 00 00 00 00 01 00 00 00 05 5f |..............._|
51000001b0 45 4e 56 |ENV|
52000001b3
53
54chenwx@chenwx:~/lua $ lua5.3 luac.out
55max value is 10
56max value is 6
Encode/Decode Lua Bytecode via Base64
The Lua bytecode can be encoded or decoded by tool base64:
1chenwx@chenwx:~/lua $ base64 --help
2Usage: base64 [OPTION]... [FILE]
3Base64 encode or decode FILE, or standard input, to standard output.
4
5With no FILE, or when FILE is -, read standard input.
6
7Mandatory arguments to long options are mandatory for short options too.
8 -d, --decode decode data
9 -i, --ignore-garbage when decoding, ignore non-alphabet characters
10 -w, --wrap=COLS wrap encoded lines after COLS character (default 76).
11 Use 0 to disable line wrapping
12
13 --help display this help and exit
14 --version output version information and exit
15
16The data are encoded as described for the base64 alphabet in RFC 4648.
17When decoding, the input may contain newlines in addition to the bytes of
18the formal base64 alphabet. Use --ignore-garbage to attempt to recover
19from any other non-alphabet bytes in the encoded stream.
20
21GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
22Report base64 translation bugs to <http://translationproject.org/team/>
23Full documentation at: <http://www.gnu.org/software/coreutils/base64>
24or available locally via: info '(coreutils) base64 invocation'
25
26chenwx@chenwx:~/lua $ base64 luac.out > luac.out.encode
27
28chenwx@chenwx:~/lua $ cat luac.out.encode
29G0x1YVMAGZMNChoKBAgECAh4VgAAAAAAAAAAAAAAKHdAAQtAaGVsbG8ubHVhAAAAAAAAAAAAAQUR
30AAAALAAAAAgAAIAGQEAAQYAAAIYAQADBwAAAAQEBAKQAgAEkQAAABkBAAEGAAACGAEAAwUABAAGB
31AQCkAIABJEAAACYAgAAHAAAABARtYXgEBnByaW50BA5tYXggdmFsdWUgaXMgEwoAAAAAAAAAEwQA
32AAAAAAAAEwUAAAAAAAAAEwYAAAAAAAAAAQAAAAEAAQAAAAABAAAACgAAAAIAAwgAAAAgAIAAHkAA
33gAgAAIAeAACACEAAgIYAQACmAAABJgCAAAEAAAAEB3Jlc3VsdAEAAAAAAAAAAAAIAAAAAwAAAAMA
34AAAEAAAABAAAAAYAAAAJAAAACQAAAAoAAAACAAAABW51bTEAAAAACAAAAAVudW0yAAAAAAgAAAAB
35AAAABV9FTlYRAAAACgAAAAEAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADQAAAA0AAAAN
36AAAADQAAAA0AAAANAAAADQAAAA0AAAAAAAAAAQAAAAVfRU5W
37
38chenwx@chenwx:~/lua $ base64 -d luac.out.encode > luac.out.decode
39
40chenwx@chenwx:~/lua $ hexdump -C luac.out.decode
4100000000 1b 4c 75 61 53 00 19 93 0d 0a 1a 0a 04 08 04 08 |.LuaS...........|
4200000010 08 78 56 00 00 00 00 00 00 00 00 00 00 00 28 77 |.xV...........(w|
4300000020 40 01 0b 40 68 65 6c 6c 6f 2e 6c 75 61 00 00 00 |@..@hello.lua...|
4400000030 00 00 00 00 00 00 01 05 11 00 00 00 2c 00 00 00 |............,...|
4500000040 08 00 00 80 06 40 40 00 41 80 00 00 86 00 40 00 |.....@@.A.....@.|
4600000050 c1 c0 00 00 01 01 01 00 a4 00 80 01 24 40 00 00 |............$@..|
4700000060 06 40 40 00 41 80 00 00 86 00 40 00 c1 40 01 00 |.@@.A.....@..@..|
4800000070 01 81 01 00 a4 00 80 01 24 40 00 00 26 00 80 00 |........$@..&...|
4900000080 07 00 00 00 04 04 6d 61 78 04 06 70 72 69 6e 74 |......max..print|
5000000090 04 0e 6d 61 78 20 76 61 6c 75 65 20 69 73 20 13 |..max value is .|
51000000a0 0a 00 00 00 00 00 00 00 13 04 00 00 00 00 00 00 |................|
52000000b0 00 13 05 00 00 00 00 00 00 00 13 06 00 00 00 00 |................|
53000000c0 00 00 00 01 00 00 00 01 00 01 00 00 00 00 01 00 |................|
54000000d0 00 00 0a 00 00 00 02 00 03 08 00 00 00 20 00 80 |............. ..|
55000000e0 00 1e 40 00 80 08 00 00 80 1e 00 00 80 08 40 00 |..@...........@.|
56000000f0 80 86 00 40 00 a6 00 00 01 26 00 80 00 01 00 00 |...@.....&......|
5700000100 00 04 07 72 65 73 75 6c 74 01 00 00 00 00 00 00 |...result.......|
5800000110 00 00 00 08 00 00 00 03 00 00 00 03 00 00 00 04 |................|
5900000120 00 00 00 04 00 00 00 06 00 00 00 09 00 00 00 09 |................|
6000000130 00 00 00 0a 00 00 00 02 00 00 00 05 6e 75 6d 31 |............num1|
6100000140 00 00 00 00 08 00 00 00 05 6e 75 6d 32 00 00 00 |.........num2...|
6200000150 00 08 00 00 00 01 00 00 00 05 5f 45 4e 56 11 00 |.........._ENV..|
6300000160 00 00 0a 00 00 00 01 00 00 00 0c 00 00 00 0c 00 |................|
6400000170 00 00 0c 00 00 00 0c 00 00 00 0c 00 00 00 0c 00 |................|
6500000180 00 00 0c 00 00 00 0d 00 00 00 0d 00 00 00 0d 00 |................|
6600000190 00 00 0d 00 00 00 0d 00 00 00 0d 00 00 00 0d 00 |................|
67000001a0 00 00 0d 00 00 00 00 00 00 00 01 00 00 00 05 5f |..............._|
68000001b0 45 4e 56 |ENV|
69000001b3
70chenwx@chenwx:~/lua $ diff luac.out luac.out.decode
71chenwx@chenwx:~/lua $
72
73chenwx@chenwx:~/lua $ ./lua-5.3.1/src/lua luac.out.decode
74max value is 10
75max 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:
1chenwx@chenwx:~/lua $ git clone https://github.com/viruscamp/luadec
2Cloning into 'luadec'...
3remote: Enumerating objects: 2117, done.
4remote: Total 2117 (delta 0), reused 0 (delta 0), pack-reused 2117
5Receiving objects: 100% (2117/2117), 2.65 MiB | 56.00 KiB/s, done.
6Resolving deltas: 100% (1308/1308), done.
7
8chenwx@chenwx:~/lua $ cd luadec/
9chenwx@chenwx:~/lua/luadec $ git submodule update --init lua-5.3
10Submodule 'lua-5.3' (https://github.com/viruscamp/lua5) registered for path 'lua-5.3'
11Cloning into '/home/chenwx/lua/luadec/lua-5.3'...
12Submodule path 'lua-5.3': checked out 'f9785d609d20af8d28b05a05a757dad5ed770852'
13
14chenwx@chenwx:~/lua/luadec $ cd lua-5.3
15chenwx@chenwx:~/lua/luadec/lua-5.3 $ git lhg -10
16* f9785d609d20 2016-09-22 VirusCamp (HEAD, tag: 5.3.3) lua-5.3.3 2016-05-30
17* 36ebdad2ed40 2016-09-22 VirusCamp (tag: 5.3.2) lua-5.3.2 2015-11-25
18* 8071eaea5ad7 2016-09-22 VirusCamp (tag: 5.3.1) lua-5.3.1 2015-06-10
19* 23c9a0ef6222 2015-03-28 VirusCamp (tag: 5.3.0) lua-5.3.0 2015-01-06
20* 06b0e58ae7f2 2014-11-12 VirusCamp lua-5.3.0-beta 2014-10-23
21* 267b4bd00ed6 2014-11-12 VirusCamp lua-5.3.0-alpha 2014-07-31
22* 680bf808e382 2014-11-12 VirusCamp lua-5.3.0-work3 2014-06-19
23* 47cf35766408 2014-11-12 VirusCamp lua-5.3.0-work2 2014-03-21
24* 184a12c4a46d 2014-11-12 VirusCamp lua-5.3.0-work1 2013-07-06
25* 5a39d6da6297 2014-10-18 viruscamp (tag: 5.2.3) lua-5.2.3 2013-11-11
26
27chenwx@chenwx:~/lua/luadec/lua-5.3 $ git co 5.3.1
28Previous HEAD position was f9785d609d20 lua-5.3.3 2016-05-30
29HEAD is now at 8071eaea5ad7 lua-5.3.1 2015-06-10
30
31chenwx@chenwx:~/lua/luadec/lua-5.3 $ cd ../
32chenwx@chenwx:~/lua/luadec $ git submodule status
33-e496bc6df2e49ea0beebb26f216aca3821a2b28e LuaAssemblyTools
34-c9ef6799113e71d89d629b29b266d1eba4105038 ilua
35-cdcfa70f2f731409046374e797a62314b4924b77 lua-5.1
36-0137406b0635f22f5c9b894e0da1d15abdb036bc lua-5.2
37+8071eaea5ad72343d6873ade47d947c42d76bae9 lua-5.3 (5.3.1)
38-79c86d1b258b13dc0d1a2a66f28aadc0f6e23944 memwatch
39
40chenwx@chenwx:~/lua/luadec $ cd lua-5.3/
41chenwx@chenwx:~/lua/luadec/lua-5.3 $ make linux
42cd src && make linux
43make[1]: Entering directory '/home/chenwx/lua/luadec/lua-5.3/src'
44make all SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
45make[2]: Entering directory '/home/chenwx/lua/luadec/lua-5.3/src'
46gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lapi.o lapi.c
47gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lcode.o lcode.c
48gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lctype.o lctype.c
49gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldebug.o ldebug.c
50gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldo.o ldo.c
51gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldump.o ldump.c
52gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lfunc.o lfunc.c
53gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lgc.o lgc.c
54gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o llex.o llex.c
55gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lmem.o lmem.c
56gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lobject.o lobject.c
57gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lopcodes.o lopcodes.c
58gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lparser.o lparser.c
59gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lstate.o lstate.c
60gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lstring.o lstring.c
61gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ltable.o ltable.c
62gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ltm.o ltm.c
63gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lundump.o lundump.c
64gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lvm.o lvm.c
65gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lzio.o lzio.c
66gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lauxlib.o lauxlib.c
67gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lbaselib.o lbaselib.c
68gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lbitlib.o lbitlib.c
69gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lcorolib.o lcorolib.c
70gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ldblib.o ldblib.c
71gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o liolib.o liolib.c
72gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lmathlib.o lmathlib.c
73gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o loslib.o loslib.c
74gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lstrlib.o lstrlib.c
75gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o ltablib.o ltablib.c
76gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lutf8lib.o lutf8lib.c
77gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o loadlib.o loadlib.c
78gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o linit.o linit.c
79ar 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
80ar: `u' modifier ignored since `D' is the default (see `U')
81ranlib liblua.a
82gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o lua.o lua.c
83gcc -std=gnu99 -o lua lua.o liblua.a -lm -Wl,-E -ldl -lreadline
84gcc -std=gnu99 -O2 -Wall -Wextra -DLUA_COMPAT_5_2 -DLUA_USE_LINUX -c -o luac.o luac.c
85gcc -std=gnu99 -o luac luac.o liblua.a -lm -Wl,-E -ldl -lreadline
86make[2]: Leaving directory '/home/chenwx/lua/luadec/lua-5.3/src'
87make[1]: Leaving directory '/home/chenwx/lua/luadec/lua-5.3/src'
88
89chenwx@chenwx:~/lua/luadec/lua-5.3 $ cd ../luadec
90chenwx@chenwx:~/lua/luadec/luadec $ make LUAVER=5.3
91gcc -O2 -Wall -DSRCVERSION=\"895d92313fab\" -I../lua-5.3/src -c -o guess.o guess.c
92...
93gcc -o luaopswap luaopswap.o ../lua-5.3/src/liblua.a -lm
94
95chenwx@chenwx:~/lua/luadec/luadec $ cd ../..
96chenwx@chenwx:~/lua $ ll
97-rw-r--r-- 1 chenwx chenwx 201 Jan 8 23:10 hello.lua
98drwxr-xr-x 4 chenwx chenwx 4.0K Jun 10 2015 lua-5.3.1
99-rw-r--r-- 1 chenwx chenwx 435 Jan 8 23:10 luac.out
100-rw-r--r-- 1 chenwx chenwx 435 Jan 9 21:19 luac.out.decode
101-rw-r--r-- 1 chenwx chenwx 588 Jan 9 21:19 luac.out.encode
102drwxr-xr-x 18 chenwx chenwx 4.0K Jan 8 23:06 luadec
103
104chenwx@chenwx:~/lua $ ./luadec/luadec/luadec luac.out
105-- Decompiled using luadec 2.2 rev: 895d92313fab for Lua 5.3 from https://github.com/viruscamp/luadec
106-- Command line: luac.out
107
108-- params : ...
109-- function num : 0 , upvalues : _ENV
110max = function(num1, num2)
111 -- function num : 0_0 , upvalues : _ENV
112 if num2 < num1 then
113 result = num1
114 else
115 result = num2
116 end
117 return result
118end
119
120print("max value is ", max(10, 4))
121print("max value is ", max(5, 6))
122
123chenwx@chenwx:~/lua $ ./luadec/luadec/luadec luac.out.decode
124-- Decompiled using luadec 2.2 rev: 895d92313fab for Lua 5.3 from https://github.com/viruscamp/luadec
125-- Command line: luac.out.decode
126
127-- params : ...
128-- function num : 0 , upvalues : _ENV
129max = function(num1, num2)
130 -- function num : 0_0 , upvalues : _ENV
131 if num2 < num1 then
132 result = num1
133 else
134 result = num2
135 end
136 return result
137end
138
139print("max value is ", max(10, 4))
140print("max value is ", max(5, 6))
Projects
LuatOS
Examples
Example 1: Print global variables
1local g_str_key = "key : "
2local g_str_type = "type : "
3local g_str_len = "length : "
4local g_str_value = "value : "
5local g_str_prefix = " "
6local g_max_layer = 10
7
8
9function print_table(table, num_of_layer)
10
11 local type_of_table = type(table)
12
13 if type_of_table ~= "table" then
14 return
15 end
16
17 local str_prefix = string.rep(g_str_prefix, num_of_layer)
18
19 -- loop all elements in this table
20
21 for key, value in pairs(table) do
22
23 str_tmp = string.format("\n%s%s%s", str_prefix, g_str_key, key)
24 print(str_tmp)
25
26 local type_of_value = type(value)
27 str_tmp = string.format("%s%s%s", str_prefix, g_str_type, type_of_value)
28 print(str_tmp)
29
30 if type_of_value == "string" then
31
32 str_tmp = string.format("%s%s%s", str_prefix, g_str_value, value)
33 print(str_tmp)
34
35 elseif (type_of_value == "table") and -- loop next table
36 (key ~= "_G") and -- exclude table _G
37 (num_of_layer <= g_max_layer) then -- limit number of layers
38
39 local len_of_table = 0
40 for _, _ in pairs(value) do
41 len_of_table = len_of_table + 1
42 end
43
44 str_tmp = string.format("%s%s%s", str_prefix, g_str_len, len_of_table)
45 print(str_tmp)
46
47 print_table(value, num_of_layer + 1)
48
49 end
50
51 end
52
53end
54
55
56-- print table _G
57
58function print_G()
59
60 local num_of_layer = 0
61 local str_prefix = string.rep(g_str_prefix, num_of_layer)
62
63 local str_tmp = string.format("%s%s%s", str_prefix, g_str_key, "_G")
64 print(str_tmp)
65
66 local type_of_value = type(_G)
67 str_tmp = string.format("%s%s%s", str_prefix, g_str_type, type_of_value)
68 print(str_tmp)
69
70 local len_of_table = 0
71
72 for _, _ in pairs(_G) do
73 len_of_table = len_of_table + 1
74 end
75
76 str_tmp = string.format("%s%s%s", str_prefix, g_str_len, len_of_table)
77 print(str_tmp)
78
79 print_table(_G, 0)
80
81end
82
83
84-- main entry
85
86print_G()
Example 2: Print boolean variables
1function print_boolean(arg)
2 print(arg and "true" or "false")
3end
4
5print_boolean(true)
6print_boolean(false)
Example 3: Get length of table
Lua code:
1function get_len(t)
2 local len = 0
3 for k, v in pairs(t) do
4 len = len + 1
5 end
6 return len
7end
8
9function print_table(t)
10 print("{")
11 for k, v in pairs(t) do
12 print(" [" .. k .. "] = " .. v .. ",")
13 end
14 print("}")
15end
16
17t = { [1] = 11, [2] = 22, [4] = 44 }
18
19print("get_len(t) = " .. get_len(t))
20print("#t = " .. #t)
21-- print("table.concat(t) = " .. table.concat(t))
22print_table(t)
23
24t = { 11, 22, 44 }
25
26print("get_len(t) = " .. get_len(t))
27print("#t = " .. #t)
28print("table.concat(t, ', ') = " .. table.concat(t, ', '))
29print_table(t)
Output:
1get_len(t) = 3
2#t = 4
3{
4 [1] = 11,
5 [2] = 22,
6 [4] = 44,
7}
8get_len(t) = 3
9#t = 3
10table.concat(t, ', ') = 11, 22, 44
11{
12 [1] = 11,
13 [2] = 22,
14 [3] = 44,
15}