-
Notifications
You must be signed in to change notification settings - Fork 142
0.7 Data representation
Luerl represents data in two ways, an internal and external formats: the external format is designed to interface with native Erlang while the internal format represents data as it is handled inside this implementation of the Lua virtual machine and interpreter.
The luerl
library has two groups of functions, those ending in 1
and those that don't. The later don't assume that the arguments are in external format and automatically encodes them, while those ending in 1
assume they are in the internal format.
In most cases using the external format makes code more readable and understandable. However saving the translation costs by directly manipulating data in the internal format can be worth it, once a function for the internal representation is used you are hooked and there is no going back!
To illustrate the following two code examples are identical using the two different formats:
St0 = luerl:init().
F = fun(_, StIn) ->
{[[{<<"a">>, 1.0}]], StIn}
end.
St1 = luerl:set_table([t], F, St0).
luerl:eval("return t()", St1).
S0 = luerl:init().
F = fun ([], Sti) ->
{T, Sto} = luerl_emul:alloc_table([{<<"a">>, 1.0}], Sti),
{[T], Sto}
end.
S1 = luerl:set_table1([<<"t">>], {erl_func, F}, S0).
luerl:eval("return t()", S1).
For the implementation of Lua data types we internally use their corresponding Erlang type:
Lua | Erlang |
---|---|
nil | atom nil
|
true/false | atoms true /false
|
strings | string binaries |
numbers | floats |
tables |
#table{} with array for keys 1..n, ttdict for rest |
functions |
#lua_func{} or #erl_mfa{} or #erl_func{}
|
Nil is a type represented by the Erlang atom nil
, whose main property is to be different from any other value. Lua uses nil
as a kind of non-value, to represent the absence of a useful value.
Erlang atoms true
and false
.
Strings are the same in both formats, Luerl use Erlang binary strings, list strings will be interpreted as a table!
Numbers are the same in both internal and external representations, they are simple floats.
All tables are combinations of Erlang ttdicts and arrays. In each table an array is used for integer keys while an ttdict is used for all other keys. We use this information when building and processing tables.
Tables in Lua are known as associative arrays. All Lua types can be used as keys, except nil
.
Tables are the only data structure mechanism in Lua used to implement many data types in simple and efficient ways, lists, sets, arrays, sparse matrices, structures, the kitchen sink, you name it. Tables in Lua are also used for several other purposes like global variables, modules, object and classes, here are some notes about the insides of the Luerl implementation.
In the external format tables are represented as lists of tuples, where the first element is the index and the second the value or as lists of values where the index is implicitly assigned by their position in the list (starting with 1). The tables [1]
and [{1,1}]
are identical.
In the internal format tables are represented as references, to allocate a table reference the function luerl_heap:alloc_table/2
is that returns a new reference and a state that includes this reference then given a name using luerl:set_table1/3
. Single keys can be accessed using luerl:get_table1/2
to resolve a name to a reference and then luerl_emul:get_table_keys/3
to get the value for a given key in the table.
In the external representations functions are simply functions of the arity/2
, where the first argument is a list of function arguments and the state at the time of function execution.
They return a tuple with a list of return values as the first argument and the new state. All parameters are in the external format and all return values need to be in the external format.
In the internal format functions are a tuple with the first element being the atom erl_func
and the second a function of the arity/2
. It can also be erl_mfa
where the second element is an Erlang module name, the third argument is the function name and the fourth data is any useful Erlang data that is passed directly into the function and never modified. The function must also be a function of arity/2
. Both return values and function parameters are in the internal format.