Lua Language

### Introduction

Lua is a lightweight, scripting programming language based on an interpreter generating compiled bytecodes (code executing in a virtual machine).

It was designed in Brasil by Roberto Ierusalimschy, Waldemar Celes and Luiz Henrique de Figueiredo in 1993.

CE Lua is a specific version of Lua interpreter adapted by Dark Byte for Cheat Engine. The CE Lua Engine is a main component of Cheat Engine.

*This wiki page is written for Lua beginners. If you know the basic Lua syntax then you can go to the next page.*

### Syntax

CE Lua interpreter respects traditional LUA syntax and provides some extra features.
The Lua Script Editor provide a real-time colored syntax and a Syntax Check feature (**Ctrl+Alt+C**).

## Comments

In Lua simple comments begin with `--` and end at the end of the line.
Multi-line comments begin with `--[[` and end with `]]` .

```
-- This is a simple comment just to the end of this line
This is not a comment but a future syntax error -- This is a new simple comment
--[[ First line of a multi-line comment
Second line of a multi-line comment
Last line of a multi-line comment]]

```

## Variables, types and operators

In Lua variables are polymorphic (can change the type during theirs lifes). By default a variable is **global** at Lua Engine level unless the declaration begins with `local` modifier.

Any variable can host different data types and use specific operators:

* **nil** meaning nothing (a variable not defined, or not assigned, or assigned to **`nil`**)
	+ Comparing operators: comparing any variable to **`nil`** ( `var == nil` or `var ~= nil` )
* a **number** value (no difference between integer or float values, nor between different precisions)
	+ Binary arithmetic operators between two numbers: `+`, `-`, `*`, `/`, `//` (floor division), `%` (modulo), `^` (power).
	+ Unary arithmetic operator: `-` (example: `var1 = -var2`)
	+ Comparing operators between two numbers giving a boolean: `>`, `>=`, `<`, `<=`, `==`, `~=`.
	+ Bitwise operators (only on integer values): `&` bitwise AND, `|` bitwise OR, `~` bitwise XOR, `~` bitwise NOT, `<<` left shift, `>>` right shift.
* a **boolean** value (equal to `true` or `false`)
	+ Binary boolean operators: `and`, `or`.
	+ Unary boolean operator: `not`.
* a **string** (constants can be surrounded by single `'string'`or double quotes `"string"` or double square brackets `[[string]]`; the last case accepts new lines inside)
	+ Concatenation operator: `..` between two strings.
	+ Comparing operators between two strings **content** giving a boolean: `>`, `>=`, `<`, `<=`, `==`, `~=`.
	+ Length operator: `#` returns the number of characters
* a **table**
	+ Indexing operator: `[ ]` returns the associated value of an index/key in a table
	+ Indexing operator: `.` returns the associated value of a string key in a table
	+ Length operator: `#` returns the integer index of the first element not equal to `nil`
* a **function**

The assign operator `=` is mandatory just for the global variable declaration and can be use later to modify any variable. Lua supports parallel assignment from a list of values to a list of variables: `Var1, Var2, Var3 = 7, "GoesInVar2", 12*12`. First, all values expressions in the right side list are evaluated, any extra value is ignored and any missing value is replaced by **`nil`**. Then these values are assigned to the corresponding variables.

**Tips:**

* Always use the right operators for the right types.
* Always use parethesis for complex expressions (the expression `not var1==nil or var1~=3` is not equal to `not (var1==nil or var1~=3)` ).
* Use the function `type` to get a **string** containing the real type of a variable.
* Prefer using local variables versus global variables.

**Examples:**

```
local MyVar0           -- local variable having nothing inside so equal to nil
MyVar1 = nil           -- global variable MyVar1 having nothing inside (no type neither)
MyVar2 = UnknownVar    -- another global variable equal to nil (because UnknowVar is not yet defined)
local MyVar3 = 2+0x10  -- local number variable MyVar3 equal to 18 (2+16)
MyVar4 = 'Hello'       -- global string variable MyVar4
local MyVar5 = "Hello" -- local string variable MyVar5 having the same string as MyVar3
MyVar6 = [[First Line
Second Line.]]         -- global multi-line string variable MyVar6 beginning with 'First' and ending with 'Line.'
MyVar2 = (1e3 > 7.55)  -- now MyVar2 becomes a boolean equal to true
MyVar7 = print         -- global function variable MyVar7 which can be used as an alias of print function
MyVar2, MyVar3 = MyVar3, MyVar2 -- parallel assignment: MyVar2 becomes 18 and MyVar3 becomes true

```

**Automatic typecast (coercion):**

When some operators or function calls need it, Lua will try to convert automatically **numbers** to **strings** or **strings** to **numbers**:

* The expression `'1'+9` is valid and is a number because the string `'1'` will be automatically converted to the number `1`.
* But the expression `'one'+9` is a not valid because the string `'one'` can't be automatically converted to a number.
* The expression `'Waiting '..10` is valid and is a string because the number `10` will be automatically converted to the string `'10'` by the presence of `..` operator.
* But the expressions `7..'days'` or `'Waiting '..10..' seconds'` are invalid because Lua interprets the first dot `.` after `7` or `10` as a decimal separator and then it is unable to detect the concatenation operator `..`.
* Solution: use spaces and parenthesis as much as you need. The following expressions are valid: `('Waiting '..10)..' seconds'` , `'Waiting '.. 10 ..' seconds'` , and `7 ..'days'` .

**Copy operations:**

For any copy operation like assignment, function calling arguments and function returns, Lua performs a ***copy by value*** (real copy) for **nil**, **numbers**, **strings**, **booleans** types and performs a ***copy by reference*** (not a new copy, just pointing to the original) for **tables** and **functions**.

## Console output

Lua uses the `print` function to output numericals and strings to the console (use the menu to open the Lua Engine console).
The `print` function has a variable number of arguments. Each argument (**string** or **number**) will be printed to the console with spaces between arguments and a new line will be added at the end. The default format for **numbers** is the decimal base with automatic use of decimal point and/or decimal power if necessary.

**Examples:**

```
print(MyVar1)                            -- prints an empty line because MyVal1 is nil
print('MyVar3=',MyVar3,MyVar3,MyVar3)    -- prints the line 'MyVar3=2 2 2'
print("MyVar2 = ",MyVar2)                -- prints just the line 'MyVar2 = ' because MyVar2 is not a numerical nor a string
print(MyVar4..' and '..MyVar5..' again') -- prints 'Hello and Hello again'
print(#MyVar5)                           -- prints 5 (the lenght of MyVar5)
MyVar7("9.9+0.1=",9.9+0.1)               -- prints the line '9.9+0.1=10.0' (because MyVar7 is now equal to print)
MyVar7('1/0=',1/0)                       -- prints the line '1/0=inf'

```

## Flow control

Lua provides a conditional test with multiple, optional branches:

```
if BooleanExpression then
  -- if statement(s) body
elseif BooleanExpression then  -- optional
  -- elseif statement(s) body
else                           -- optional
  -- else/default statement(s) body
end

```

and several conditional loops:

```
while BooleanExpression do    -- do statements while BooleanExpression is true
  --statements
end

repeat                        -- repeat statements
  --statements
until BooleanExpression       -- until BooleanExpression becomes true

for Idx = Start,Stop,Step do  -- any numerical value for Start, Stop and Step (Step is optional and defaults to 1)
  --statements
end                           -- loop while Idx <= Stop (for positive Step) or Idx >= Stop (for negative Step)

for KeyIdx,Val in ListExpr do -- it loops over all the ListExpr, giving for each element the KeyIdx and the Val
  --statements                -- KeyIdx and Val available inside the for loop
end

```

Lua has a special unconditional block mainly used to isolate some local variables:

```
do
  --statements
end

```

The `break` instruction breaks any type of loop and jump to the next instruction after the loop.
Any flow control instruction can be embedded in any other flow control instruction.

**Examples**:

```
i=5
while i<80 do                 -- it loops for i equal to 5, 10, 20, and 40
  i=i*2
end

i=5
repeat                        -- it loops for i equal to 10, 20, 40, 80
  i=i*2
until i==80

i=5
repeat
 i=i*2
until i==82                   -- warning: this loop will never ending and will block the Lua Engine & Cheat Engine

for i = 10, 14 do             -- it loops for i equal to 10, 11, 12, 13, and 14
end

for i = 10, 14, 2 do          -- it loops for i equal to 10, 12, and 14
end

for i = 10, 14, 2.1 do        -- it loops for i equal to 10 and 12.1
end

for i = 10, 14, -2.1 do       -- it never loops because the start value 10<14 and step is negative
end

for i = 14, 10, -2.1 do       -- it loops for i equal to 14 and 11.9
end

do
  local MyVar=314;
  print(MyVar)                -- prints '314' and new line
end
print(MyVar)                  -- prints nothing but a new line

```

## Functions

Functions are just some special variables, and can be declared at the global level or inside a block or another function.

```
-- first syntax version
function MyFunction(arg1, arg2, ...)   -- takes 0, 1 to several arguments or undefined number of arguments
  -- statements
  return result1, result2              -- returns 0, 1 to several variables
end

-- second syntax version
MyFunction = function(arg1, arg2, ...) -- takes 0, 1 to several arguments or undefined number of arguments
  -- statements
  return result1, result2              -- returns 0, 1 to several variables
end

```

Any of preceding 2 declaration versions creates a function variable named `MyFunction`. Then the user can call it, use it or assign it a new value.

**Examples**:

```
MyFunction(MyVar4, MyVar2, MyVar7)   -- calling MyFunction with 3 arguments
MyVar1 = MyFunction(MyVar2, MyVar7)  -- calling MyFunction with 2 arguments and keep the first result in MyVar1
print = MyFunction                   -- now the official print function will be MyFunction
MyFunction = nil                     -- MyFunction will be unavailable now (but print still keeps original MyFunction)
MyFunction = MyVar7                  -- now MyFunction is an alias of the original print function

```

Any type of arguments or return values are copied *by value* **except for table arguments** copied *by reference*.
Any absent argument at function call will have a `nil` value during calling execution.

**Examples**:

```
Func1=function(Tab, Idx)
  if(Idx==nil) then Idx=1 end        -- giving a default value 1
  Tab[Idx]=-100                      -- changing Idx-th element in the real calling argument table (reference not copy)
  Idx=33                             -- changing Idx value, no effect to the real argument, this is a local copy value
end

function Show(Tab)                   -- prints the first 3 elements of Tab, on the same line
  print(Tab[1],Tab[2],Tab[3])
end

function Show2(Tab)                  -- prints the first 3 elements of Tab, one by line
  for Idx=1,3 do print(Tab[Idx]) end
end

function Show3(Tab)                  -- prints all elements of Tab, one by line
  for Idx in ipairs(Tab) do          -- using the build-in iterator ipairs on input table
    print(Tab[Idx])                  -- prints value using the [] operator
  end
end

function Show4(Tab)                  -- prints all elements of Tab, one by line
  for Idx,Val in ipairs(Tab) do      -- using the build-in iterator ipairs on input table
    print(Val)                       -- prints directly the value
  end
end

local MyTab1 = {10, 20, 30}          -- local table with 3 numbers
local MyIdx = 2
Show(MyTab1)                         -- prints '10 20 30'
Func1(MyTab1,MyIdx)                  -- change value of 2nd element of MyTab1 but no the value of MyIdx
Show(MyTab1)                         -- prints '20 -100 30'
Func1(MyTab1,MyIdx)                  -- change value of 1st element of MyTab1 but no the value of MyIdx
Show(MyTab1)                         -- prints '-100 -100 30'
Show2(MyTab1)                        -- prints on 3 lines '-100' '-100' '30'
Show3(MyTab1)                        -- prints on 3 lines '-100' '-100' '30'
Show4(MyTab1)                        -- prints on 3 lines '-100' '-100' '30'

```

## Tables

Tables are a very special build-in data type providing the only way to create user-defined data structures. Tables are heterogeneous associative arrays where each element is a pair of a **key/index** and a **data/value**. Data and key types can be different between elements. Lua provides automatic numeric key creation and build-in functions for access, iteration, adding etc.

A table declaration uses `{ }` and inside elements are separated by `,` . Implicit keys/indexes are automatically generated and start with 1. Explicit keys/indexes declaration uses a special syntax for each element:`[key]=value` . A key can't be `nil` nor a `NaN` number.

	+ Can be declared without surrounding squared breaks and unquoted (like the key of the first element of Tab3 in examples).
	+ Can use the point operator `.` instead of squared brackets operator `[ ]`. These make tables usage similar to structures/records/classes/namespaces in C/C++/Pascal.
* Automatic insertion:
	+ Assigning an unknown (but valid) key in a existing table will automatically create/add this element.

**Examples**:

```
-- Creates an empty table
Tab0 = {}

-- Creates an homogenous table of 3 pairs (number key/index, number value): (1,5), (2,10), and (3,20)
Tab1 = {5, 10, 20}

-- Creates an heterogeneous table of 3 pairs: (number 1,number 0), (number 2,string "second"), (number 3,function print)
Tab2 = {0, "hours", print}

-- creates an heterogeneous table Tab3 of 3 pairs: (string 'no_space',number 8), (string 'string with spaces',boolean true), (number 12,table Tab2)
-- Warning: the value of the 3th element is not a new copy of Tab2 but really Tab2 (Lua uses copy by reference for tables!)
Tab3 = {no_space = 8, ['string with spaces'] = true, [12] = Tab2}

-- The next quasi-unreadable instruction will print '8 hours'
Tab2[3](Tab3["no_space"],Tab3[12][2])
-- Explanation: Tab2[3] value is print, Tab3["no_space"] is 8, Tab3[12] is Tab2 and Tab2[2] is "hours"

Tab3[12][1]=Tab1[2]    -- write 10 (value of 2nd element of Tab1) in the value of Tab2[1] (first element of Tab2)
Tab3.no_space = -8     -- write -8 in the value of the first element of Tab3
Tab3.FourthElement=3.7 -- create a new element in Tab3 with key 'FourthElement' and value 3.7

function ShowTab(tab)
  for i,val in ipairs(tab)
    print('tab[',i,']=',val);
  end
end

ShowTab(Tab1);         -- prints each element of Tab1, one by line

function ShowTypeTab(tab)
  for key,val in pairs(tab)
    print('type(tab[',key,']) =',type(val))
  end
end

ShowTypeTab(Tab1);     -- type(tab[ 1 ]) = number
                       -- type(tab[ 2 ]) = number
                       -- type(tab[ 3 ]) = number

ShowTypeTab(Tab3);     -- type(tab[ string with spaces ]) = boolean
                       -- type(tab[ no_spaces ]) = number
                       -- type(tab[ ForthElement ]) = number
                       -- type(tab[ 12 ]) = table

Tab2D = {{9,2,3},
         {6,5,4},
         {7,8,1}}      -- embedded tables emulate a 3x3 matrix
print(Tab2D[1][1],Tab2D[2][2],#Tab2D,#Tab2D[3],#Tab2D[4])
-- prints '9 5 3 3' (lenght of Tab2D is 3 and lenght of Tab2D[3] is 3 too)

```

**Table functions:**
Lua provides several functions in the table (namespace) `table`:

* `table.insert(tab, val, pos)` : insert `val` in the table `tab` as new element, after the optional key `pos` or at the end.
* `table.remove(tab, pos)` : remove from table `tab` the element with key `pos`.
* `table.sort(tab)` : sort all elements of `tab` in increasing order of theirs values.
* `table.concat(tab, sep)` : concatenates all values of `tab` using an optional separator.

**Examples**:

```
numbs = {'One','Two','Three','Four'}
print(table.concat(numbs,' ')) -- 'One Two Three Four'
table.insert(numbs,'Five')
print(table.concat(numbs,' ')) -- 'One Two Three Four Five'
table.sort(numbs)
print(table.concat(numbs,' ')) -- 'Five Four One Three Two'
table.remove(numbs,3)
print(table.concat(numbs,' ')) -- 'Five Four Three Two'

```

## External links

* wikipedia.org/wiki/Wikipedia:Lua
* www.lua.org
* Lua Users Wiki
* Wikimedia Lua Programing Book