.. highlightlang:: us .. _elements-of-uniscript: Elements of UniScript ===================== .. index:: comments, C, C++ .. _comments-in-uniscript: 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); } .. index:: continuation lines .. _continuation-line: 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. .. _constant-expressions: 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. .. _numeric-constants: 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. .. index:: #define 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 .. index:: 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. .. index:: hexadecimal constants, octal constants, C, 0x .. _hexadecimal-and-octal-constants: 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. .. index:: complex constants, i, sqrt(-1) .. _complex-constants: 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``. .. index:: string constants, escape sequences .. _string-constants: 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. .. list-table:: :header-rows: 1 * - 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. .. index:: long strings "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" .. index:: null-characters in strings .. _null-characters-in-strings: 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 :ref:`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. .. index:: variables .. _variables: 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: .. code-block:: none 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**: .. list-table:: :header-rows: 1 * - 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. .. _vectors-and-matrices: 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]``. .. math:: \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. .. math:: \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] .. index:: index expressions .. _index-expressions: 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. :sub:`id-1040188`