This is one of the
STIPPLE Documentation pages.
STIPPLE Statements
With the single exception of the assignment
statement, all STIPPLE statements start with
a keyword. This permits easy extensions to
the STIPPLE language.
The syntax for a statement is:
-
statement
-
nesting_statement
-
evaluate_statement
-
conditional_statement
-
iteration_statement
-
miscellaneous_statement
STIPPLE uses indentation to perform statement
block nesting.
Nesting Statements
The syntax for nesting statements are:
-
nesting_statement
-
block_statement
-
with_statement
-
variadic_with_statement
The block Statement
The syntax for the block statement is:
-
block_statement
-
block eol
nested_statements
-
nested_statements
-
indent
{ statement }+
outdent
The block statement introduces a grouping of
statements. The block statement is used to
either improve readability and/or provide a
scope for a handle statement.
The with Statement
The syntax of the with statement is:
-
with_statement
-
with expression eol
nested_statements
-
nsested_statements
-
indent
{ statement }+
outdent
The with statement evaluates its expression and
introduces a nested level of statements which
have additional variables defined. Let the type
of the with expression be T. A variable named V
of type VT is introduced to the nested scope if
the procedures T@V_get and T@V_set exist with
the following signatures:
procedure T@V_get
takes T
returns VT
procedure T@V_set
takes T
v1 V
{Variable conflicts need to be discussed.}
{This is a horrible example.}
Each time one of these variables is accessed, the
appropriate set or get routine is invoked. For example:
...
define point
record
x unsigned
y unsigned
...
procedure transpose
takes
point1 point
with point1
x, y := y, x
is equivalent to
...
temp:: point := point1
temp.x, temp.y := temp.y, temp.x
...
The variadic_with Statement
The syntax of the variadic_with statement is:
-
variadic_with_statement
-
variadic_with expression eol
nested_statements
-
nested_statements
-
indent
{ statement }+
outdent
The variadic_with statement is used to access the
variadic records of a variadic procedure. As such,
it can only be used inside of procedures with a
variadic clause. Let N be the procedures variadic
size variable value. Let I be the value of the
variadic_with expression of type unsigned.
I must be a non-negative number that is less than N.
The signal bounds is raised if I is greater than
or equal to N. The nested statements of the
variadic_with statement can directly access the
I'th variadic record, where the first variadic
record index is zero. Nested variadic_with
statements are illegal.
The evaluate Statement
The syntax for the evaluate statement is:
-
evaluate_statement
-
{ evaluate }
{ assignable_expressions
assign_operator }
value_expressions eol
-
assignable_expressions
-
assignable_expression ,...
-
value_expressions
-
assign_operator
-
:=
-
:+=
-
:-=
-
:*=
-
:/=
-
:%=
-
:&=
-
:|=
-
:^=
-
:<<=
-
:>>=
The evaluate statement computes one or more
expression values and assigns them to one or
more assignable expressions. The evaluate
keyword is optional and should only be used
when the first assignable expression starts
with variable is the same as another keyword;
the compiler will generate a warning message
if the evaluate keyword is used when it is
unnecessary. The types of the expression
values must match the corresponding types
in the assignable expressions.
The evaluate statement is the most commonly
used one for defining new variables.
Some example assignment statements are shown below:
a:: integer # Illegal, expression returns a value
b:: integer := +17
c:: integer := a + b
d:: integer := a + d # Illegal, d is not in scope
c, d := d, c # Swap c with d
evaluate a := 12 # Illegal, a is not a keyword
evaluate if:: integer := 17 # Define variable named if
if := 42 # Illegal, variable confused with keyword if
evaluate if := 123
evaluate evaluate:: integer # Define variable named evaluate
evaluate evaluate := 456
print(`Hello world') # Invoke a routine with no return values.
Conditional Statements
The syntax for a conditional statement is:
-
conditional_statement
-
if_statement
-
switch_statement
-
extract_statement
There are three kinds of conditional statements -
the if, switch, and extract statements.
The if Statement
The syntax for an if statement is:
-
if_statement
-
if logical_expression eol
nested_statements
{ else_if_clause }*
{ else_clause }
-
else_if_clause
-
else_if logical_expression eol
nested_statements
-
else_clause
-
else eol
nested_statements
-
logical_expression
-
nested_statements
-
indent
{ statement }+
outdent
The if statement evaluates the boolean expressions
in order until one of the expressions evaluates to
true@logical, at which time control is transferred
to the nested statements immediately following the
true boolean expression. If all expressions evaluate
to false@logical and there is an else clause, control
is transferred to the statements immediately
following he else. Unless there is an explicit
control transfer statement, upon executing all
of the appropriate nested statements control is
transferred to the statement immediately following
the if statement. In particular, at most one set
of nested statements is ever executed for an if
statement.
The switch Statement
The syntax for the switch statement is:
-
switch_statement
-
switch enumeration_expression eol
indent
{ case_clause }*
{ case_default_clause }
outdent
-
enumeration_expression
-
case_clause
-
case constant_enumeration_expression
,... eol
nested_statements
-
case_default_clause
-
case_default eol
nested_statements
-
nested_statements
-
indent
{ statement }+
outdent
-
constant_enumeration_expression
-
The switch statement evaluates the enumeration
expression and transfers control to nested
statements under to the case or case_default
clause that matches enumeration expression.
If no match occurs, control is immediately
transferred to the statement following the
switch statement. A case clause will match
any of the expressions that immediately
follow it. If present, the case_default
clause will match all expressions not
explicitly mentioned in another case clause.
The compiler will emit an error if any of
the constant enumeration expressions have
duplicate values.
The compiler enforces the requirement that
all possible expression values must have a
matching case or case_default clause. Thus,
unless the case clauses completely cover all
expression values, a case_default clause is
required; the compiler will emit an error
otherwise. The do_nothing statement is used
if there is no code that needs to be executed
for a case_default.
The extract Statement
The syntax for the extract statement is:
-
extract_statement
-
extract extract_variable :=
variant_expression eol
indent
{ tag_clause }*
{ tag_default_clause }
indent
-
extract_variable
-
variant_expression
-
tag_clause
-
tag constant_enumeration_expression
,... eol
nested_statements
-
tag_default_clause
-
tag_default eol
nested_statements
-
nested_statements
-
indent
{ statement }+
outdent
-
constant_enumeration_expression
-
The extract statement dispatches control
depending the tag value of the variant
expression. Control is transferred to the
first statement in the matching tag or
tag_default clause. All of the tag names
must be of the same type. The default
clause must be supplied if the tag clauses
do not completely enumerate all of the
possible variant tag values.
{More description goes here.}
Iteration Statements
The syntax of an iteration statement is:
-
iteration_statement
-
loop_statement
-
break_statement
-
continue_statement
-
while_statement
-
until_statement
-
if_first_statement
-
if_continue_statement
-
if_break_statement
-
if_done_statement
-
for_statement
-
next_statement
-
finalize_statement
{The iteration statement needs quite a bit more work!}
{The loop_end statement is not described.}
The loop Statement
The syntax for a loop statement is:
-
loop_statement
-
loop { loop_label } eol
nested_statements
{ finish_clause }
-
loop_label
-
nested_statements
-
indent
{ statement }+
outdent
-
finish_clause
-
finish eol
nested_statements
The loop statement sets up an infinite loop
that repeatably executes its nested statements
in sequential order. When the last nested
statement is executed, control is automatically
returned to the first statement. The continue,
break, while, until, iterator, and for statements
(described below) are used to modify loop control
flow. If a finish clause is present, the nested
statements that follow are executed when the
loop terminates.
The optional loop label is used by the break
and continue statement to name a loop statement.
In general, loop labels are only used when it
necessary for a break or continue statement
to name an outer loop from inside an inner
loop. The scope of a loop label is all of the
nested statements following the loop keyword,
but not including the nested statements
following the optional finish clause. While
a procedure is permitted to have two loop
statements with the same loop label, it is
illegal for their scopes to overlap in any way.
The break Statement
The syntax for the break statement is:
-
break_statement
-
loop_label
-
The break statement, with no loop label, causes
the current inner-most loop to terminate. The
break statement, with a loop label, causes the
loop named loop_label to terminate. It is an
error for a break statement to reference a loop
label outside of its scope. An error message is
generated for any break statement that does not
occur inside the nested statements of a loop
statement.
The continue Statement
The syntax for the continue statement is:
-
continue_statement
-
continue {
loop_label } eol
-
loop_label
-
The continue statement, with no loop label,
transfers control to the first statement in
the current inner-most loop. The continue
statement, with a loop label, transfers
control the first statement of the named
loop. It is an error for a continue statement
to reference a loop label outside of its
scope. An error message is generated for
any continue statement that does not occur
inside the nested statements of a loop
statement.
The while Statement
The syntax for the while statement is:
-
while_statement
-
while logical_expression eol
-
logical_expression
-
The while statement terminates the current loop
if its boolean expression evaluates to
false@logical; otherwise, control continues
to the next statement. An error message is
generated for any while statement that does
not occur inside the nested statements of
a loop statement.
The while statement is equivalent to:
if !(boolean_expression)
break
The until Statement
The syntax for the until statement is:
-
until_statement
-
until logical_expression eol
-
logical_expression
-
The until statement terminates the current
loop if its boolean expression evaluates to
true@logical; otherwise, control continues
to the next statement. An error message is
generated for any until statement that does
not occur inside the nested statements of
a loop statement.
The until statement is equivalent to:
if boolean_expression
break
The if_first Statement
The syntax for the if_first statement is:
-
if_first_statement
-
if_first eol
nested_statements
-
nested_statements
-
indent
{ statement }+
outdent
The if_first statement will execute its nested
statements only on the first iteration of a
loop. For all subsequent loop iterations, the
nested statements are not executed. An error
message is generated for any if_first statement
that does not occur inside the nested
statements of a loop statement.
The if_continue Statement
The syntax for the if_continue statement is:
-
if_continue_statement
-
if_continue eol
nested_statements
-
nested_statements
-
indent
{ statement }+
outdent
The if_continue statement will execute its
nested statements only on the second and
subsequent loop iterations. The nested
statements are not executed for the first
loop iteration. An error message is generated
for any if_continue statement that does not
occur inside the nested statements of a loop
statement.
The if_break Statement
The syntax for the if_break statement is:
-
if_break_statement
-
if_break eol
nested_statements
-
nested_statements
-
indent
{ statement }+
outdent
The if_break statement will execute its nested
statements only if its associated loop was
explicitly terminated by a break statement.
An error message is generated for any if_break
statement that does not occur inside the nested
statements following a loop_end clause.
{Be more specific.}
The if_done Statement
The syntax for the if_done statement is:
-
if_done_statement
-
if_done eol
nested_statements
-
nested_statements
-
indent
{ statement }+
outdent
The if_done statement will execute its nested
statements only if its associated loop was not
explicitly terminated by a break statement.
An error message is generated for any if_done
statement that does not occur inside the nested
statements following a loop_end clause.
{Be more specific.}
The for Statement
{Iterators are quite a bit more complicated for
STIPPLE than they are for CLU. The reason for
this complexity is because in CLU, a break
statement does not return control back to
the iterator. This means that the iterator
can not free up any resources that it might
be using, such as a lock. In STIPPLE, a
solution to this problem is highly desired.{
The syntax for the for statement is:
-
for_statement
for { yield_assign }
I>iterator_expression
{ as iterator_name
} eol
indent
{ for_else_clause }
{ statements }+
outdent
-
yield_assign
-
assignable_expression ,...
assign_operator
-
iterator_name
-
iterator_expression
-
for_else_clause
-
for_else eol
nested_statements
-
nested_statements
-
indent
{ statement }+
outdent
-
assign_operator
-
:=
-
:+=
-
:-=
-
:*=
-
:/=
-
:%=
-
:&=
-
:|=
-
:^=
-
:<<=
-
:>>=
The for statement is used to invoke an iterator
and obtain successive yield values from it. It
is an error for a for statement to occur outside
the nested statements of a loop statement. The
iterator expression is only evaluated the first
time a for statement is executed in order to
initialize an iterator. Each time the for
statement is executed, the iterator is
started/resumed until it executes a yield
statement, at which time the yielded values
are assigned to the assignable expressions.
The iterator types must match the assignable
expression types. Whenever the iterator
terminates by executing a return statement,
the loop is terminated and control is
transferred to the first statement of the
loop_end clause, if present.
The as clause is used to provide a name for
the iterator. The iterator name is used in
the next and finalize statements. The finalize
statement is used to access any values
returned by the iterator. The next statement
is a shortened version of the for statement
that can only resume an iterator. The scope
of the iterator name is all of the nested
statements in the current loop, including
the nested statements following the loop_end
clause, if present. While a procedure is
permitted to have two iterator names with
the same name, their scopes are not
permitted to overlap.
{What about a for statement in an if statement.}
{Describe the for_else statement.}
The next Statement
The syntax for the next statement is:
-
next_statement
-
next { assignable_expression
,... assign_operator }
iterator_name eol
{ next_else statement }
-
iterator_name
-
assign_operator
-
:=
-
:+=
-
:-=
-
:*=
-
:/=
-
:%=
-
:&=
-
:|=
-
:^=
-
:<<=
-
:>>=
The next statement is a shortened version of
the for statement that can only resume the
named iterator until the next time it executes
a yield statement, at which time, it assigns
the resulting yield values to the specified
assignable expressions in the next statement.
If the iterator terminates by executing a
return statement, the loop is terminated.
If the named iterator is not active, the
next statement has not effect.
{Describe the next_else statement.}
The finalize Statement
The syntax for the finalize statement is:
-
finalize_statement
-
finalize {
assignable_expression
,...
assign_operator }
iterator_name eol
-
iterator_name
-
assign_operator
-
:=
-
:+=
-
:-=
-
:*=
-
:/=
-
:%=
-
:&=
-
:|=
-
:^=
-
:<<=
-
:>>=
The finalize statement is used to obtain
the return values from an iterator that
executed a return statement. The returned
values are assigned to the specified
assignable expressions. The iterator
return types must match the assignable
expression types. If the named iterator
did not execute a return statement, the
finalize statement has no effect. The
finalize statement can only occur in
the nested statements of an loop_end
clause.
Miscellaneous Statements
The syntax for the miscellaneous statements are:
-
miscellaneous_statement
-
return_statement
-
yield_statement
-
signal_statement
-
raise_statement
-
handler_statement
-
resignal_statement
-
go_to_statement
-
label_statement
-
do_nothing_statement
The return statement
The syntax for the return statement is:
-
return_statement
-
return { value_expression
,... }
The return statement terminates the current
procedure and transfers control back to the
calling procedure. The specified expression
values are returned as the procedure return
values. The procedure return types must
match the expression value return types.
The yield statement
The syntax for the yield statement is:
-
yield_statement
-
yield { value_expression
,... } eol
{ yield_finalize statement }
The yield statement can only occur in an iterator.
The yield statement suspends the iterator and
returns control back to the procedure that
invoked the iterator. When the invoking procedure
resumes the iterator, it will continue at the
statement following the yield statement. The
specified expression values are yielded as
the iterator yield values. The iterator yield
types must match the expression value yield types.
If the loop containing the iterator is terminated
in any way (e.g. via a break statement), all
active iterators execute the statements in loop
terminate clause associated with the last yield.
These statements are expected to clean up any state.
{Describe yield_finalize clause.}
The signal statement
The syntax for the signal statement is:
-
signal_statement
-
signal signal_name
{ value_expression
,... } eol
-
signal_name
-
The signal statement can occur anywhere in a
routine. The signal statement transfers control
to a signal handler in the calling routine.
The raise statement
The syntax for the raise statement is:
-
raise_statement
-
raise signal_name
{ value_expression
,... } eol
-
signal_name
-
The raise statement is just like the signal
statement except that control is transferred
to the closest handler within the same procedure.
The handler Statement
The syntax for the handler statement is:
-
handler_statement
-
handler
{ assignable_expression
... assign_operator
} signal_name eol
nested_stateents
-
nested_statements
-
indent
{ statement }+
outdent
-
assign_operator
-
:=
-
:+=
-
:-=
-
:*=
-
:/=
-
:%=
-
:&=
-
:|=
-
:^=
-
:<<=
-
:>>=
{This seems wrong!}
The handler statement catches signals. Any signal
values are assigned to the specified assignable
expressions. The signal types must match the
assignable expression types. The scope of the
handler is:
-
all statements at the same nesting level
-
all statements at a deeper nesting level
that do not have a handler with same the
signal name.
It is an error to have two handlers with the same
name in the same statement block.
The resignal Statement
The syntax for the resignal statement is:
-
resignal_statement
-
signal_name
-
The resignal statement is equivalent to:
handler helper_variable1, ... := signal_name
signal signal_name helper_variable1,...
The go_to statement
The syntax for the go_to statement is:
-
go_to_statement
-
label_name
-
The go_to statement immediately transfers
control to the specified label statement.
The go_to statement can only transfer control
to a label that is in scope; thus, a go_to
statement can not transfer control to a label
that is at a deeper nesting level.
The label statement
The syntax for the label statement is:
-
label_statement
-
label label_name
{ label_count
} eol
-
label_count
-
The label statement is target of one or more go_to
statements. The optional label count specifies the
number of go_to statements that reference the named
label. The compiler generates an error message if
the actual number of go_to statements does not
exactly equal the specified integer.
The do_nothing statement
The syntax for the do_nothing statement is:
-
do_nothing_statement
-
The do_nothing statement does nothing except fill
a statement location. It is meant to be used in
situations where the STIPPLE grammar requires as
statement, but the application semantics do not
require anything to be executed.
From here you can go to either the next chapter on
STIPPLE Expressions or back to the
table of contents.
Copyright (c) 1991 --
Wayne C. Gramlich. All rights reserved.