2.4 – Statements
Lua supports an almost conventional set of statements, similar to those in Pascal or C. This set includes assignment, control structures, procedure calls, table constructors, and variable declarations.
2.4.1 – Chunks
The unit of execution of Lua is called a chunk. A chunk is simply a sequence of statements, which are executed sequentially. Each statement can be optionally followed by a semicolon:
- chunk ::= {stat [`;´]}
Lua handles a chunk as the body of an anonymous function (see 2.5.8). As such, chunks can define local variables and return values.
A chunk may be stored in a file or in a string inside the host program. When a chunk is executed, first it is pre-compiled into opcodes for a virtual machine, and then the compiled code is executed by an interpreter for the virtual machine.
Chunks may also be pre-compiled into binary form; see program luac
for details. Programs in source and compiled forms are interchangeable; Lua automatically detects the file type and acts accordingly.
2.4.2 – Blocks
A block is a list of statements; syntactically, a block is equal to a chunk:
- block ::= chunk
A block may be explicitly delimited to produce a single statement:
- stat ::= do block end
Explicit blocks are useful to control the scope of variable declarations. Explicit blocks are also sometimes used to add a return or break statement in the middle of another block (see 2.4.4).
2.4.3 – Assignment
Lua allows multiple assignment. Therefore, the syntax for assignment defines a list of variables on the left side and a list of expressions on the right side. The elements in both lists are separated by commas:
- stat ::= varlist1 `=´ explist1
- varlist1 ::= var {`,´ var}
- explist1 ::= exp {`,´ exp}
Expressions are discussed in 2.5.
Before the assignment, the list of values is adjusted to the length of the list of variables. If there are more values than needed, the excess values are thrown away. If there are fewer values than needed, the list is extended with as many nil‘s as needed. If the list of expressions ends with a function call, then all values returned by that function call enter in the list of values, before the adjustment (except when the call is enclosed in parentheses; see 2.5).
The assignment statement first evaluates all its expressions and only then are the assignments performed. Thus the code
- i = 3
- i, a[i] = i+1, 20
sets a[3]
to 20, without affecting a[4]
because the i
in a[i]
is evaluated (to 3) before it is assigned 4. Similarly, the line
- x, y = y, x
exchanges the values of x
and y
.
The meaning of assignments to global variables and table fields can be changed via metatables. An assignment to an indexed variable t[i] = val
is equivalent to settable_event(t,i,val)
. (See 2.8 for a complete description of the settable_event
function. This function is not defined or callable in Lua. We use it here only for explanatory purposes.)
An assignment to a global variable x = val
is equivalent to the assignment _env.x = val
, which in turn is equivalent to
- settable_event(_env, "x", val)
where _env
is the environment of the running function. (The _env
variable is not defined in Lua. We use it here only for explanatory purposes.)
2.4.4 – Control Structures
The control structures if, while, and repeat have the usual meaning and familiar syntax:
- stat ::= while exp do block end
- stat ::= repeat block until exp
- stat ::= if exp then block {elseif exp then block} [else block] end
Lua also has a for statement, in two flavors (see 2.4.5).
The condition expression exp of a control structure may return any value. Both false and nil are considered false. All values different from nil and false are considered true (in particular, the number 0 and the empty string are also true).
The return statement is used to return values from a function or from a chunk. Functions and chunks may return more than one value, so the syntax for the return statement is
- stat ::= return [explist1]
The break statement can be used to terminate the execution of a while, repeat, or for loop, skipping to the next statement after the loop:
- stat ::= break
A break ends the innermost enclosing loop.
For syntactic reasons, return and break statements can only be written as the last statement of a block. If it is really necessary to return or break in the middle of a block, then an explicit inner block can be used, as in the idioms `do return end
´ and `do break end
´, because now return and break are the last statements in their (inner) blocks. In practice, those idioms are only used during debugging.
2.4.5 – For Statement
The for statement has two forms: one numeric and one generic.
The numeric for loop repeats a block of code while a control variable runs through an arithmetic progression. It has the following syntax:
- stat ::= for Name `=´ exp `,´ exp [`,´ exp] do block end
The block is repeated for name starting at the value of the first exp, until it passes the second exp by steps of the third exp. More precisely, a for statement like
- for var = e1, e2, e3 do block end
is equivalent to the code:
- do
- local var, _limit, _step = tonumber(e1), tonumber(e2), tonumber(e3)
- if not (var and _limit and _step) then error() end
- while (_step>0 and var<=_limit) or (_step<=0 and var>=_limit) do
- block
- var = var + _step
- end
- end
Note the following:
- All three control expressions are evaluated only once, before the loop starts. They must all result in numbers.
_limit
and_step
are invisible variables. The names are here for explanatory purposes only.- The behavior is undefined if you assign to
var
inside the block. - If the third expression (the step) is absent, then a step of 1 is used.
- You can use break to exit a for loop.
- The loop variable
var
is local to the statement; you cannot use its value after the for ends or is broken. If you need the value of the loop variablevar
, then assign it to another variable before breaking or exiting the loop.
The generic for statement works over functions, called iterators. For each iteration, it calls its iterator function to produce a new value, stopping when the new value is nil. The generic for loop has the following syntax:
- stat ::= for Name {`,´ Name} in explist1 do block end
A for statement like
- for var_1, ..., var_n in explist do block end
is equivalent to the code:
- do
- local _f, _s, var_1 = explist
- local var_2, ... , var_n
- while true do
- var_1, ..., var_n = _f(_s, var_1)
- if var_1 == nil then break end
- block
- end
- end
Note the following:
explist
is evaluated only once. Its results are an iterator function, a state, and an initial value for the first iterator variable._f
and_s
are invisible variables. The names are here for explanatory purposes only.- The behavior is undefined if you assign to
var_1
inside the block. - You can use break to exit a for loop.
- The loop variables
var_i
are local to the statement; you cannot use their values after the for ends. If you need these values, then assign them to other variables before breaking or exiting the loop.
2.4.6 – Function Calls as Statements
To allow possible side-effects, function calls can be executed as statements:
- stat ::= functioncall
In this case, all returned values are thrown away. Function calls are explained in 2.5.7.
2.4.7 – Local Declarations
Local variables may be declared anywhere inside a block. The declaration may include an initial assignment:
- stat ::= local namelist [`=´ explist1]
- namelist ::= Name {`,´ Name}
If present, an initial assignment has the same semantics of a multiple assignment (see 2.4.3). Otherwise, all variables are initialized with nil.
A chunk is also a block (see 2.4.1), so local variables can be declared in a chunk outside any explicit block. Such local variables die when the chunk ends.
The visibility rules for local variables are explained in 2.6.