The do statement executes a block and an expression repeatedly until the value of the expression is false. The expression must have type Boolean and a multiplicity upper bound of 1.
Examples
do {
line = file.readNext();
WriteLine(line);
} while (line != endMarker);
do {
reading = sensor.getNextReading();
Record(reading);
} while (!reading.isFinal());
Syntax
DoStatement(s: DoStatement)
= "do" Block(s.body) "while" "(" Expression(s.condition) ")" ";"
Figure 9 53 Abstract Syntax of do Statements
Cross References
-
Expression see Subclause 8.1
-
Statement see Subclause 9.1
-
Block see Subclause 9.1
Semantics
When a do statement is executed, its block is executed first. Then its expression is evaluated. If the result of the expression is true, then the entire do statement is executed again. If the result of the expression is false, the execution of the do statement is complete.
Names
Local names defined before a do statement may be reassigned within the do statement and new local names may be defined within the do statement, in either the condition expression or the block. Local names defined within the condition expression are not available within the body block, but they are available after completion of the do statement, with values assigned as of the last evaluation of the do condition expression.
Local names defined within the body block of a do statement are available within the condition expression of the do statement, with the value as computed on each iteration of the loop. They are also available after completion of execution of the do statement, with the values assigned as of the last evaluation of the do condition expression.
Local names defined before a do statement may be reassigned within the do statement. After completion of execution of the do statement, they have the values assigned as of the last evaluation of the do statement.
9.12for Statements
The for statement executes a block repeatedly while assigning a loop variable to successive values of a sequence.
Examples
for (member in memberList) {
names->add(member.name);
addresses->add(member.address);
}
for (sensor in sensors) {
if ((reading = sensor.reading())->isEmpty()) {
break;
}
if (reading > noiseLimit) {
readings->add(reading);
}
}
for (i in 1..recordCount) {
processRecord(i);
}
//@parallel
for (ActivityEdgeInstance outgoingEdge: this.outgoingEdges) {
outgoingEdge.sendOffer(tokens);
}
// Fast Fourier Transformation computation
//@parallel(Sn_Even,Sn_Odd)
for (lower in S_Lower, upper in S_Upper, root in V) {
//@parallel
{
Sn_Even -> add(lower+upper);
Sn_Odd -> add((lower-upper)*root);
}
}
Syntax
ForStatement(s: ForStatement)
= "for" "(" ForControl(s) ")" Block(s.body)
ForControl(s: ForStatement)
= LoopVariableDefinition(s.variableDefinition)
{ "," LoopVariableDefinition(s.variableDefinition) }
LoopVariableDefinition(v: LoopVariableDefinition)
= Name(v.variable) "in" Expression(v.expression1)
[ ".." Expression(v.expression2) ]
| TypeName(v.typeName) Name(v.variable) ":"
Expression(v.expression1) (typeIsInferred=false)
Figure 9 54 Abstract Syntax of for Statements
Cross Reference
-
Name see Subclause 7.5
-
Expression see Subclause 8.1
-
QualifiedName see Subclause 8.2
-
Statement see Subclause 9.1
-
Block see Subclause 9.1
Semantics
Loop Variables
A for statement defines one or more loop variables that are given successive values from sequences during the execution of the loop. A loop variable definition in a for statment is thus the assigned source for the loop variable name so defined within the for statement. The name of a loop variable must be unassigned before the for statement, may not be otherwise assigned within the for statement and is considered unassigned after the for statement.
There are two forms for a loop variable definition.
In the first form, the type of the loop variable is given implicitly by the expression from whose result the loop variable takes values. For example, suppose that the name memberList has the type Member and a multiplicity of [0..*] in the statement
for (member in memberList) {
names->add(member.name);
addresses->add(member.address);
}
The loop variable member is then implicitly given the type Member, the same type as that of the name expression memberList.
However, collection conversion may be performed on the expression in a loop variable definition. That is, if the type of the expression is a collection class (see Subclause 11.6) and the multiplicity upper bound of the expression is no greater than 1, then the operation toSequence is implicity called on the expression to produce the sequence of values for the loop variable. The loop variable is then the type of the result of the toSequence call (i.e., the element type of the collection). Thus, the example above would still be legal if the type of memberList was, e.g., List.
In the second form, the type of the loop variable is declared explicitly. For example, the following statement is semantically equivalent to the example given above:
for (Member member: memberList) {
names->add(member.name);
addresses->add(member.address);
}
In this form, the declared type of the loop variable normally must conform to the type of the expression (see Section 8.2 for the definition of type conformance). However, if collection conversion applies to the expression, then the declared type must conform to the element type of the collection.
NOTE. The second form of loop variable definition has a similar syntax to that used in a “for each” statement in Java.
A loop variable definition of the form var in expr1..expr2 is a shorthand for var in Integer[]{expr1..expr2} (see Subclause 8.3.15 on ranges in sequence construction expressions). In this case, both expressions must have type Integer and a multiplicity upper bound of 1. A loop variable so defined takes on sequential integer values in each loop iteration, beginning with the value given by expr1 and ending with the value given by expr2. If the second value is less than the first, then the for loop execution completes with no iterations.
Iterative Execution
When a for statement is executed, the expressions in its loop variable definitions are evaluated concurrently. If the result for the first variable is a sequence of at least one value, and the for statement has no while condition expression, then the block of the for statement is executed once for each value in the sequence. On each such execution, the local names of the loop variables within the block have corresponding values from the sequences resulting from the evaluation of the expressions in their definitions.
Note that the sequences for all the loop variables in a specific execution of a for statement should have the same size. However, if this is not true, it is the sequence for the first variable that controls the execution. If another variable has a sequence of a larger size than the first variable, then the additional values will be ignored. If it has a sequence of a smaller size, then the variable will be empty on iterations after all values in its sequence have been used. For this reason, the first loop variable has the multiplicity [1..1], while any other loop variables are given the multiplicity [0..1].
NOTE. At the minimum conformance level (see Subclause 2.1), a for statement is allowed to have only one loop variable.
By default, the executions of the body block of a for statement occur in sequential iterations. Values are taken from the sequence for each loop variable in order.
Since a loop variable expression is only evaluated once, any local names defined in it have the values assigned during that evaluation for all executions of the body block of the for statement, unless reassigned within that block.
Local names defined within the body block of a for statement are prohibited from being accessed outside the for statement, since they could be uninitialized if the for statement does not execute its body. Local names defined within an expression in a loop variable definition are available after completion of execution of the for statement.
Parallel Execution
If a for statement is preceded by a @parallel annotation (see Subclause 9.2), then the executions of the body block of the for statement occur concurrently rather than sequentially.
A @parallel annotation may include a list of names. Each such name must be already assigned before the body of the for statement, with a multiplicity of [0..*]. They may then be used within the body block of the for statement to collect values across the concurrent executions of that block (any prior assigned values are lost). As such, these names may only appear within the for statement as the target argument (i.e., argument to the first parameter) for the add function from the Alf CollectionsFunctions library package (see Subclause 11.5).
For example, consider the following piece of a Fast Fourier Transform (FFT) computation, using an iterative for statement.
Sn_Even = Integer[]{};
Sn_Odd = Integer[]{};
for (lower in S_Lower, upper in S_Upper, root in V) {
Sn_Even -> add(lower+upper);
Sn_Odd -> add((lower-upper)*root);
}
This is computationally correct, but it forces sequential execution of what is essentially a parallel algorithm. This can be corrected by inserting appropriate @parallel annotations:
Sn_Even = Integer[]{};
Sn_Odd = Integer[]{};
//@parallel(Sn_Even,Sn_Odd)
for (lower in S_Lower, upper in S_Upper, root in V) {
//@parallel
{
Sn_Even -> add(lower+upper);
Sn_Odd -> add((lower-upper)*root);
}
}
The listing of the names Sn_Even and Sn_Odd in the @parallel annotation is required so that the add operation invocations continue to be permitted within the for statement.
NOTE. The normal behavior invocation notation (see Subclause 8.3.9) may also be used for the add function instead of the sequence operation notation (see Subclause 8.3.17). For example “Sn_Even->add(lower+upper);” may instead be written “add(Sn_Even, lower+upper);”. The behavior invocation notation is available at the minimum conformance level, while the sequence operation notation is not available until the full conformance level (see also Subclause 2.1 on syntactic conformance levels).
If, after the loop variable definitions of a parallel for statement, a name has an assigned source, then it must have the same assigned source after the block of the for statement. Other than for names defined in the @parallel annotation of the for statement, the assigned source for such names is the same after the for statement as before it. Any names defined in the @parallel annotation have the for statement itself as their assigned source after the for statement.
Unlike the case of an iterative for statement, names defined before a parallel for statement may not be reassigned within the statement, unless they are listed in the @parallel annotation for the statement. As in the iterative case, any names defined within the body of a parallel for statement are not available outside of the for statement.
Share with your friends: |