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 and nil 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

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

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}

References