Scripting

1 - Introduction to Lua

Lua is a typical procedural programming language, giving rich features for development. This is a powerful and simple language with huge set of meaningful constructions.

Being a language targeted to extent existing software, Lua doesn't use "main program" concept. Lua functions inside other programs' environment, called hosts. In this case GEDKeeper is the host. A host runs part of code (next: script) written in Lua. Because host can extents potential of Lua, the latter may solve wide range of tasks.

Lua is a freely distributed software, and therefore it gives no guarantees when you use it according to Lua license. You can download Lua 5.1 described on this page on Lua official site: www.lua.org.

As many other manuals, this one has a formal style. To get detailed technical information about the language usage you should refer to documentation on the Lua official site. There is a good book about Lua, that can be helpful for you: it is Roberto Ierusalimschy's Programming in Lua, Second Edition.

2 – Lua language description

This chapter describes language's constructions, how to use them and what they mean.

A construction will be presented using extended BNF, where {a} stands for zero or more number of `a` elements, and [a] means an optional element. General writing of text is used for nonterminal symbols, while keywords are highlighted with bold text: keyword; all other terminal symbols are enclosed in single quotes: '='.

2.1 – Lexical conventions

Names (identifiers) in Lua is a string of letters, digits and underline character. It cannot begin with a digit. This is a usual rule for most programming languages. You use identifiers to name variables and tables with values.

The following keywords are reserved and cannot be used as identifiers:

and      break    do     else       elseif
end      false    for    function   if
in       local    nil    not        or
repeat   return   then   true       until   while

Lua is a case-sensitive language: `and` is a keyword, while `And` and `AND` are two different valid identifiers. There is a convention, dictating that names beginning with underline and are being written in upper case (`_VERSION`, for example), are reserved to name Lua's internal global variables.

These are another allowed symbols:

+    *    /    %    ^    #
==   ~=   <=   >=   <    >    =
(    )    {    }    [    ]
;    :    ,    .    ..   ...

String literals must be enclosed in single or double quotes, and may contain the following C-like escape sequences: '\a' ("bell"), '\b' ("backspace"), '\f' ("page break"), '\n' ("new line"), '\r' ("carriage return"), '\t' ("horizontal tab"), '\v' ("vertical tab"), '\"' ("double quote character"), '\'' ("single quote character"). When you need to add a line break into a long line of code, you also use backslash character. To add a character into string literal using character code, use the following escape sequence: \ddd, where ddd is a sequence of maximum three digits. (It is worth noting that when you need to add a digit after a character written by its code, you have to use exactly three digits in the escape sequence). Lua strings may contain any 8-byte value, including null character, that is written as '\0'.

You have to use escape sequences when you need to add double quote character, new line character, backslash or null character to a string literal. Any other symbol may be written as is.

You can also define string literals using long format, when a string literal is enclosed in long brackets. Opening long bracket of level n is defined as an initial square bracket, that follows equal signs, repeated n times, that follow another initial square bracket. Thus, opening long bracket of level 0 is written as `[[`, opening long bracket of level 1 is written as `[=[`, and so on. Closing long bracket is defined in the same way. For example, closing long bracket of level 4 is written as `]====]`. Long strings begin with opening long bracket of any level, and end with the first closing bracket of the respective level. Such literals may be multiline literals; escape sequences inside it never get expanded; long brackets of any other level are ignored. They may contain anything except closing bracket of the respective level.

For convenience, when an opening long bracket is followed by new line character, the latter is not added to the string literal. For example, on a system, where character 'a' is encoded as 97, new line -- as 10 and '1' -- as 49, the following five literal declarations are the same:

a = 'abc\n123"'
a = "abc\n123\""
a = '\97bc\10\04923"'
a = [[abc
123"]]
a = [==[
abc
123"]==]

Number literal can be written with optional decimal part and exponent. When you want to define a hexadecimal number, use `0x` prefix. The following is an example of valid number literals:

3   3.0   3.1416   314.16e-2   0.31416E1   0xff   0x56

Double hyphen ('--'), everywhere outside a string literal, begins a comment. When a comment begins with double hyphen, is not being followed by an opening long bracket [, then the comment is a short one. It continues until end of the line. Otherwise, this is a long comment. It continues until a closing long bracket. Long comment is frequently used to temporary disable a part of code.

2.2 – Types and values

Lua is a language with dynamic type definition. A variable in Lua may store value of any type. There is no way to declare user-defined type. Value in Lua may be stored as a variable, passed as a function argument and be a return value of function.

There are eight main types in Lua: nil (undefined), boolean, number, string, function, userdata (user-defined data), thread and table. nil is type of the nil [empty] value. The main purpose of nil is to differ from other values and designate lack of a valid value. Values false and true have boolean type. Both nil and false values are considered as false values, any other value is true one. number is type of a double precision floating-point value. Array of characters has string type. Strings in Lua may contain any 8-byte character, including null character '\0' (see §2.1).

Lua can use a function that was implemented as Lua code, or a function that was supplied by host (see §2.5.8).

An userdata (user-defined data) instance stores any data owned by host. Value of such instance is reference to a memory block. Only assignment and equality operators are allowed for variables of type `userdata`. Using metatables, however, developer can define operations with variables of this type (see §2.8). Lua code cannot create or change variables of `userdata` type, only host can do that. This guarantees integrity of data, owned by host.

table type defines associative arrays. Both numbers and other values, except nil, can be used as indices of such arrays. The table can contain values of several types simultaneously (except nil). The only way to structure your data in Lua is tables; they can be used as simple array, character map, set, structure, tree and so on. To implement a dictionary, Lua uses keys as indices of a table. Expression `a.name` is equivalent to `a["name"]` expression. There are several ways in Lua to create tables (see §2.5.7).

Table's indices and values can be of any type except nil. And because functions are also a Lua type, tables can contain functions. Therefore, tables are able to store methods (see §2.5.9).

Variable of the following types: table, function, thread and userdata, never stores a value itself. Such variable stores reference to the respective object. Assignment (a direct one, or passing argument to function, or returning function result) processes references and never creates object copies.

type library function returns a string, that contains type of value.

2.2.1 – Type cast

Lua casts string and numeric types on the fly automatically. When you do an arithmetic operation with a string operand, the latter get converted to the respective number using general casting types. When you apply a number where string is expected, the former get converted to string type in an arbitrary appropriate format. Therefore, when you need to get some specific string representation of number, you should use format function from Lua string library (see string.format).

2.3 - Variables

Variables store values while a program is running. There are three types of variables in Lua: global variables, local variables and fields of tables.

An individual identifier declares a global or local variable (or function parameter, which is a particular case of local variable):

var ::= Name

, where Name is an identifier defined according to §2.1.

If a variable was not defined as local one explicitly, it is considered to be a global variable (see §2.4.7). A local variable exists in a lexical context: any function from this context can access the local variable. (see §2.6).

All variables initialized with nil value by default.

To access a table's element by its index, you use square brackets:

var ::= prefixexp '[' exp ']'

You can change access to global variables and fields of tables with help of metatables. Expression `t[i]` is equivalent to call `gettable_event(t, i)` (Complete description of `gettable_event` function is available in §2.8. This function is unavailable in Lua code and mentioned here only as an example).

`var.Name` expression is equivalent to `var["Name"]` expression:

var ::= prefixexp '.' Name

All global variables are fields of general Lua tables, called environment tables or, shortly, environments (see §2.9). Each function has a reference to its own environment, and all global variables inside this function refer to this table. When a function get called, it inherits the environment of caller function. You can use getfenv function to get a function's environment table, and setfenv function to change the table (if you want to change environment of C functions, you have to use debug library (see §5.9)).

Accessing global variable `x` is equivalent to `_env.x`, or also:

gettable_event(_env, "x")

where `_env` is environment of callee function (Complete description of `gettable_event` is available in §2.8. This function is unavailable in Lua code and mentioned here only as an example).

2.4 – Operators

Lua supports standard operator set, almost the same as one in Pascal and C. Lua has assignment operator, controlling flow of execution, function call and defining variables.

2.4.1 – Chunk

Chunk is an execution unit in Lua. Chunk is a sequence of any Lua operators. Operators in a chunk are delimited by semicolons:

chunk ::= {stat [';']}

Lua does not define "no operator", therefore `;;` expression is not allowed.

From Lua's perspective a chunk is an unnamed function with arbitrary parameter set (see §2.5.9). Chunk can define local variables and can return values.

Chunk is stored in file or as a line in base program. When a chunk is being dispatched to execution, it is compiled to intermediate bytecode (instructions for virtual machine). Intermediate bytecode then is executed on virtual machine.

2.4.2 – Blocks

Block is an operator list; a block is syntactically equivalent to a chunk:

block ::= chunk

Block can be defined explicitly, and, thus, defining compound operator:

stat ::= do block end

Using compound operators, you can limit a scope for local variables. Compound operators is also used in loops and conditional operators (see §2.4.4).

2.4.3 – Assignment

Lua supports parallel assignment. In the general case, assignment operator is variable list, `=` symbol and expression list. List entries are delimited by comma:

stat ::= varlist1 '=' explist1

varlist1 ::= var {',' var}

explist1 ::= exp {',' exp}

Expressions are discussed in §2.5.

Before been assigned, variable list is adjusted with expression list by their length. If the list on the right side is longer than one on the left side, excess elements are simply ignored. If the right list is shorter, missing elements are defined as nil. If operator list ends with function call, then, before adjustment, all return values are added to the right list (except cases, when function call is enclosed in parentheses; see §2.5).

All expressions are evaluated before assignment. In the following code:

i = 3

i, a[i] = i + 1, 20

`a[3]` gets 20, because `i` in `a[i]` expression has the same value, as in `i + 1` expression, when it is being evaluated. Similarly, the following line

x, y = y, x

simply swaps values of two variables ("classic" method requires a temporary variable).

Metatables can override assignment operations for global variables and fields of tables. Assigning to an indexed variable `t[i] = val` is equivalent to `settable_event(t, i, val)` expression (Complete description of `settable_event` function is available in §2.8. This function is unavailable in Lua code and mentioned here only as an example).

Global variable assignment `x = val` is equivalent to `_env.x = val` expression, or

settable_event(_env, "x", val)

, where `_env` is environment of callee function (variable `_env` is unavailable in Lua code and mentioned here only as an example).

2.4.4 – Control structures

if, while and repeat operators have 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

There are two variants of for loop in Lua (see §2.4.5).

A boolean expression in control structures can have any value. false and nil are false values. Everything else is true (including 0 and an empty string!).

repeat-until loop ends on the condition that is followed until keyword. Therefore, the loop's condition can use local variables from loop's scope.

return operator returns value from a function or chunk. Syntax of return operator allows to return multiple values from function or chunk:

stat ::= return [explist1]

break operator terminates while, repeat or for loop:

stat ::= break

break exits a loop, in which scope `break` is written; outer loops continue execution.

return (or break) must be the last operator in a block (otherwise, all following operators will be ignored). If you do need return or break inside a block, you should use compound operator, like `do return end` or `do break end`.

2.4.5 – For operator

for operator has simple and extended notation.

In simple notation for executes code while its loop variable, that is changed by an arithmetical progression, does not reach a defined limit.

stat ::= for Name ' = ' exp1 ',' exp2 [', ' exp3] do block end

The loop repeatedly executes block for the name loop variable, that initially has exp1 value, increments name by exp3 on each iteration, while exp2 is evaluated to true value.

Thus, the following code

for v = e1, e2, e3 do block end

is equivalent to

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

        local v = var

        block

        var = var + step
    end
end

It is worth noting that:

Extended notation of for operator uses iterator functions. On each loop iteration iterator is called to get new value for the loop variable. The loop terminates when its iterator returns nil. Syntax of extended notation of for operator:

stat ::= for namelist in explist1 do block end

namelist ::= Name {', '~ Name}

The following code

for var_1, ···, var_n in explist do block end

can be written as

do
    local f, s, var = explist

    while true do
        local var_1, ···, var_n = f(s, var)

        var = var_1

        if var == nil then break end

        block
    end
end

It is worth noting that:

2.4.6 – Function call

To create a side effect, it may be helpful to call functions, used as operators:

stat ::= functioncall

In this case all return values are ignored. Function calls are discussed in §2.5.8.

2.4.7 – Local declaration

Local variables are declared anywhere inside a block. Declaration may include initialization:

stat ::= local namelist ['=' explist1]

Initialization has all properties of assignment operation (including parallelism), see §2.4.3. By default, any variable is initialized with nil.

A chunk is a block (see §2.4.1), therefore a local variable can be declared outside any explicit block. Scope of such local variable is the chunk's bounds.

The visibility rules for local variables are discussed in §2.6.

2.5 - Expressions

The following constructions are Lua expressions:

exp ::= prefixexp

exp ::= nil | false | true

exp ::= Number

exp ::= String

exp ::= function

exp ::= tableconstructor

exp ::= '...'

exp ::= exp binop exp

exp ::= unop exp

prefixexp ::= var | functioncall | '(' exp ')'

Numbers and string are discussed in §2.1; variables -- in §2.3; function declaration -- in §2.5.9; function call -- in §2.5.8; table constructor -- in §2.5.7. Implicit arguments, that are defined as `...`, can be used only with the properly declared function; see §2.5.9.

Binary operations (binop) include arithmetic (see §2.5.1), comparison (see §2.5.2), boolean (see §2.5.3) and concatenation (see §2.5.4) operations. Unary operations include unary minus (see §2.5.1), negation not (see §2.5.3) and length query # (see §2.5.5).

Function call result and implicit parameters can contain several values. If they are used as operators (§2.4.6) (functions only), any return value is ignored. If this is the last or the only element in expression list, no correction is performed (if the call is not enclosed in parentheses). In all other cases Lua converts return list to single element by throwing all values away except the first one.

Here are some examples:

f()                -- function result is ignored

g(f(), x)          -- only the first value in the list counts - it is `f()` result

g(x, f())          -- g gets x and all values from f()

a,b,c = f(), x     -- getting the first element from calling to `f()` result (`c` gets `nil`)

a,b = ...          -- `a` gets the first argument from `...`, `b` - the second (both `a` and `b` may get `nil`, when implicit parameter list is empty)

a,b,c = x, f()     -- two results from f()

a,b,c = f()        -- three results from f()

return f()         -- return all values from f()

return ...         -- return all implicit arguments

return x,y,f()     -- return `x`, `y` and everything from f()

{f()}              -- create a list with results from f()

{...}              -- create a list with all implicit parameters

{f(), nil}         -- single result from f()

An expression enclosed in parentheses always returns single value. Thus, `(f(x,y,z))` always gives single value, even if `f` returns several values. Value of `(f(x,y,z))` is the first value that `f` gives, or `nil` when `f` does not return value.

2.5.1 – Arithmetic operations

Lua supports general arithmetic: binary + (addition), - (subtraction), * (multiplication), / (division), % (remainder in division) and ^ (powering); unary - (sign reversal of number). When operands are numbers or strings (which are convertible to numbers §2.2.1), all operations work seamlessly. Powering functions for any power exponent. For example, x^(-0.5) calculates reciprocal of square root of `x`.

2.5.2 – Comparison operations

The following are Lua's comparison operations:

==    ~=    <     >     <=    >=

Comparison operations always return false or true.

Equality operator (`==`) compares operand types at first. When the types are different, the operator returns false. Otherwise the operator compares values of operands. Numbers and strings are compared as usual. Objects (tables, used-defined datatypes, threads and functions) are compared by reference: two objects are equal when they are the same object. Newly created object (table, used-defined datatype, thread or function) cannot be equal to already existing object.

Conversion rules from §2.2.1 do not affect equality operators. For example, `"0"==0` gives false, while `t[0]` and `t["0"]` are two different table record.

`~=` operator is antithetic to equality operator `==`.

Lesser or bigger operators works in the following way. Numbers are compared as usual. Strings are compared in lexicographical order. All other cases will cause call of metamehod (is not discussed in this manual).

2.5.3 – Logical operations

Lua supports the next logical operations: and, or and not. Just as control structures do (§2.4.4), logical operations consider false and nil as false and everything else as true.

Negation operation not always returns false or true. Conjunction operation and returns its first operand if value of the first operand is false or nil; otherwise and returns the second operand. Disjunction operation or returns the first operand when value of the first operand is not equal to nil and false; otherwise or returns the second argument. Both operators evaluate the second operand only if it is necessary.

Examples:

10 or 20            --> 10

10 or error()       --> 10

nil or "a"          --> "a"

nil and 10          --> nil

false and error()   --> false

false and nil       --> false

false or nil        --> nil

10 and 20           --> 20

(In this manual --> shows evaluation result)

2.5.4 - Concatenation

Strings concatenation operator in Lua is two points: `..`. When both operands are numbers or strings, they will be converted to strings according to the rules described in §2.2.1. Otherwise -- metamehod is called (this is not discussed in this manual).

2.5.5 – Getting length

Unary # is getting length operation. This operation returns number of bytes in a string (in the usual sense, this is the length of a string where each character occupies one byte).

Any integral index `n` is the length of table `t`, when t[n] is not nil but t[n+1] is nil. Furthermore, `#t = 0` if t[1] is nil. For arrays from 1 to n, not containing nils, length is `n`, i.e. index of the last value. When an array has "holes" (nil values between non-nil values), `#t` is index of an element, followed by nil value (therefore, any nil value is the end of array per se).

2.5.6 – Operator precedence

The following table shows operator precedence in Lua. Powering has the most priority and then in descending order:

or
and
<     >     <=    >=    ~=    ==
..
+     -
*     /     %
not   #     - (unary)
^

To change expression evaluation order you use parentheses. Concatenation ('..') and powering ('^') are right-associative operators. All other binary operators are left-associative.

2.5.7 – Table constructor

Table constructor is an expression. Any table constructor in code causes creation of a new table. The constructors can create either empty or partially or fully initialized tables. This is table constructor syntax:

tableconstructor ::= '{' [fieldlist] '}'

fieldlist ::= field {fieldsep field} [fieldsep]

field ::= '[' exp ']' '=' exp | Name '=' exp | exp

fieldsep ::= ',' | ';'

Each field, written as `[exp1] = exp2`, adds `exp2` value with `exp1` key into the table. `name = exp` field is equivalent to `["name"] = exp` field. `exp` field is equivalent to [i] = exp, where `i` is integer autoincrement counter with seed equal to 1. Fields that were defined in other formats, do not affect this counter. For example, the following definition:

	a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }

is equivalent to

do
	local t = {}

	t[f(1)] = g

	t[1] = "x"

	t[2] = "y"

	t.x = 1

	t[3] = f(x)

	t[30] = 23

	t[4] = 45

	a = t
end

If the last field in the definition list was declared as `exp`, and `exp` is a function call or undefined parameter list, then all values that are returned by this expression, are sequentially added to this list (§2.5.8). To avoid this, enclose function call (or undefined parameter list) in parentheses (§2.5).

Field list may be terminated by delimiter. This makes computer-generated code more readable.

2.5.8 – Function call

Function call in Lua has the following syntax:

functioncall ::= prefixexp args

Prefix expression and arguments are evaluated first in a function call. When prefix expression has function type, the function is called with the supplied arguments. Otherwise metamehod is called (it is not discussed in this manual).

The following notation

functioncall ::= prefixexp ':' Name args

can be used to call "methods" `v:name` expression (args) is a syntax analog of `v.name` (`v,args`), but `v` is evaluated only once.

Here is definition on arguments:

args ::= '(' [explist1] ')'

args ::= tableconstructor

args ::= String

All expressions are evaluated before call made. A call made by `f{fields}` expression is an analog of `f ({fields})` expression; thus, argument list is a new table per se. A call made by `f'string'` (or `f"string"`, or `f[[string]]`) is an analog of `f('string')`; but in this case a single string literal is a list of arguments

Pretty loose Lua syntax has an exception: you cannot add a line break right before `(` when you call a function. This exception avoids ambiguity in Lua. If you wrote:

a = f

(g).x(a)

Lua processes this as ` a = f(g).x(a)` expression. If you still need two expressions, you must add a semicolon between the expressions. If you actually need to call `f` function, you should remove line break before `(g)`.

A final call is when you call a function with `return function call`. Lua supports self final call (or recursive final call): in this case callee uses stack of the caller. Therefore number of recursive final calls is not limited. It is worth noting that a final call removes debug information about the caller. Syntax of final call allows to call only a single function, mentioned after return operator. Thus, return gives just the same result, as the function gives. There is no valid final call in the following example:

return (f(x))        -- result list get truncated

return 2 * f(x)      -- result get doubled

return x, f(x)       -- several values are returned

f(x); return         -- call result is ignored

return x or f(x)     -- result list get truncated

2.5.9 – Function declaration

This is the function declaration syntax:

function ::= function funcbody

funcbody ::= '(' [parlist1] ')' block end

Or, more simplified version:

stat ::= function funcname funcbody

stat ::= local function Name funcbody

funcname ::= Name {'.' Name} [':' Name]

Expression

function f () body end

is evaluated as

f = function () body end

Expression

function t.a.b.c.f () body end

is evaluated as

t.a.b.c.f = function () body end

Expression

local function f () body end

is evaluated as

local f; f = function () body end

but not as

local f = function () body end

The difference will appear when function body uses the same function name, for example, on recursion call.

Function declaration is an evaluated expression, its type is function type. When Lua is precompiling a chunk, all functions in the chunk are also precompiled. Thus, when Lua processes a function declaration, the function is already instantiated (or closed). This instance (or closure) is the final value of "function declaration" expression. Different instances of the same function may refer different outer local variables and have different environment tables.

Function's arguments are local variables per se; they are initialized with argument values:

parlist1 ::= namelist [',' '...'] | '...'

When a function is called, length of passed argument list is adjusted according to declaration, if the function is not a function with variable argument list. There is no adjustment made for functions with variable argument list; all arguments are passed as multiple result of function. When an undefined expression is used inside another expression or inside expression list, then its value list get truncated to one entry. When such expression is the last in expression list, truncation is not made (but only if the call is not enclosed in parentheses).

Let's examine the following declarations:

function f(a, b) end

function g(a, b, ...) end

function r() return 1,2,3 end

This is an example of how arguments are mapped to function parameters:

CALL            PARAMETERS

f(3)             a=3, b=nil

f(3, 4)          a=3, b=4

f(3, 4, 5)       a=3, b=4

f(r(), 10)       a=1, b=10

f(r())           a=1, b=2


g(3)             a=3, b=nil, ... -->  (nothing)

g(3, 4)          a=3, b=4,   ... -->  (nothing)

g(3, 4, 5, 8)    a=3, b=4,   ... -->  5  8

g(5, r())        a=5, b=1,   ... -->  2  3

A function gives back its result with return operator (see §2.4.4). If you omitted return operator, and execution flow reaches end of the function, function completes but do not return any value.

Syntax with a colon (`:`) is used when you need to define methods. Such functions get `self` as implicit first argument. Thus, expression:

function t.a.b.c:f (params) body end

is similar to:

t.a.b.c.f = function (self, params) body end

2.6 – Scope

Lua is a language having lexical delimitation of scopes. A variable scope begins after the variable declaration and exists until end of block, where the variable was declared. Let's examine the following example:

x = 10                  -- a global variable

do                      -- beginning of a block
    local x = x         -- local variable declaration

    print(x)            --> 10

    x = x+1

    do                  -- beginning of an enclosed block
        local x = x+1   -- another local variable 'x'

        print(x)        --> 12
    end

    print(x)            --> 11
end

print(x)                --> 10  (global variable)

It is worth noting that in the `local x = x` declaration, the local variable is declared in foreigner scope, therefore value of the external variable is assigned.

According to the rules of lexical delimitation of scopes, local variables are accessible for functions, that were declared in variables' scopes. When such a function uses such a variable, the variable is called outer local variable (relative to a function declared in the variable's scope).

Each local declaration creates new local variable. For example:

a = {}

local x = 20

for i=1,10 do

    local y = 0

    a[i] = function () y=y+1; return x+y end

end

The loop creates ten instances of the function, which use different `y` variables and the same `x` variable.

2.7 – Error handling

Lua is an extension language, therefore, Lua starts to work when a hosting code has called lua_pcall Lua library function. If an error occurred while Lua code was being compiled or run, host application gets execution control and performs error handling (it shows an error message, for example)

Lua program can generate an error explicitly, by calling error function. If you want to handle errors in Lua code itself, use pcall function.

2.8 – Garbage collector

Lua manages memory resources automatically. This means that you do not have to worry about memory allocation when you create an object, and memory deallocation once an object becomes unnecessary. Lua runs garbage collector from time to time, that removes in background out of date objects (i.e. objects that are not accessible from Lua code anymore). The garbage collector processes all Lua objects: tables, userdata instances, functions, threads and strings.

3 - Using Lua in GEDKeeper

3.1 - Naming convention

"gk_" prefix is used for general functions,
"gt_" prefix is used for functions that process a tree.

Data types:
`void` is an empty argument or function result;
`int` is an integer argument or function result;
`string` is a string argument or function result;
`boolean` is a boolean argument or function result.

Attention: the first entry in any database list has zero index. Therefore, to enumerate all database records, for example, you should use the following code:


for i = 0, gt_get_records_count() - 1 do -- i.e. number of elements "-1"
	...
end

3.2 - Data structure

Any database structure is handled via pointers. A pointer is a special variable, that stores (refers to) some memory location where a structure is located.

There are following available types of pointer to structures:

3.3 - API

void gk_print(string text)
Outputs `text` string.
void gk_progress_init(int length, string title)
Shows the window with a progress state, where `length` is number of progress stages, `title` is a header.
void gk_progress_done()
Hides the window with a progress state.
void gk_progress_step()
Increases number of completed progress stages by one.
int gk_strpos(string substr, string str)
Finds the first occurrence of `substr` in `str` and returns its index.
void gk_update_view()
Updates all lists (this is necessary after bulk update).
string gk_select_file()
Shows "Open file" dialog and returns filename.
int gt_get_records_count()
Returns number of records in database.
record_ptr gt_get_record(int index)
Gets a database record by its index. Attention: records of all type are located randomly in database. They are stored in a sequence in which they were added to database. Therefore, you should always check type of a record.
int gt_get_record_type(record_ptr)
Gets type of the specified record. Possible return values:
string gt_get_record_type_name(int type)
Converts record type from numeric view to string one.
string gt_get_record_xref(record_ptr)
Returns record identifier, used for cross-reference links between database records.
string gt_get_record_uid(record_ptr)
Get global unique identifier of the specified record.
gt_delete_record(record)
Removes the specified record from database.
boolean gt_record_is_filtered(record_ptr)
Returns `true` when the specified record was filtered out and it is visible on the current view.
string gt_get_person_name(record)
Gets full name of the specified person.
int gt_get_person_associations_count(person_ptr)
Gets number of associations for the specified person.
ptr gt_get_person_association(person_ptr, int index)
Gets an association for specified person by the given index.
gt_delete_person_association(person_ptr, index)
Removes the specified association from the specified person.
int gt_get_person_events_count(person_ptr)
Gets number of facts for the specified person.
event_ptr gt_get_person_event(person_ptr, int index)
Get a fact for the specified person using the specified index.
gt_delete_person_event(person_ptr, int index)
Removes the specified fact from the specified person.
string gt_get_event_value(event_ptr)
Converts the specified event to a string.
string gt_get_event_place(event_ptr)
Gets location of the specified event.
string gt_get_event_date(event_ptr)
Gets date of the specified event as a string.
string gt_get_event_name(event_ptr)
Returns name - identifier of the specified event type (attention: this is internal event identifier, see Identifiers of event types ).
person_ptr gt_create_person(string name, string patronymic, string family, string sex)
Creates new person record: `name` is person's first name, `patronymic` is person's patronymic name, `family` is person's last name, `sex` is person sex (possible values: "N" -- not defined, "M" -- male, "F" -- female, "U" -- unknown).
family_ptr gt_create_family()
Creates new family record.
gt_bind_family_spouse(family_ptr family, person_ptr spouse)
Attaches `spouse` husband to `family`. Attention: `spouse` record must have defined sex, because it is used on automatic detection of a role in family.
bool csv_load(string filename, bool first_line_is_schema)
Loads CSV table from `filename` file. `first_line_is_schema` defines whether the first row in the file is a header row.
csv_close()
Close previously opened CSV table.
int csv_get_cols()
Returns number of columns in the CSV table.
int csv_get_rows()
Returns number of rows in the CSV table.
string csv_get_cell(col, row)
Gets value of the specified cell in the CSV table (rows and columns are numbered from zero).
note_ptr gt_create_note()
Creates new note record.
gt_bind_record_note(record_ptr, note_ptr)
Attaches the note to the record.
gt_add_note_text(note_ptr, string text)
Appends the specified note with the new `text`.
record_ptr gt_select_record(int record_type)
Shows record selection dialog.
gt_bind_record_source(record_ptr, source_ptr, string page, int quality)
Attaches the specified source to the specified record and sets `page` and source `quality` (0..3).
string gt_define_sex(string name, string patronymic)
Returns sex identifier evaluated from `name` and `patronymic`.
gt_set_event_place(event_ptr, string place)
Sets location in the specified event.
source_record gt_create_source(string name)
Creates new source with the specified name.
source_record gt_find_source(string name)
Search through list for a source with the specified name.
event_ptr gt_create_event(record_ptr, string sign)
Creates new fact in person or family record, where `sign` is type of the fact given by string.
gt_set_event_date(event_ptr, string date)
Sets `date` for the specified event.
gt_bind_family_child(family_ptr, person_ptr child)
Adds the specified child to the specified family.
association_ptr gt_add_person_association(person_ptr, string relation, person_ptr rel_person)
Adds to `person_record` new link-association to `rel_person`. For example, this can be used when one creates a link with godparents.
string gt_define_patronymic(string father_name, string child_sex, bool confirm)
Defines patronymic name of a child that is `child_sex` and having father with `father_name`, using internal dictionary. `confirm` parameter defines must a confirmation be shown to user in arguable cases.
family_record gt_get_person_parents_family(person_ptr)
Gets parent's family of the specified person.
int gt_get_person_spouses_count(person_ptr)
Gets number of spouses of the specified person.
family_ptr gt_get_person_spouse_family(person_ptr, int index)
Gets family of the specified person and his wife or her husband, `index` is a marriage number.
person_ptr gt_get_family_husband(family_ptr)
Gets husband in the specified family.
person_ptr gt_get_family_wife(family_ptr)
Gets wife in the specified family.
int gt_get_family_childs_count(family_ptr)
Gets number of children in the specified family.
person_ptr gt_get_family_child(family_ptr, int index)
Gets a child person in the specified family by child number.