IF and SWITCH: Conditional and Alternative¶
IF: Conditional Actions¶
A conditional action is a construct that performs different actions depending on whether a programmer-specified boolean condition evaluates to true or false. A conditional action takes the form:
if (boolean_expression)
{
... actions launched if the condition evaluates to true ...
}
or
if (boolean_expression)
{
... actions launched if the condition evaluates to true ...
}
else
{
... actions launched if the condition evaluates to false ...
}
Like other actions, a conditional action can be prefixed by a delay. Note that the actions in the if and in the else clause are evaluated as if they are in a group. So, the delay of these actions does not impact the timing of the actions which follow the conditional. For example
if ($x) { 5 print HELLO }
1 print DONE
will print DONE
one beat after the start of the conditional
independently of the value of the condition.
The actions of the “true” (resp. of the “else”) parts of a condition are
members of an implicit group named xxx_true_body
(resp.
xxx_false_body
) where xxx
is the label of the conditional
itself. The attribute of if
are used for these groups.
There are also conditional expressions (sections Conditional Expression and Extended Expression If) that share a similar syntax.
Any kind of Antescofo value can be interpreted as a boolean value, see sections scalar values and data structures.
SWITCH: Alternative Actions¶
Alternative actions extend conditional actions to handle several alternatives. At most one of the alternative will be performed. They are two forms of alternative actions, without and with selector, which differ by the way the alternative to execute is chosen.
There are also alternatives expressions (section switch expression) that share a similar syntax in the context of function definitions.
Alternative Actions without Selectors¶
An alternative action without a selector is simply a sequence of cases guarded by expressions. The guards are evaluated in the sequence order and the action performed is the first case whose guard evaluates to a true value. So :
switch
{
case e₁: a₁
case e₂: a₂
; ...
}
(where e₁
, e₂
... are arbitrary expressions
and a₁
, a₂
... are sequences of actions) can
be rewritten in:
if ( e₁ ) { a₁ }
else
{
switch
{
case e₂: a₂
; ...
}
}
If no guard is true, then no action is performed. Notice that several
actions can be associated to a case
: they are launched
as a group.
Here is an example where the evaluation order matters: the idea is to
rank the value of the variable $x
. The following code
whenever ($PITCH)
{
switch
{
case $PITCH < 80:
$octave := 1
case $PITCH < 92:
$octave := 2
case $PITCH < 104:
$octave := 3
}
}
uses a whenever to set the variable $octave
to some
value each time $PITCH
is updated for a value below
104
.
Note that the actions associated to a case
are evaluated
as if they are in a group. So the eventual delay of these actions does
not impact the timing of the actions which follows the alternative. And
like other actions, an alternative action can be prefixed by a delay.
Alternative Action with a Selector¶
In this form, a selector is evaluated and checked in turn against each guard of the cases:
switch (s)
{
case e₁: a₁
case e₂: a₂
; ...
}
The evaluation proceeds as follows: the selector s is evaluated and then, the result is checked in turn with the result of the evaluation of the e_i:
-
If
eᵢ
evaluates to a function, this function is assumed to be a unary predicate and is applied tos
. If the application returns a true value, the sequence of actionsaᵢ
is performed. -
If
eᵢ
is not a function, the values ofs
andeᵢ
are compared with the operator==
. If it returns a true value, the sequence of actionsaᵢ
is performed.
The evaluation start with e₁
and stops as soon as an
action is performed for one of the eᵢ
. If no guard checks
true, no action is performed.
For example:
switch ($x)
{
case 0:
$zero := true
case @size:
$empty := false
$zero := false
}
checks a variable $x
and sets the variable $zero
to true if $x == 0
or 0.0
(because
0.0 == 0
). It then sets the variable $empty
and $zero
to false if $x
refers to
a non-empty tab or to a non-empty map (because function @size returns
an integer which is 0
only if its argument is an empty
tab or an empty map).