.sh 1 "Sequential Statements"
.(b
statement  ::=  sequential_statement   #   interaction_statement
.)b
.(b
sequential_statement  ::=  |1skip_statement   #   stop_statement   #   assignment_statement   #
                           /1increment_statement   #   decrement_statement   #
                           /1if_statement   #   do_statement   #   for_all_statement   #
                           /1exit_statement   #   next_statement
.)b
.lp
Sequential statements compute values and control the
flow of execution within procs and processes.
The kinds of sequential statements resemble those found
in other imperative languages, but their form is somewhat
different to make them more compact and also similar in
form to the interaction statements.
Interaction statements enable procs and resources to communicate
and synchronize; these are discussed in Section 6.
.sh 2 "Skip"
.(b
skip_statement  ::=  @skip@
.)b
.lp
The @skip@ statement has no effect and terminates immediately.
It is the SR ``empty'' statement and is typically used in guarded commands
to indicate that there is no action to take when the associated
guard is true.
.sh 2 "Stop"
.(b
stop_statement  ::=  @stop@  exit_code{{o}}
.)b
.(b
exit_code  ::=  (  integer_expression  )
.)b
.lp
The @stop@ statement immediately stops execution of an
entire program, even if there are active processes.
If an exit code is given, it is returned as the exit status
to the command that started program execution;
the default exit status is zero.
.sh 2 "Assignment"
.(b
assignment_statement  ::=  variable  @:=@  expression
.)b
.(b
increment_statement  ::=  variable  @++@
.)b
.(b
decrement_statement  ::=  variable  @--@
.)b
.(b
swap_statement  ::=  variable  @:=:@  variable
.)b
.(b
variable  ::=  denotation
.)b
.lp
An assignment statement evaluates an expression and assigns
its value to a variable.\**
.(f
\**The order in which the address of the variable and the expression
are evaluated is not defined.
Thus, there could be side-effects between the expression and a
subscripted variable that invokes a function during subscript evaluation.
.)f
The expression and variable must be compatible, as described
in Section 7.6.
.pp
The increment and decrement statements are special assignment statements
that may be used with ordered types and with pointers.
An increment or decrement of an ordered type assigns the next or
previous value of that type, if there is one.
An increment or decrement of a pointer causes it to point to the
successor or predecessor in memory of its current target.
For example, a pointer to an array can be used to step through the array.
Variables of type @ptr any@ may not be incremented or decremented since the
size of the target is not known.
As always with pointer variables, the increment and decrement
statements must be used with care.
.pp
In increment and decrement statements,
the variable denotation is evaluated only once.
Thus, these statements are abbreviations
for regular assignment statements only if evaluating the
variable denotation has no side effects.
.pp
A swap statement exchanges the values of two variables,
which must have the same type.
.\" --- this is not true, at least at the moment ---
.\" The left-side variable is evaluated first, then the
.\" right side.
.PS L
%Examples:
.sp .5
	i := i+1
	i++        # same effect as above
	x :=: y    # swap x and y
	str := "hi" | | " there"
	char_buf[1:N] := (char_buf[2:N], ' ')   # left shift, blank fill
	bool_matrix[i,1:N] := bool_matrix[j,1:N]   # move row j to row i
	position := differ(string1,string2)
	sc.push := null   # disallow push on stack pointed to by sc
.PE
.sh 2 "Alternation"
.(b
if_statement  ::=  @if@  guarded_command  @[]@{{+}}  else_command{{o}}  @fi@
.)b
.(b
guarded_command  ::=  boolean_expression  @->@  block
.)b
.(b
else_command  ::=  @[] else@  @->@  block
.)b
.lp
The @if@ statement combines aspects of @if-then@,
@if-then-else@, and @case@ statements.
It is similar but not identical to Dijkstra's guarded command
based @if@ statement.
An @if@ statement is executed by evaluating the boolean expressions,
each at most once,
until one evaluates to true or all evaluate to false;
the order in which the expressions are evaluated is non-deterministic.
If some boolean expression is true,
the block in the corresponding command is executed;
when that block terminates, the @if@ statement terminates.
If no boolean expression is true,
the @if@ statement terminates immediately.
.pp
The optional @else@ command is selected if none of the other boolean
expressions is true;
@else@ is thus an abbreviation for the negation
of the disjunction of the boolean expressions in the other guards.\**
.(f
\**However, these expressions are not re-evaluated.
.)f
Note that an @if@ statement ending with
`@[] else -> skip@'
is equivalent to the same statement without the @else@ command.
.PS L
%Examples:
.sp .5
	if x<=y -> minimum := x
	[] y<=x -> minimum := y
	fi

	# if ch is a lower case ASCII letter, convert it to upper case
	if ch>='a' and ch<='z' -> ch := char(int(ch)-32) fi
.PE
.sh 2 "Iteration"
.(b
do_statement  ::=  @do@  guarded_command  @[]@{{+}}  else_command{{o}}  @od@
.)b
.(b
for_all_statement  ::=  @fa@  quantifier  @,@{{+}}  @->@   block  @af@
.)b
.(b
exit_statement  ::=  @exit@
.)b
.(b
next_statement  ::=  @next@
.)b
.(b
quantifier  ::=  bound_variable  @:=@  expression  direction  expression  such_that{{o}}
.)b
.(b
direction  ::=  @to@   #   @downto@
.)b
.(b
such_that  ::=  @st@  boolean_expression
.)b
.lp
The @do@ statement is used for indefinite iteration.
On each iteration,
the boolean expressions are evaluated
until one evaluates to true or all evaluate to false;
the order in which the expressions are evaluated is non-deterministic.
If some boolean expression is true,
the block in the corresponding command is executed,
then execution of the @do@ statement is repeated.
A @do@ statement terminates when all its boolean expressions are false
or an @exit@ statement is executed (see below).
As in the @if@ statement,
the optional @else@ command is selected if none
of the other boolean expressions are true.
Note that a @do@ statement containing an @else@ command will
terminate only if @exit@ or @return@ is executed within the loop.
.pp
The for-all statement is used for definite iteration.
It contains one or more quantifiers, which implicitly declare
bound variables.
The scope of these bound variables is the enclosing for-all statement;
thus, they can be used within the for-all statement from
the point of their definition to the end of the statement.
The types of the bound variables
are derived from  the types of the corresponding initial and final
expressions, which must be matching ordered types.
.pp
A quantifier specifies that the remainder of the for-all
statement is to be evaluated for each value in the range
from the specified initial value up to (@to@) or down to (@downto@)
the specified final value.
A bound variable usually takes on all values in this range;
if the optional such that clause is present, the bound
variable only takes on those values for which the
boolean expression following @st@ evaluates to true.
Thus, the block within a for-all statement is executed for each
combination of values of the bound variables, or until
an @exit@ statement is executed.
Note that the right-most bound variable varies the most rapidly,
then the next to right-most, etc.
Initial and final expressions are evaluated as needed,
and the boolean expressions following
@st@ are re-evaluated before each iteration.
As a concrete example, the statement
.PS
fa i := 1 to N st i != 5, j := i+1 to N -> \fRblock\fP af
.PE
is simply an abbreviation for
.PS
i := 1
do i <= N -> 
    if i != 5 -> 
        j := i+1
        do j <= N -> \fRblock\fP
                     j++
        od
    fi
    i++
od
.PE
In the translation, @i@ and @j@ are new variables;
@i@'s scope is the outer @do@ loop, @j@'s is the inner @do@ loop.
Also, the block must not contain @exit@ or @next@.
Bound variables may be modified within the loop body, although
it is generally inadvisable to do so.
.pp
The @exit@ statement is used to force early termination
of the smallest enclosing iterative statement.
The @next@ statement is used to force return to the loop control
of the smallest enclosing iterative statement.
Within a @do@ statement,
execution of @next@ causes the @do@ statement to be re-executed.
Within a for-all statement,
execution of @next@ causes the next combination
of bound variable values to be assigned;
if no values remain, the statement terminates.
The @exit@ and @next@ statements may only appear within loop bodies
or within the @co@ statement (see Sec. 6.4).
If @exit@ or @next@ is executed within a conditional or input
statement that is itself within the smallest enclosing iterative
or @co@ statement, the conditional or input statement is also
forced to terminate.
.PS L
%Examples:
.sp .5
	# skip over blanks in string
	pos := 1
	do pos<=length(str) & str[pos]=' ' -> pos++ od

	# compute greatest common divisor of positive x and y
	X := x;  Y:= y
	do X<Y -> Y := Y-X
	[] Y<X -> X := X-Y
	od
	gcd := X

	# count the number of 0's in vector v
	fa i := lb(v) to ub(v) st v[i]=0 -> cnt++ af

	# transpose matrix m[1:N,1:N]
	fa i := 1 to N, j := i+1 to N -> m[i,j] :=: m[j,i] af
.PE
.PS L
	# print counts for upper-case letters in char_count[char]
	fa c := 'A' to 'Z' ->
	    write("occurrences of ",c,":  ",char_count[c])
	af
.PE
