This page is showing examples in the target language CC++PythonTypeScriptRust. You can change the target language in the left sidebar.
A subset of LF syntax is used to write expressions, which represent values in the target language. Expressions are used to initialize state variable and to give values to parameters. Arbitrary expressions in the target language can always be given within delimiters {= ... =}
, but simple forms do not require the delimiters. These simple forms are documented here.
Basic expressions
The most basic expression forms, which are supported by all target languages, are the following:
-
Literals:
- Numeric literals, e.g.
1
,-120
,1.5
,3.14e10
. Note that the sign, if any, is part of the literal and must not be separated by whitespace. - String literals, e.g.
"abcd"
. String literals always use double-quotes, even in languages which support other forms (like Python). - Character literals. e.g.
'a'
. Single-quoted literals must be exactly one character long —even in Python. - Boolean literals:
true
,false
,True
,False
. The latter two are there for Python.
- Numeric literals, e.g.
-
Parameter references, which are simple identifiers (e.g.
foo
). Any identifier in expression position must refer to a parameter of the enclosing reactor. -
Time values, e.g.
1 msec
or10 seconds
. The syntax of time values isinteger time_unit
, wheretime_unit
is one of the following:- nsec or ns: nanoseconds
- usec or us: microseconds
- msec or ms: milliseconds
- sec, second, or s: seconds
- minute or min: 60 seconds
- hour: 60 minutes
- day: 24 hours
- week: 7 days
Each of these units also support a plural version (e.g.,
nsecs
,minutes
, anddays
), which means the same thing.The time value
0
need not be given a unit, but for all other values, the unit is required.Time values are compatible with the
time
type. -
Escaped target-language expression, e.g.
{= foo() =}
. This syntax is used to write any expression which does not fall into one of the other forms described here. The contents are not parsed and are used verbatim in the generated file.
For instance, to have a 2-dimensional array as a parameter in C:
reactor Foo(param:()) { ... }
Both int[][]
and { {1}, {2} }
are C fragments here, not LF.
For instance, to assign a 2-dimensional list as an initial value to a parameter in the Python target:
reactor Foo(param()) { ... }
Collections
This page is showing examples in the target language CC++PythonTypeScriptRust. You can change the target language in the left sidebar.
To avoid the awkwardness of using the code delimiters {= ... =}
, Lingua Franca supports initialization of simple arrays and similar structures. The interpretation is slightly different in each target language.
In C, a parameter or state may be given an array value as in the following example:
reactor Foo(param:double[](0.0, 1.0, 2.0)) { ... }
This will become an array of length three. When instantiating this reactor, the default parameter value can be overridden using a similar syntax:
main reactor { f = new Foo(param = (3.3, 4.4, 5.5)); }
See the Target Language Details for details and alternative syntaxes.
In C++, initial values for a parameter or state can be used to pass arguments to a constructor, as in the following example:
state x: int[](1,2);
Here, the type int[]
is translated by the code generator into std::vector
and the (1,2)
to constructor arguments, as in new std::vector(1,2)
. See the Target Language Details for details and alternative syntaxes.
In Python, a parameter or state variable may be assigned an array expression as its initial value, as in the following example:
reactor Foo(param(1, 2, 3)) { state x(1, 2, 3) ... }
The Python target interprets the (1, 2, 3)
expression differently depending on
whether the assignee is a parameter or a state variable. For parameters, the
(1, 2, 3)
expression will translate into an immutable Python tuple (i.e.,
param = (1, 2, 3)
). For state variables, the (1, 2, 3)
expression will
translate into a mutable Python list (i.e., x = [1, 2, 3])
). The reason behind
this discrepancy is that parameters are assumed to be immutable after
instantiation (in fact, they are also read-only in reaction bodies), but state
variables usually need to be updated during execution.
Notice that even though the tuple assigned to the parameter is immutable (you cannot assign new values to its elements), the parameter itself can be overridden with another immutable tuple when instantiating the reactor:
main reactor { f = new Foo(param = (3, 4, 5)) }
See the Target Language Details for details and alternative syntaxes.
In TypeScript, a parameter or state variable may be assigned an array expression as its initial value, as in the following example:
reactor Foo(param:()) { state x:(); }
See the TypeScript reactor documentation for details and alternative syntaxes.
FIXME: Rust