-
Notifications
You must be signed in to change notification settings - Fork 143
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. Those that don't assume that the arguments are in external format and automatically encodes them, while those ending in 1
assume they are in 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 the first using the external representation the second using the internal one:
Command | Description |
---|---|
git status | List all new or modified files |
git diff | Show file differences that haven't been staged |
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, ordict for rest |
functions | #lua_func{} or #erl_func{} |
See luerl.hrl for the field names of the records.
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.
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 represented the same in both formats, luerl uses binary strings list strings will be interpreted as a table!
Numbers are the same in both internal and external representations, they are simple float numbers. Please be aware that in Lua < 5.3 numbers are always treated as floats.
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, tables 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, next are some notes about the insides of its 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_emul: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 function
and the second a function of the arity/2
.
Both the return values as well as the function parameters are in the internal format as well.