# Erlang-Lua

Erlang C Node to run Lua scripts

This library provides a way to run Lua code from within Erlang. It
differs from the other Lua - Erlang integrations available, in that it runs
the Lua VM as an external Node (using Erlang's Port and C Node

It's early days in making this available to the public, so be aware
that some assembly is required.

## Building

The Erlang-Lua C C Node code currently compiles and tests successfully
on Mac OS X (10.9, using XCode command line utilities) and Ubuntu
(Trusty 14.04.1 LTS). It probably works on further Mac OS X versions
and Linux distros, but I've not tried it yet.

A Lua installation (5.1 or 5.2) is required to be on the system.
It's needed for the header files and to link the C Node. You can
get Lua from . The current 5.1 source package
can be downloaded from ,
and the 5.2 one from . To
build on Mac OS X, you run `make macosx test`, and on Ubuntu run
`make linux test`. You'll need to install it somewhere, run `make
INSTALL_TOP=Path_to_Lua_installation install`.

Building the Erlang-Lua C Node uses `rebar`
(, and a small `Makefile` is provided
to wrap around the calls to `rebar`. You need to edit the `rebar.config`
file and edit the setting of the Lua path to point to your Lua

{ port_env,[
    {"LUA", "/Path_to_Lua_installation"},

After that, `make compile` compiles it all up (expect a warning
about `missing braces around initializer`) and `make test` runs the
Eunit test suite. The latter produces a whole bunch of logging to
standard output and, if all is good, ends with `All 87 tests passed.`
A `make clean` does the obvious.

## What It Can Do

Starting a Lua VM through
(rtr@> erlang_lua:start_link(foo).
brings up a `gen_server` that provides the interface to running and
monitoring the Lua VM. It starts a C program to run the Lua VM via
`open_port`, monitors it and receives logging from it. The C program
itself initialises itself as an Erlang C Node and connects to the
Erlang Node that launched it.

Running Lua code on the external Lua VM is accomplished by sending
messages to the C Node and receiving answers back. The Lua results
are converted to Erlang terms.
(rtr@> erlang_lua:lua(foo, <<"return {x=1, y='foo'}">>).
(rtr@> erlang_lua:lua(foo, <<" x = 42 + 'fourty two' ">>).
{error,"[string \" x = 42 + 'fourty two' \"]:1: attempt to perform
 arithmetic on a string value"}

Some support for automatically translating Erlang values to Lua is
available via the `call` interface:
(rtr@> erlang_lua:lua(foo, <<"find = string.find">>).
(rtr@> erlang_lua:call(foo, find, [<<"foobar">>, <<"(o)b(a)">>]).

It is also possible to call back into Erlang from Lua:
(rtr@> erlang_lua:lua(foo, <<"return erl_rpc('date')">>).
(rtr@> erlang_lua:lua(foo, <<"return erl_rpc('erlang', 'date')">>).
(rtr@> erlang_lua:lua(foo, <<"return erl_rpc('lists', 'seq', 2, 15, 3)">>).
(rtr@> S = <<"foobar">>.
(rtr@> {lua, [ R ]} = erlang_lua:call(foo, erl_rpc, [base64, encode, S]).
(rtr@> {lua, [ S ]} = erlang_lua:call(foo, erl_rpc, [base64, decode, R]).

The Lua VM is stopped using
(rtr@> erlang_lua:stop(foo).

### Value Translation From Lua To Erlang

	nil -> 'nil' Atom

	true -> 'true' Atom
	false -> 'false' Atom

	erl_atom"string" -> 'string' Atom

	integer number -> Integer Number
	floating point number -> Float Number

	"string" -> Binary

	erl_string"string" -> "string" String

	erl_tuple{ V1, V2, V3, ..., Vn } -> { V1, V2, V3, ..., Vn }

	{ V1, V2, V3, ..., Vn } -> [ V1, V2, V3, ..., Vn ]

	{ K1=V1, K2=V2, K3=V3, ..., Kn=Vn } -> [ {K1, V1}, {K2, V2}, {K3, V3}, ..., {Kn, Vn} ]
		/ Order of pairs not guaranteed,
		/ If type(K) == "string" and #K < 256 then Erlang K is Atom

	{ V1, V2, ..., Vn, Kn+1=Vn+1, Kn+2=Vn+2, ..., Kn+k=Vn+k  }
			-> [ V1, V2, ..., Vn, {Kn+1, Vn+1}, {Kn+1, Vn+2}, ..., {Kn+1, Vn+n} ]
		/ Order of {K, V} pairs not guaranteed
		/ If type(K) == "string" and #K < 256 then Erlang K is Atom

	Unusable types:
		function -> 'function' Atom
		userdata -> 'userdata' Atom
		thread -> 'thread' Atom
		lightuserdata -> 'lightuserdata' Atom

### Value Translation From Erlang To Lua

	'nil' Atom -> nil
	'true' Atom -> true
	'false' Atom -> false

	Atom -> string

	Integer Number -> number
	Float Number -> number

	Binary -> string
	/ Note: Regular Erlang Strings are Lists: "abc" -> { 97, 98, 99 }

	{ V1, V2, V3, ..., Vn } -> { V1, V2, V3, ..., Vn }
	[ V1, V2, V3, ..., Vn ] -> { V1, V2, V3, ..., Vn }

	[ {K1, V1}, {K2, V2}, {K3, V3}, ..., {Kn, Vn} ] -> { K1=V1, K2=V2, K3=V3, ..., Kn=Vn }
		/ If all Erlang K are Atoms

	[ V1, {K2, V2}, V3, {K4, V4}, V5, ..., Vn, {Kn+1, Vn+1}, ... ] -> { V1, V3, V4, ..., Vn, K2=V2, K4=V4, ..., Kn+1=Vn+1 }
		/ If Erlang K is Atom
		/ Note: All elements that are not a 2-tuple with the first element an Atom, become array elements in Lua
		/      Only the ordering of non 2-tuples is preserved! 

	Unusable types:
		Reference, Fun, Port, Pid -> nil