Statements denote actions. There are simple and
compound statements. Simple statements do not consist of any
parts that are statements themselves. They are the assignment,
procedure call, return, break, continue, throw, and the wait
statements. Analogous to the C language the last symbol of a Dino
simple statement is semicolon ;
. Compound statements
consists of parts that are statements themselves. They are used to
express sequencing, exception handling, conditional, and repetitive
execution.
There is also the empty statement in Dino. It denotes no action. The empty statement is included in Dino for convenience.
ExecutiveStmt = ";"
Example: Usage of an empty statement in a for-statement:
for (i = 0; a[i] == 0; i++)
;
A block-statement is simply a block and can used to group statements into one statement and/or describe local declarations. For details on how the block is executed see section Declaration and Scope Rules.
ExecutiveStmt = BlockStmt
BlockStmt = Block
Example: Usage of a block-statement in a for-statement:
sum = 0;
for (i = 0; i < #a; i++)
{
var value = a[i];
if (value > 0)
sum += value;
}
Assignment-statements are used to change variable values or element
values of a structured value which are referred through a designator
(see sub-section Designator in section Expressions.
The designator can not denote a final variable (see section
Variable Declaration). You can not change the element value
of an immutable value (see section Types and Values). In
this case exception immutable
is generated. Assignment to a
table element has a side effect, the element key becomes immutable.
A simple assignment statement looks like Designator = Expr;
.
That means that the expression value is assigned to variable or
element of structured type value denoted by the designator. For the
convenience of C programmers there are also the Dino assignments
Designator op= Expr;
, Designator++;
,
++Designator;
, Designator--;
, and
--Designator;
. They are analogous correspondingly to
Designator = Designator op Expr;
, Designator = Designator
+ 1;
, and Designator = Designator - 1;
. The only
difference is in the fact that the designator is evaluated only once,
not twice as in the analogous form. It is important to know if you
have side effects in the statement.
A special construction Designator <=> Designator;
swaps values
of the designators.
ExecutiveStmt = Designator Assign Expr ";"
| Designator ("++" | "--") ";"
| ("++" | "--") Designator ";"
| Designator <=> Designator ";"
Assign = "="
| "*="
| "/="
| "%="
| "+="
| "-="
| "@="
| "<<="
| ">>="
| ">>>="
| "&="
| "^="
| "|="
Examples:
v = [10, 20];
i = 1;
i++;
--i;
i *= 20;
v [0] <=> v [1];
A call-statement is used to call a function, a thread-function, or a class. It works analogous to the call in an expression (see sub-section Calls in section Types and Values). The single difference is in that a call-statement throws away the call's result.
ExecutiveStmt = Designator ActualParameters ";"
Examples:
putln ("percent=" @ percent @ "%");
newthread ();
The Dino if-statement is analogous to the C language one. First, the
expression after if
is evaluated and arithmetic conversion is
done to it. The value should be an integer or a floating-point
number, otherwise the exception optype
is generated. If the
value is nonzero the first statement is executed, otherwise the
statement after else
is executed (if any). The problem with
dangling else is resolved analogous to the C language --
else
is associated with the closest if
.
ExecutiveStmt = if "(" Expr ")" Stmt [ else Stmt ]
Examples:
if (i < 0) i = 0;
if (i < j) return -1; else if (i > 0) return 1; else return 0;
The Dino for-statement is analogous to the C language one. The statement is executed in the following way.
optype
is generated.break
in the body. The body can be finished
by execution of statement continue
. In this case, the
for-statement execution continues with the step 4.
ExecutiveStmt = for "(" Stmt ForGuardExpr ";" Stmt ")" Stmt
ForGuardExpr = [Expr]
Examples:
for (i = 0; i < 10; i++;) sum += v [i];
for (i = 0; i < 10; i++) sum += v [i];
for ({sum = 0; i = 0;} i < 10; i++) sum += v [i];
This statement is used to execution of the foreach-statement body (the
statement) for all keys of table which is value of the expression.
The expression value should be a table. If this is not true,
exception keyop
is generated. The current key value on each
iteration is assigned to the designator. The order in which the key
values are assigned on each iteration is undefined. One iteration can
be finished with the aid of the statement continue
and a
foreach-statement can be finished by execution of statement
break
.
ExecutiveStmt = for "(" Designator in Expr ")" Stmt
Examples:
putln ("The table is");
for (k in t) {
put ("key=");
print (k);
put (", element=");
println (t{k});
}
Statements break
and continue
are used
correspondingly to finish execution of the closest-containing for- or
foreach-statement covering the statement and to finish one iteration
of the body of the for- or foreach-statement. These statement can be
used only inside a for- or foreach-statement.
ExecutiveStmt = break ";"
| continue ";"
Examples:
for (i = 0; i < 10; i++) {
if (ind [i] < 0)
continue;
val = v [ind[i]];
}
for (i in t)
if (t{i} == elval)
break;
Return-statement is used to finish execution of a function, a thread, or class block. The statement corresponds to the closest-containing function, thread-function, or class covering the statement, so the return-statement can be placed only in a function, a function-thread, or a class. The expression in a return-statement can be given only for functions. In this case, the expression value will be the value of the function call (instead of the default result value nil).
ExecutiveStmt = return [ Expr ] ";"
Examples:
return;
return [10, 2:0]
This statement generates an exception which is given by value of the
expression. The expression should evaluate to an object of
predeclared class except
or an object of a class declared
somewhere in predeclared class except
. If this is not true,
exception optype
is generated. How exceptions are processed
is described in the following section.
ExecutiveStmt = throw Expr ";"
Examples:
ext except {
ext error {
class myexcept (msg) {}
}
}
throw errors.myexcept ("this is an user defined exception");
Exceptions can be generated by the Dino interpreter when some
conditions are not satisfied, by predeclared Dino functions, by other
OS processes, by user interruptions, or by the user with the aid of a
throw-statement. Actually, the exceptions are represented by an
object of the predeclared class except
or by an object of a
class declared inside the predeclared class except
. All
predeclared exceptions are described in the section Predeclared
Identifiers. To detect and process exceptions, a try-block can
be used.
When an exception is generated, the closest-containing try-block which
is covering the statement generating the exception or currently being
executed (when this is is generated by an OS process or by an user
interruption) is searched for. Then, expressions in the catch list
elements are processed. The expression value in the catch list
element being currently processed should be the predeclared class
except
or a class declared inside the predeclared class
except
. If the expression being processed is a class and the
exception is an object of the class or an object of a class declared
inside the class, the block corresponding to the given catch list
element is executed. If there is no such catch expression, the
closest-containing try-block covering the current try-block is
searched for and processing the exception is repeated. If there are
no more try-blocks, the program finishes with a diagnostic message
which is dependent on the generated exception.
Blocks corresponding to catch list elements have a predeclared
variable e
. When block execution starts, the variable
contains the object representing the exception.
ExecutiveStmt = TryBlockStmt
TryBlockStmt = try Block { Catch }
Catch = catch "(" ExceptClassList ")" Block
ExceptClassList = Expr { "," Expr }
Examples:
try {
var ln;
for (;;)
ln = getln ();
} catch (invcalls.eof) {
}
try {
var v = [];
v {1} = 0;
} catch (except) {
put ("catching and propagating exception"); println (class (e));
throw e;
}
This statement is used for the synchronization of different threads in
a Dino program. The expression can not contain a function, class, or
a thread-function call. The thread in which the statement has been
executed waits until the expression value becomes nonzero. The
expression value (after implicit arithmetic conversion) should be an
integer or a floating point number. Otherwise the exception
optype
is generated. When the expression value becomes
nonzero, the statement after the expression (it is called
sync-statement) is executed without interruption by other process. It
is used as critical region for process synchronization. In a critical
region execution of wait-statement is prohibited (it results in
generation of exception syncwait
). Also thread calls inside
a critical region result in generation exception
syncthreadcall
.
ExecutiveStmt = wait "(" Expr ")" Stmt
Examples:
wait (!empty);