4. Elements of UniScript

4.1. Comments in UniScript

A comment is text that is included in a program to explain what the program does and how it works. You should add comments to your programs in order that you or another person understands the program at a later time.

As in C, UniScript language comments start with the characters, /*, and end with */. UniScript also supports the C++ comment format. This comment starts with a double-slash (//) sequence. Wherever this sequence appears (unless it is inside a string), everything to the end of the current line is a comment.

Example:

/*
    This is a comment
    in C format.
*/

Comments in C format can appear wherever a blank is allowed, e.g.:

rvSignal = [1.4, 1.45, 133254.4 /* Error ? */, 1.53];

Comments in C format cannot be nested. This means that the character sequence, */, is not allowed inside a /* */ comment.

If you add comments to your program, keep in mind the following hints: It is better to choose a descriptive function name than to add a comment to a bad function name:

ssFilename = GetOpenFileName();

is easier to understand than

f = getname();

Comments are frequently used ignore source code lines as shown in the following example:

def hilb(n)
{
/*
    h = zeros(n, n);
    for (i in 1:n) {
        for (j in 1:n) {
            h[i;j] = 1/(i+j-1);
         }
    }
    return h;
*/
    // this is much faster than two for loops
    x = 1:n;
    x = x[ones(1,n); /* all columns */ ];
    return 1./(x+x.'-1);
}

4.2. Continuation Line

If you do not have enough room on the line to type a statement, you can use .. to continue a statement on the next line. UniScript will ignore all characters that appear after the two dots:

return (ones(1,m) .* 10) .^  ..
       [s1+(0:m-2) * (S2-s1) ./ (m-1), S2];

Continuation characters can be used wherever a blank character is allowed. You cannot use them inside a name or a constant.

To write a string in several lines use the .. continuation characters as shown here:

"This is a long constant string" + ..
" written in two lines"

Beginning with UniPlot R2013.11 the continuation characters can be omitted after a comma, a Semicolon or a binary operator. That means the two colons .. in the example above are redundant.

4.3. Constant Expressions

Constants are static values UniScript uses during the execution of your program. There are two types of constants: String constants and numeric constants. A constant may be a scalar, a vector or a matrix. A numeric constant may contain complex values.

4.4. Numeric Constants

A simple numeric constant is a single number that can be an integer, a decimal fraction, a number in exponential notation or a complex number. Note that all numeric values are represented within UniScript in double-precision floating point format. Complex numbers are stored as pairs of double-precision floating point values.

Here are some examples:

123
12.8
+13.01e-3
12E3

The following numbers are not valid:

Incorrect   Correct
.03         0.03        Number cannot start with a period
12.         12.0        Number cannot end with a period
13.9D8      13.9E8      Character D as the exponent
                        character is incorrect
3,82        3.82        Decimal sign is a period and not a comma

UniScript uses the same rules as the programming language C.

If you want to use a name for a constant expression, you can use the #define statement. The #define statement has the following syntax:

#define constant-name replace-text

Every time the UniScript interpreter finds the expression constant-name (except inside a string or a comment) it will be replaced by the replace text. The constant name must be a valid UniScript name, the replace text can be any length.

Example for the constant pi

#define PI  3.1415926535897931

The constant PI can be used in a statement like u = 2 * PI * r. Constant names appear normally in capital letters to distinguish them from variable names.

After the definition of the name PI, the constant can be used in every file, not only in the file where the definition is located.

In the UniScript Editor numeric constants are colored dark red.

4.5. Hexadecimal and Octal Constants

As in C, integer constants can be written as hexadecimal or octal numbers. A hexadecimal number (Base 16) has the prefix 0x or 0X. For hexadecimal numbers, the digits 0...9 and the characters a...f (or A...F) are allowed. Examples:

Hexadecimal Decimal
0x10         16
0xFF         255
0x0d         13
0x5          5

An octal number (Base 8) has the prefix 0. For octal numbers, only the digits 0...7 are allowed.

Examples:

Octal       Decimal
034         28
0377        255

In the UniScript Editor hexadecimal constants are colored dark red.

4.6. Complex Constants

To specify complex constants, expressions can be written in the following forms: 3i, or 1.23e-8i, or 0xFFi. The letter i stands for the pure imaginary constant, defined as sqrt(-1). A space is not allowed between the number and the i.

4.7. String Constants

A string constant consists of a sequence of characters in double quotes. Example:

"This is a string constant"

Some characters cannot be included literally in a string constant. Instead, they can be represented with escape sequences, which are character sequences beginning with a backslash ("\"). For instance, the escape sequence \n represents a newline. In the following example, the words "string constant" will be printed into a new line:

"This is a\nstring constant"

Here is a table of all the escape sequences used in UniScript. They are the same as those used in the C programming language.

Code Meaning
\\ Represents a literal backslash, \
\n a newline
\r a carriage return
\b a backspace
\f a formfeed
\t a horizontal tab
\a the “alert” character
\" a literal double-quote character "
\zzz an integer

The number zzz represents a decimal, hexadecimal or octal number in the range 0...255 (decimal). It defines the ASCII-Code for the appropriate character. For example, the following strings are identical: "Hello\n", "Hello\10" and "Hello\0x0a".

The length of a constant string is limited to 255 characters. A variable can hold a string of unlimited length.

In the UniScript Editor string constants are colored red.

In hexadecimal form the character \x or \0x must be followed by exactly two hexadecimal characters (0 .. f).

In decimal an octal form all decimal (0 .. 9) or octal (0 .. 7) numbers will be read. If the number is greater than 255 (decimal) the number will be reduced to one byte. Example: "\300a" is not identical to "\30" + "0a".

If a string has a prefix r, e.g. r"Hello\10" all backslashes will be left in the string. r"Hello\10" is identical to "Hallo\\10". Inside a simple string with the r prefix the "-character cannot be used.

4.8. “Long” strings

As of UniScript 4.0 so called “long strings” are available. These strings start with "[[ and end with ]]". Example:

a = "[[
This is a long
string constant
]]"

is identical to:

a = "\nThis is a long\nstring constant\n"

In long string constants the "-character can be used with or without the leading backslash. With the r prefix the backslash no longer quotes characters and loses it special meaning. This can be useful for example for file names.

b = r"[[
  c:\foo
  \t
]]"

// b == "\nc:\\foo\n\\t\\n"

4.9. Null-characters in Strings

Beginning with UniScript 4.2.0 character strings can contain Null characters (eight-bit clean Strings). The advantage is that UniScript-Strings can contain binary data. The + operation can be used for strings containing Null characters. The comparison operators only compare the strings to the first Null character:

"Hello\x00Hello" == "Hello"

returns TRUE (1). To compare the complete character string the mem_compare function can be used.

Many string functions will only use the string to the first Null character, for example:

strlen("Hello\x00Hello")

returns 5. The function mem_len("Hello\x00Hello") will return 11.

4.10. Variables

Variables are the names that you have chosen to represent values used in an UniScript program. Variables may represent either numeric values or strings. Variables may not be used before they have been given a value. Doing so results in an error.

The following statement will assign the value 1 to the variable a:

a = 1

If a already exists, the old variable will be destroyed and a new variable will be created. The statement will allocate memory for the constant value and then copy the value 1 into the memory. The old value of a could be a string matrix or anything else. A variable in UniScript can change its type.

The name of a variable must be a sequence of letters, digits and underscores, but it may not begin with a digit. The length of variable names is not limited in UniScript, however, only the first 80 characters are significant. Case is also significant in variable names. For example var is not the same as Var.

The following identifiers are keywords and may not be used as variable or function names:

break
continue
def
else
except
for
global
if
in
print
return
try
while

Variable names should also be distinct from function names: sin = sin(1) is incorrect, but Sin = sin(1) is correct.

Valid names for variables are:

_test
var1
This_is_a_valid_name
__
a1
Return

The following names are invalid:

1a
This is not a name
a?3

In larger programs it is recommended to choose names that indicate the data type they hold. Therefore, most of the names used in UniScript functions have one of the following prefixes:

Example:

Name Meaning
ssFilename ss stands for scalar string. ssFilename might therefore hold only one file name.
svFilename sv stands for string vector. svFilename holds probably more than one file name.
smSorted sm stands for string matrix.
rsXValue rs stands for real scalar.
rvMin rv stands for real vector.
rmSize rm stands for real matrix.
bVisible b stands for boolean. A variable with this prefix should only be assigned the values TRUE (1) or FALSE (0).
hLayer h stands for handle.
hvLayer hv stands for handle vector.
nLayer n stands for numbers. The variable should only hold integers, e.g. 123.

4.11. Vectors and Matrices

The following statement will generate a row vector with the three elements 6, 4 and 13 and assign the vector to the variable a:

a = [6, 4, 13]

If the variable was already used, the old value of a will be replaced by the new vector. a is a real vector with three elements.

Once a variable has been given a value, it can be used in statements. The statement

b = a + 5

adds the value 5 to each element of the vector a and assigns the result to the variable b. b will then have the value [11, 9, 18].

A range is a convenient way to create a row vector with evenly spaced elements. Example: [1, 2, 3, 4, 5, ..., n] or [1, 1.5, 2, ...]. Use the : operator in one of the following manners:

start:end

and

start:step:end

A range constant is defined by the value of the first element in the range, a maximum value which the elements of the range will not exceed, and an optional value for the increment between elements. start, step and end are separated by colons (:).

Example:

1:5         defines the set of values [1, 2, 3, 4, 5]
1.3:4       defines the set of values [1.3, 2.3, 3.3]
1:0.5:2     defines the set of values [1, 1.5, 2.0]
1:0.5:2.4   defines the set of values [1, 1.5, 2.0]

start can be greater than end

5:1         defines the set of values [5, 4, 3, 2, 1]

A vector in UniScript is a special form of a matrix. [6, 4, 13] is a 1 * 3 matrix. That means the matrix has one row and three columns.

To create a column vector, the elements must be separated by a semicolon:

a = [1;2;3]

To change a column vector to a row vector (and vice versa), use the transpose operator ('):

b = a'

The following matrix, for example, can be seen as a combination of the row vectors [1,2,3], [4,5,6] and [7,8,9].

\begin{pmatrix}
   1 & 2 & 3\\
   4 & 5 & 6 \\
       7 & 8 & 9
 \end{pmatrix}

A matrix in UniScript can be defined as the following:

m = [1,2,3; 4,5,6; 7,8,9]

A matrix can also be created from a combination of vectors and matrices, e.g.

\left[
\begin{array}{ccc|cc|c}
1 & 2 & 3 & 10 & 11 & 16 \\
4 & 5 & 6 & 12 & 13 & 17 \\
\cline{4-5}
    7 & 8 & 9 & 14 & 15 & 18
\end{array} \right]

m1 = [1,2,3; 4,5,6; 7,8,9]
m2 = [10,11; 12,13]
v1 = [14,15]
v2 = [16;17;18]

m = [m1, [m2;v1], v2]

4.12. Index Expressions

An index expression allows you to reference or extract elements of a matrix or vector.

If a = [1.5, 3.8, 6.3], then a[1] is the value 1.5, a[2] the value 3.8 and a[3] the value 6.3. Indices are integers beginning with 1. Instead of a scalar index, you can also use an index vector. The expression a[1, 3] will extract the values [1.5, 6.3] and a[1, 3, 1] will extract [1.5, 6.3, 1.5]. Single indices can be used more than once.

A vector variable with a index vector can stand on both sides of the assignment operator:

a = [1, 2, 3, 4, 5]
a[1, 4] = [-1, 66]

In this statement, the element a[1] will be assigned the value -1 and a[4] the value 66. In any case, the index vector on both sides of the assignment operator must have the same number of elements.

After the statement is executed, the variable a is [-1, 2, 3, 66, 5].

The statement

a[1, 4] = a[4, 1]

will exchange the first and the fourth element of the vector without changing any other element.

The second line of the following statements

a = [1, 2, 3, 4, 5]
a[6] = 100

will result in an runtime error. The vector a contains 5 elements. The following statement will add a sixth element to the vector a.

a = [a, 100]

A matrix can be accessed by two index vectors separated by one semicolon. The first vector is a row index vector and the second is a column index vector. If the matrix a is [5,6;7,8] then a[1;1] is 5 and a[1;2] is 6. The result of the expression a[1,2;1] is [5, 6], the first column of the matrix a.

If a row or column index vector is complete, it can be omitted. Instead of a[1,2;1], you can write a[;1] to access the first row of the matrix a.

A matrix in UniScript is stored columnwise as a vector with one dimension. The elements of the following matrix

are saved in the order [1, 4, 7, 2, 5, 8, 3, 6, 9]. The internal representation can be accessed when the matrix is accessed with a one dimensional vector. Instead of a[2;3] (second row, third column), this element can be accessed with the expression a[8]. To access all elements of the matrix a, you can write a[1:9], this is equivalent to a[:].

Summary

var = start:step:end creates a row vector.

var = start:end creates a row vector with the increment 1.0.

var = [e1, e2, e3] creates a row vector.

var = [e1; e2; e3] creates a column vector.

var = [e1, e2; e3, e4] creates a matrix.

var[index-vector] references elements of a vector.

var[row-index-vector; column-index-vector] references elements of a matrix.

var[row-index-vector ; ] references the row elements of a matrix.

var[ ; column-index-vector] references the column elements of a matrix.

var[:] changes a matrix to a row vector.

id-1040188