6. Control Statements¶
Control statements determine the order in which the UniScript program is executed.
6.1. The if-else Statement¶
The if
-else
statement is a conditional
statement. It has the following syntax:
if (condition) {
if statements
} else {
else statements
}
The expression condition has to be a real scalar. The if
statement will be executed if the condition is true. This means that
the expression is not equal to 0. The else
statement will be
executed if the condition is false. else
is optional.
if (condition) {
if statements
}
If the if
and else
statements consist of only one
statement, the braces are not necessary.
a = 1;
if (a == 1) print "a equals 1" else print "a not equal 1"
It is easier to read if you write the statements in separate lines:
a = 1
if (a == 1) {
print "a equals 1"
} else {
print "a not equal 1"
}
The following syntax is not allowed in UniScript and will
result in a syntax error. The second brace will be interpreted as the
end of the if
-else
statement.
a = 1;
if (a == 1)
{
print "a equals 1";
}
else
{
print "a not equal 1";
}
However using Continuation Line one can write:
a = 1;
if (a == 1)
{
print "a equals 1";
} ..
else ..
{
print "a not equal 1";
}
As mentioned previously, the condition must be a real scalar. The expression
string == "Hello"
returns a real scalar if string
is a scalar. The
expression will return 1 if string
holds the string "Hello"
. Otherwise,
it will return 0. If string
is a vector or a matrix of strings, the
expression will return a real vector or a real matrix. For example, if
string
is a vector with the three elements ["Hello", "HELLO", "hello"]
,
the expression will return a real vector with the elements [1, 0, 0]
. To
convert this vector to a real scalar you can use one of the UniScript functions
all and any. The function all returns TRUE (1) if all
elements of the input vector are not zero, otherwise the function returns the
value 0. The any function returns 1 if at least one of the elements of
the input vector is not zero, otherwise the function returns the value
0. If the argument of the function all or any is a
real matrix, the matrix will be evaluated columnwise. In this case,
the return value is a row vector. When the argument is a matrix and
you use all or any twice, the return value is a scalar.
The following example will execute the if
statements if all elements of the string
variable have the
value "Hello"
, no matter if string
is a scalar,
vector or matrix.
if (all(all(string == "Hello"))) {
if statements
} else {
else statement
}
The if
-else
statements can be used to make a
decision out of multiple choices:
if (condition-1) {
statements-1
} else if (condition-2) {
statements-2
} else if (condition-3) {
statements-3
} else {
Statements-n
}
The conditions will be checked one after the other until one
condition is true. After the statements are executed, the
else
-if
chain is finished. If no condition is true, the last
else
case will be executed.
6.2. The for Statement¶
The for
statement is used to iterate the overall
elements of a vector. The general form of the for
statement
is
for (i in vector) {
statements
}
If vector
has the value [1, 3, 6, 4]
, then i
takes the values 1, 3, 6, 4 one after the other. vector
can also
be a string vector or a complex vector.
The vector will only be evaluated once at the beginning of the
for
loop. The following example
a = [1,2,3]
for (i in a) {
a = 0;
printf("a = %d, i = %d\n", a, i);
}
generates the output
a = 0, i = 1
a = 0, i = 2
a = 0, i = 3
The following example will open two UniScript files:
svFilename = ["plot.ic", "alias.ic"];
svFilename = GetRootDirectory() + "script/" + ..
svFilename;
for (ssName in svFilename) {
EdCreate(ssName);
}
6.3. The while Statement¶
The while
statement is used to execute one or more statements
repeatedly. A while
statement has the following syntax:
while (condition) {
statements
}
The condition expression must be a real scalar. The statements will be executed as long the condition is true, i.e. a value not equal to 0.
while (1) {
print "Hello"
}
would print the word "Hello"
indefinitely, because the
condition will never be 0. This loop can only be interrupted by
pressing the ESCAPE key (ESC). The while(1)
statement can also be
interrupted by a break
or return
statement.
The following while
loop will print the word "Hello"
10 times and
then print the number 11.
i = 1;
while (i <= 10) {
print "Hello";
i = i + 1;
}
print i;
6.4. The break and continue Statement¶
The break
statement is used to terminate within an iteration
statement. break
can be used in the statement body of a while
or for
loop.
Some programming languages have iteration statements which check the condition at
the end of the loop (the repeat
statement in Pascal or the do
statement
in C). In UniScript, the behavior of such control statements can be simulated
with the break
statement. The following example will print the string
"Hello"
10 times and will then print the number 10.
i = 1;
while (1) {
print "Hello";
if (i == 10) break;
i = i + 1;
}
print i;
The continue
statement is used inside a while
or
for
loop to skip over the rest of the statements and to continue with
the next loop cycle immediately. The next example opens all files with the
extension .ipw
.
ssPath = "c:/uniplot/samples/";
svFiles = FindFiles(ssPath + "*.*");
for (ssName in ssPath + svFiles[;1]) {
if (strupper(SplitPath(ssName)[4]) != ".IPW") {
continue;
}
if (DocCreate(ssName) == 0) break;
}
The function call FindFiles(ssPath + "*.*")
returns a string matrix of the
files in the ssPath
directory. The first column holds the file names, the
second column the file size, and the third column holds the file attributes. In
our example, we are only interested in the file names. The expression
svFiles[;1]
selects all elements of the first column.
The function SplitPath splits a complete file name into items: drive,
path, name and extension. Therefore, the call SplitPath(ssName)[4]
returns
the extension of the file ssName
. strupper converts its argument into
upper case characters.
If the condition is true, i.e. the file does not have the extension
".ipw"
, the continue
statement will be executed and the
next file name will be evaluated. If the condition is false, the
function DocCreate will load the file. If the file cannot
be opened, DocCreate returns 0. The loop will be terminated
because of the break
statement.
If we had called the FindFiles function with the search pattern
"*.ipw"
, we would have found all wanted files without using
the for
loop and the continue
statement.
6.5. The try-except Statement¶
The try
-except
statement can be used to
handle programming errors. It has the following syntax:
try {
try statements
} except (condition) {
except statements
}
In contrast to the if
-else
statement, the second block in
the try
-except
statement is not optional. Every
try
block has exactly one except
block.
try
-except
statements can be nested.
Normally, only the try
statement is executed. The condition and the
except
statement will only be executed in case of an error in the
try
statement. There are many reasons why a problem can occur while
executing a statement.
Examples:
Not enough memory is available to execute the statement.
The user pressed the ESC key inside a
try
statement.A vector element that does not exist was accessed.
An error occurs inside a function call within a
try
statement body.The error function was called inside the function body.
1 and 2 are problems which the programmer cannot avoid but 3 and 4 are programming errors. In case 5 (call of the error function) an exception was created deliberately.
Example:
def GetTextFile(ssFileName)
{
fp = fopen(ssFileName, "rt");
ssText = fread(fp, "char");
fclose(fp);
return ssText;
}
The function fopen opens a file for reading, fread reads the file, and fclose closes the file. It is important to close the file as soon as possible, because the operating system only allows a limited number of simultaneous open files.
If you call GetTextFile("d:\\test.txt")
, the function will return the
contents of the file d:\test.txt
as a string, if it exists, if all
function calls are error free, if enough memory is available and if the user did
not press the ESC key. If one of these exceptions occurs before the call of the
function fclose, a so called resource loss will occur.
This problem can be solved by protecting the statements with a
try
-except
statement.
def GetTextFile(ssFileName)
{
fp = 0;
try {
fp = fopen(ssFileName, "rt");
ssText = fread(fp, "char");
if (isreal(ssText)) error();
fclose(fp);
return ssText;
} except (1) {
if (fp != 0) {
fclose(fp);
}
MessageBox("File cannot be loaded!");
return "";
}
}
If an exception occurs inside the try
body, the program
branches into the except
body to clean up the function. In our
example, the open file will be closed and an error message will be displayed.
The keyword except
is followed by a condition expression in
parentheses. If the condition is false (0), the exception statements
are not executed. If the condition is true (equal 1), the except
statement is executed. With the function GetExceptionCode, the
exception type can be received.
Example:
def TestException(a, b)
{
try {
i = 0;
while (1) {
x = a + b;
i = i + 1;
}
} except (GetExceptionCode() == ICERR_INTERRUPT) {
MessageBox(..
sprintf("User Abort (i = %d", i"));
}
}
If the function is called with the parameters "a"
and 1.6
(TestException("a", 1.6)
), an exception will occur and the exception
condition will be evaluated.
GetExceptionCode() == ICERR_INTERRUPT, ICERR_OPERATOR_TYPE
GetExceptionCode returns an error code - in this case the error code with
the name ICERR_OPERATOR_TYPE
. Because the error code is not
ICERR_INTERRUPT
, the except
statement will not be executed. The
exception will only be handled if the user presses the ESC key to produce an
ICERR_INTERRUPT
exception. (UniScript error codes are listed in the file
alias.ic
.)
id-1192040