.. include:: alias.rst

.. _lua_scripts:

Lua scripts
===========

All scripts in states, namely the *entry*, *exit* and *action*
scripts, are written in the `Lua <http://www.lua.org>`_ language. Lua
is a widely used and well documented extension language. Thus, this
chapter is not intended to be a thorough documentation of the Lua
language itself but assumes that the reader is already familiar
with the language. Instead, this document provides
information on |rcm| data types and functions that are provided for
Lua scripts to interact with the |rcm| state machine logic, access
parameters, variables and results and call operations. The currently
used Lua interpreter is of version 5.3.5.

Accessing |rcm| properties
---------------------------

This section documents the |rcm| related data exposed by the |core| in
Lua scripts.

Parameter, result and variable values
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

States are parameterized with their parameter value and can provide
computation results through their result value.
The state's parameter value in Lua scripts is
bound to the symbol ``parameter`` while the state's current result
value is bound to the symbol ``result``. Additionally, every state can
utilize a variable to store private data which is persistent even
if a (child) state is deactivated and later activated again. The
state's variable is bound to the ``variable`` symbol.
Its parameter value corresponds to the declared parameter type of the
state, the result value corresponds to the declared result type and
the variable to the declared variable type. Values are
translated into (and from) Lua data types according to the following rules:

 * ``int`` and ``float`` types correspond to numbers.

 * ``string`` types correspond to strings.

 * ``bool`` types correspond to booleans.

 * Array types (e.g. ``[2]int``) correspond to Lua arrays, i.e. tables
   with ascending numeric keys starting with 1.

 * Struct types correspond to Lua tables with keys according to the
   struct field names.

 * State interface types correspond to Lua tables with exactly two fields,
   "state" and "parameter", just like the corresponding LF value described
   in: :ref:`lf-values`

 * A ``nil`` value corresponds to Lua ``nil``.

In addition, the functions ``setResult`` and ``setVariable`` are provided
by the |core| to allow to set the current result or variable to a new value.
``setResult`` and ``setVariable`` allows to set the result value only partially
or to set it to ``nil``. A partial result/variable value is only defined for
struct result/variable types and is a Lua table that contains a subset of the
keys of the declared result type. Fields which cannot be found in the
result/variable type struct lead to a runtime error.

Let us assume a state with the following result type:

.. code-block:: none

   {
      int foo;
      float bar;
      []int baz;
   }

The following code snippets show different examples on how to set the
result value (the same is true for ``setVariable`` and the variable value):

.. code-block:: lua

   setResult({ foo = 1, bar = 2.4, baz = {1, 2, 3} }) -- 1. Result value: { foo: 1; bar: 2.4; baz: [1, 2, 3]; }
   setResult({ foo = 1 })                             -- 2. Result value: { foo: 1; bar: nil; baz: nil }
   setResult(nil)                                     -- 3. Result value: nil
   setResult({ foo = true })                          -- 4. Runtime error: invalid type for 'foo'.
   setResult({ foo = 1.3 })                           -- 5. Runtime error: invalid type for 'foo'.

As can be seen, example 1 sets a complete result value. Example 2 sets
only one field in the result. Example 3 shows
resetting of the complete result value while both examples 4 and 5 lead to a
runtime error because the values ``true`` and ``1.3`` are not of type int.

Accessing ports
^^^^^^^^^^^^^^^

To query the truth value of ports, the |core| exposes the function
``port(name)`` in the Lua script context. The function returns a
boolean value corresponding to the truth value of the corresponding
port's expression.

Accessing children
^^^^^^^^^^^^^^^^^^

An array of the names of all children of the current |rcm| state is
bound to the symbol ``childNames``. In addition, Lua scripts can
access the activation state and result and parameter values of their
*direct* children with the ``child`` function. However, grand children
cannot be accessed.

The ``child`` function takes one parameter, the
name of the child, and returns a Lua table containing the following
properties:

 * ``active``: A boolean indicating if the child is currently active.

 * ``parameter``: The child's parameter value. Parameter expressions
   are resolved when a state is activated, so if the child has never
   been active, this value will be ``nil``.

 * ``result``: The child's result value. If the child did not set a
   result yet, this value will be ``nil``.

 * ``port(name)``: The truth value of the corresponding port of the
   child.

.. caution::

   The Lua table also contains some properties that are **experimental**
   and might have **breaking changes in the future**:

     * ``setParameterOverride(child, value)``: Set a value that will override
       the parameter value of the child obtained from resolving its parameter
       expression when the child is activated.
       For structs in the parameter type, partial values are allowed and
       will be merged into the parameter value.
       Fields which cannot be found in a parameter type struct lead to a
       runtime error.
     * ``resetParameterOverride(child)``: Removes any existing parameter override.
     * ``parameter_override``: The child's parameter override value. If no
       override has been set, this value will be ``nil``.

The following example shows how to find all currently active children:

.. code-block:: lua

   local active = {}
   for i, childName in ipairs(childNames) do
     if child(childName).active then
       active[#active + 1] = childName
     end
   end

.. hint::

   Functions taking a ``child`` as their first parameter can be called using
   the syntax ``child:function(arg)``, which is syntactic sugar for
   ``child.function(child, arg)`` in Lua.

.. note::

   Variable values can only be accessed by a state itself and not
   using the ``child()`` function.

Services, operations and events
-------------------------------

To interact with services, the |core| exposes the function
``service(name)``. It takes exactly one parameter, the name of the
service to access. The return value of the ``service`` function is a
table that contains two functions, ``operation(name)`` and
``event(name)``. The name parameter is either the name of the
operation or the name of the event to access.

The ``event`` function returns the latest event value sent by the
corresponding service or ``nil`` if none has been received yet. The
value corresponds to the declared event type and is translated to a
Lua value according to the same rules that are used for translating
parameter and result values.

The ``operation`` function returns a table with the following fields:

 * ``call(request)``: A function to call the operation. The parameter
   must be a Lua value that corresponds to the declared operation
   request type. The function does not have a meaningful return
   value. However, the call fails if a call to the same operation is
   already pending, i.e. if the operation has been called in this
   state in this macro step.

 * ``status``: A string indicating the status of a previous operation
   call. One of the following values;

   - ``"unknown"``: The operation has not been called.

   - ``"pending"``: The operation has been called but no result has
     been received yet.

   - ``"success"``: The operation call succeeded and the ``result`` field
     contains the result value.

   - ``"error"``: The operation call failed and the ``error`` field
     contains the corresponding error value returned by the service.

   - ``"internalError"``: An internal error occurred. Neither a result
     nor an error value could be received.

 * ``result``: The result value of a successful operation call or ``nil``.

 * ``error``: The error value returned by a failed operation call or
   ``nil``.

The |core| manages operation calls on a per-state basis. In other
words, operation calls are tracked separately for each state. This
allows to call the same operation in the same macro step from multiple
states. The individual correct result values are exposed to the
corresponding calling states. Result values stay valid for a complete
macro step. In particular that means that if a state called an
operation in a previous macro step and received a result in this macro
step, the result will be available even if the state makes another
call. The result will however be invalidated in the next macro step if
for the new operation call, no result has been received so far.

Results stay valid for a complete macro step. Between macro steps,
results are kept as long as a state is active and until the state
calls the operation again.

Third-party Lua modules
-----------------------

The |core| provides support for third-party Lua modules that provide
additional functionality. Currently, only a `matrix module
<http://lua-users.org/wiki/LuaMatrix>`_ is provided (also refer to the 
`github page <https://github.com/davidm/lua-matrix/blob/master/lua/matrix.lua>`_ 
of the matrix module for more details).

Modules can be loaded with Lua's ``require`` function. The following example
shows how to load and use the ``matrix`` module:

.. code-block:: lua

   matrix = require("matrix")
   foo = matrix {1, 2, 3, 4}
   foo_inverted = matrix.invert(foo)

Logging data
------------

For simple debugging, the |core| provides the two functions ``print``
and ``printf`` that allow to log data on a specific logger of the
|core|. It must be noted that both functions always print a newline as
the last character. Multiline printing is possible by using ``\n`` in strings.

The ``print`` function takes an arbitrary number of parameters and
prints them.

The ``printf`` function prints according to a format string. The
format string is a string with arbitrary characters and sequences of
format sequences. Format sequences are strings that begin with a
percent character (``%``). The following format sequences are
supported:

 * ``%1``, ``%2``, ..., ``%9``: Print the first, second, ..., ninth
   parameter after the format string.

 * ``%{n}``: Print the nth parameter after the format string.

 * ``%p``: Print the parameter value of this state.

 * ``%r``: Print the current result value of this state.

 * ``%%``: Print the `%` character.
