simple-expr | ::= | value-path |
| | constructor | |
| | constructor expr | |
| | immediate | |
| | ( expr ) | |
| | { label = expr { ; label = expr } } | |
| | simple-expr . label | |
multiple-matching | ::= | pattern-list -> expr |
| | pattern-list => expr | |
pattern-list | ::= | pattern { pattern } |
expr | ::= | simple-expr |
| | simple-expr simple-expr { simple-expr } | |
| | fun multiple-matching | |
| | simple-expr where [ rec ] definition { and definition } | |
| | let [ rec ] definition { and definition } in expr | |
| | if expr then expr else expr | |
| | prefix-op expr | |
| | expr infix-op expr | |
| | expr or expr | |
| | not expr | |
| | expr when expr | |
| | expr whenot expr | |
| | merge expr expr expr | |
| | expr fby expr | |
| | pre expr | |
| | last ident | |
| | expr -> expr | |
| | run simple-expr { simple-expr } | |
| | await signal-pattern do expr | |
| | match expr with match-handlers end | |
| | reset expr every expr | |
| | automaton automaton-handlers end | |
| | present present-handlers end | |
match-handlers | ::= | [ | ] pattern -> expr { | pattern -> expr } |
present-handlers | ::= | [ | ] signal-pattern -> expr { | signal-pattern -> expr } |
automaton-handlers | ::= | [ | ] automaton-handler { | automaton-handler } |
automaton-handler | ::= | constructor [ pattern ] -> expr transitions |
transitions | ::= | є |
| | then state-expression | |
| | continue state-expression | |
| | transition { transition } | |
transition | ::= | until signal-pattern then state-expression |
| | until signal-pattern continue state-expression | |
| | unless signal-pattern then state-expression | |
| | unless signal-pattern continue state-expression |
The precedence and associativity rules are the one of Objective Caml. For special Lucid Synchrone primitives, they are given below: higher precedences come first.
run | left |
last | right |
pre | - |
function application | right |
fby | left |
when, whenot | left |
merge | left |
... let,... | - |
-> | right |
Expressions consisting in a constant evaluate to an infinite stream made of this constant.
Expressions consisting in a variable evaluate to the value bound to this variable in the current evaluation environment.
The expression ( expr ) has the same value than expr.
A function abstraction has two forms:
fun pattern_{1} ... pattern_{n} -> expr |
defines a combinatorial (or state-less) function. This means that expression expr must not contain any state constructions.
fun pattern_{1} ... pattern_{n} => expr |
defines a sequential (or state-full) function.
The expression expr_{1} expr_{2} is an application. The expression expr_{1} must evaluate to a functional value which is applied to the value of expr_{2}.
The expression expr_{1} expr_{2} ... expr_{n} stands for (...(expr_{1} expr_{2}) ... expr_{n}). No evaluation order is specified.
When expr_{1} is a function imported from the host language Objective Caml and expr_{2} is a stream then expr_{1} expr_{2} stands for the point-wise application of expr_{1} to every element of expr_{2}.
The let and let rec constructs bind variables locally. The expression
defines values to be visible in expr.
Recursive definitions of variables are introduced by let rec:
The language provides an alternate form of local definitions written in a reverse order and borrowed from Caml Light. In this way, functions may be defined is a way similar to Lustre. The expression:
has the meaning of:
The operators written infix-op in the grammar can appear in infix position (between two expressions). The operators written prefix-op in the grammar (section 3.9 can appear in prefix position (in front of an expression).
Classical operators provided by Objective Caml (from the Pervasives module) are imported. As for general scalar value imported from the host language, they become stream operators which are applied point-wisely to streams.
The expression pre expr is the delayed stream. expr must be a stream. The clock of the result is the clock of expr. The n-th value of the result is the n−1-th value of expr. Its value at the first instant is undefined.
The binary operator fby is the initialized delay operator. The first value of expr_{1} fby expr_{2} is the first value of expr_{1}. Its n-th value is the n−1-th value of expr_{2}.
The expression last ident denotes a shared memory which contains the last computed value of ident.
expr_{1} -> expr_{2} initializes a stream. The expr_{i} must be streams of the same type and on the same clock. It returns a stream with the same type and clock. The first value of the result is the first value of expr_{1}. Then, the n-th value of the result is the n-th value of expr_{2}.
The expression if expr_{1} then expr_{2} else expr_{3} is the point-wise conditional. expr_{1} must be a boolean stream, expr_{2} and expr_{3} two streams of the same type. The type of the result is the type of expr_{2}. The expressions expr_{i} must be on the same clock. The clock of the result is the clock of expr_{1}. The conditional returns a stream such that its n-th value is the n-th value of expr_{2} if the n-th value of expr_{1} is true and the n-th value of expr_{3} otherwise.
The expression expr_{1} when expr_{2} is the under-sampling operator. expr_{1} must be a stream and expr_{2}, a clock made from a boolean stream. The type of the result is the type of expr_{1}. The expressions expr_{i} must be on the same clock cl. The clock of the result is a sub-clock cl on expr_{2}. This expression returns the sub-stream of expr_{1} defined for all instants where expr_{2} is defined and is true.
The expression merge expr_{1} expr_{2} expr_{3} merges two complementary streams. expr_{1} must be a boolean stream, expr_{2} and expr_{3} two streams of the same type. The type of the result is the type of expr_{2}. If expr_{1} is on clock cl, expr_{2} must be on clock cl on expr_{1} (expr_{2} must be present when expr_{1} is present and true) and expr_{3} must be on clock cl on not expr_{1}. This expression returns a stream such that its n-th value is the n-th value of expr_{2} if the n-th value of expr_{1} is true and the n-th value of expr_{3} otherwise.
The constructions reset
, match/with
, reset
and
automaton
are control-structures which combine equations and
thus belong to the syntactic class of definitions (see
section 3.10).
A derived form belonging to the syntactic class of expressions is also provided. The derived form is useful for textual programming whereas the original one is motivated by the graphical representation of dataflow programs. The derived form is only syntactic sugar for the original form.
The expression await spat do expr awaits for the presence of a signal before executing the expression expr. This construction is a short-cut for the expression:
let | automaton |
| Await -> do unless spat then Go(v) | |
| Go(v) -> do emit o = expr done | |
end in | |
o |
provided o is a fresh name and v is the list of free variables from the signal pattern spat.
The expression match expr with pat_{1} -> expr_{1} | …| pat_{n} -> expr_{n} end is a short-cut for the expression:
let | match expr with |
| pat_{1} -> do o = expr_{1} done | |
… | |
| pat_{n} -> do o = expr_{n} done | |
end in | |
o |
provided o is a fresh name.
The expression reset expr_{1} every expr_{2} is a short-cut for let reset o = expr_{1} every expr_{2} in o, provided o is a fresh name.
The expression automaton state_{1} -> expr_{1} trans_{1} | …| state_{n} -> expr_{n} trans_{n} end is a short-cut for the expression:
let | automaton |
| state_{1} -> do o = expr_{1} trans_{1} | |
… | |
| state_{n} -> do o = expr_{n} trans_{n} | |
end in | |
o |
provided o is a fresh name.
The expression present spat_{1} -> expr_{1} | …| spat_{n} -> expr_{n} end is a short-cut for the expression:
let | present |
| spat_{1} -> do o = expr_{1} done | |
… | |
| spat_{n} -> do o = expr_{n} done | |
end in | |
o |
provided o is a fresh name.