:Revision=24
:HTML
<<
1
Syntax Help cPCI Interpreter
$NoSort;Open
--
>>

<<
1.1 - 1
Overview
$NoSort
--
>>

<<
1.1.1 - 1.1
Syntactic Elements|Elements
$NoSort
--
The interpreter uses the ASCII-font with the letters <!CW>A to <!CW>Z and <!CW>a to <!CW>z, the figures <!CW>0 to <!CW>9 and other standard characters. The language does not make any differentiations between upper- and lower case. 

The space (ASCII 32) and the control character (ASCII 0 to 31 including ASCII 13 for line feed) are refered to as <i>blanks</i>.

The combinations of basic syntactic elements (the so called Token) form  expressions, declarations and <a href="1.1.7.1">instructions</a>. 

An instruction describes an algorithmic action which can be carried out within a program. 

An expression is a syntactic unit, contained in an instruction and describes a value. 

A declaration defines an identifier (e.g. the name of a function or variable) used in expressions and instructions. If necessary, it also assigns memory space.
>>

<<
1.1.1.1 
Comments
--
Comments are source text parts which are ignored by the interpreter. They serve as exemplifications of the codes or can be used to 'freeze' the several source code parts from execution. 

There are two types of comments:

<ol indent=18>
 <li>Block comments
All the characters between an opening curly brackets <!CW>'{' and the first next closing curly brackets <!CW>'}' are ignored. These comments cannot be nested.

</li>
 <li>Line comments
All the characters after a double backslash <!CW>'//' are ignored until the end of the line.
</li>
</ol>
>>

<<
1.1.1.2
White-Spaces
--
The individual elements of the interpreter language are separated by white-spaces. 

These can be
<ul indent=12>
<li>blanks</li>
<li>tabs</li>
<li>line-ends</li> 
</ul>
any combinations of these.

If the end of an element is unambiguous, then no white-space is necessary.
>>

<<
1.1.1.3
Reserved Words
--
Reserved words are predefined elements of the IP-language which have a fixed meaning for the interpreter without any futher prior declaration.

Reserved words are, among other things, control elements like <!RW>begin, <!RW>end, <!RW>step as well as names of the IP-Objects and their methods. 

Reserved words may not be used as identifiers.

As in the case of identifiers, there is no differentiation between upper- and lower case.
>>

<<
1.1.1.4
Identifiers
--
Identifiers are used for parameters, variables, procedures and functions. 

Although an identifier may be of any length, it should be of maximum circa 20 characters out of visibility and speed reasons.

An identifier must begin with a letter or an underscore (_) and may not contain any blanks. The first character can be followed by letters, figures and underscores.

Reserved words may not be used as identifiers.

Since the difference between upper-and lower case is not relevant for the interpreter, for the CalculateValue identifier e.g. the following spellings are allowed (among a lot of others):

<ul indent=12>
<li><!CW>CalculateValue</li>
<li><!CW>calculateValue</li>
<li><!CW>calculatevalue</li>
<li><!CW>CALCULATEVALUE</li>
<li><!CW>CaLcUlAtEvAlUe</li>
</ul>
>>

<<
1.1.1.5
Literals
--
Literals are values 'readily available' in the source code which can be used directly by the interpreter.

Examples of literals are numbers and character strings.
>>

<<
1.1.1.5.1
Numbers
--
The interpreter understands numbers in 3 number systems:
<h4>Decimal:</h4>
Numbers without any special markers are considered decimal values. They may consist of the following parts:
<ul indent=12>
<li>an algebraic sign (+/-) -> numbers without algebraic signs are considered positive values</li>
<li>the integer part (consisting of the figures 0..9)</li>
<li>optionally, a decimal point and the decimal places (consisting of the figures 0..9)</li>
<li>optionally, an exponent in scientific notation (E or e followed by an exponent). This is then read as "raised to the 10th power".</li>
</ul>

Example:
<!CODE>
  123
  123.45
  -123.45
  +123E2       // = 12300
  -123.45e-4   // = -0.012345
<!TXT>

<!REM>
Note: 
The decimal separator is always the period. Separators of thousands are not allowed.
<!TXT>
<h4>Hexadecimal:</h4>
The dollar character ($) indicates a hexadecimal number, e.g. $8F.

Valid hexadezimal digits are 0..9 and A..F, and / or a..f.

Hexadecimal numbers must be in the range of $00000000 to $FFFFFFFF.

Example:
<!CODE>
  $00
  $7B    // = 123 decimal
  $ABFE3
<!TXT>

<!REM>
Note: 
Hexadecimal numbers must always be integers.
<!TXT>
<h4>Binary:</h4>
The paragraph character () indicates a binary number, e.g. 101.

Valid binary digits are 0 and 1.

Binary values must be in the range of 0..2<sup>32</sup>-1 and are always integers.

Example:
<!CODE>
  1111011  // = 123 decimal
<!TXT>
>>

<<
1.1.1.5.2
Strings
--
A string is a sequence of zero or more characters of the extended ASCII (8-Bit) set. It can consist of a string in quotation marks, of a control character-string or a combination of the two.
Such a string must be between single quoatation marks (') in onesource text line. A string between quotation marks which does not contain any characters between the single quotation marks is an empty-string. Two consecutive single quotation marks in a string - placed in quotation marks themselves- represent a single quotation mark. Some examples:

<!CODE>
'MCD-Elektronik'    -> MCD-Elektronik
'Miller''s office'  -> Miller's office
''''                -> '
''                  -> an empty string, 0 characters long
' '                 -> a blank
<!TXT>

A control character-string is a sequence of one or several control characters. Each of these control characters consists of an #-symbol and an unsigned integer-constant between 0 and 255 (decimal or hexadecimal), which indicates the corresponding ASCII-character. The control character-string

<!CODE>
#77#67#68
<!TXT>

corresponds to the following string between quotation marks:

<!CODE>
'MCD'
<!TXT>

Strings between quotation marks and control character-strings can be combined to build longer strings. E.g. the character for a carriage return/line feed between line 1 and line 2 is inserted with the following string:

<!CODE>
'Line 1'#13#10'Line 2'
<!TXT>

However, strings between quotation marks cannot be connected this way, because a pair of consecutive single quotation marks is interpreted as one single character. In order to join strings between quotation marks the operator + should be used. But the relevant strings can be also simply combined with a single string between quotation marks.

The length of a character-string corresponds to the number of characters in the string.
>>

<<
1.1.1.5.3
Vectors/StringVectors
--
A Vector-literal consists of the vector elements separated by commas and enclosed in square brackets.
Every vector-element contains only elements of the same type, strings or real values.
A vector-element could a number-literal, a string-literal, a numeric expression or a string expression.

Example:
<!CODE>
[]         		-> empty vector, 0 elements (for vectors and stringvectors)
[1]      		-> vector with one element of value 1
['hello'] 		-> Vector with one string element and the value 'hello'
[1,2,3,4]  		-> vector with 4 elements
['Hello','World']	-> Vector with 2 elements ('Hello' and 'World')
[1+2, 3*4] 		-> vector with 2 elements (3 and 12)
['Hello'+'World'+'!']	-> Vector with 1 element ('Hello World!')
<!TXT>
>>

<<
1.1.2
Data Types
--
The interpreter differentiates 3 real data types:

<ul indent=12>
<li><a href="1.1.2.1">REAL</a></li>
<li><a href="1.1.2.2">STRING</a></li>
<li><a href="1.1.2.3">VECTOR</a></li>
</ul>

and the pseudo-data-types

<ul indent=12>
<li><a href="1.1.2.4">ComObject</a></li>
<li><a href="1.1.2.6">NetObject</a></li>
</ul>

It is not possible to declare other data types.
>>

<<
1.1.2.1
Data Type REAL|Real
!1.1.6.3
--
The data type <!RW>REAL is used for any numeric values.
It is not only used for float values, but also for integer and logical values. The conversion is automatically carried out internally.

<!STBL>
<!>CPU Data type<!>IEEE Double<!>
<!>Value range<!> (5.0 * 10<sup>-324</sup> .. 1.7 * 10<sup>308</sup>)<!>
<!>Precision<!>15 significant digits<!>
<!ETBL>

If a <!RW>REAL value is converted internally into an integer, then the value range is limited according to the called function.

The following apply for the conversion of logical values (<!RW>True, <!RW>False) into and from <!RW>REAL values:

<pre>  Logic -> <!RW>REAL           <!RW>REAL -> Logic
   <!RW>TRUE ->  1        unequal 0 -> <!RW>TRUE  
  <!RW>FALSE ->  0                0 -> <!RW>FALSE</pre>
>>
<<
1.1.2.2
Data Type STRING|String
!1.1.6.4
--
The data type <!RW>STRING is used for all the strings.

A string can contain between 0 and ca 2 milliones of characters (more exactly: 2^31-8).

Each character occupies 1 Byte (8-Bit set). A string can contain zero bytes, they do not serve as string ends, because the length of the string is managed separately.
>>
<<
1.1.2.3
Data Type VECTOR|Vector
!1.1.6.5
--
The data type <!RW>VECTOR realizes an one-dimensional array of real values.

The number of elements can be between 0 and 65535. Each element represents a <!RW>REAL value.

The length of a vector is not predefined, but determined by the purpose of its application.
>>

<<
1.1.2.4
Pseudo-Data type COMOBJECT|COMObject
!1.1.7.4
--
The pseudo data type <!RW>COMOBJECT is used to notify the interpreter about an identifier which is going to be used as COM-Object (ActiveX-Object).

<!RW>COMOBJECT values are not directly assignable; they are assigned by calling methods of the interpreter object <a href="128.118">COM</a>and then used similarly to integrated interpreter objects.
>>

<<
1.1.2.5
Data Type STRINGVECTOR|StringVector
!1.1.6.5
--
The data type <!RW>STRINGVECTOR realizes an one-dimensional array of strings.

The number of elements can be between 0 and 65535. Each element represents a <!RW>String value.

The length of a vector is not predefined, but determined by the purpose of its application.
>>

<<
1.1.2.6
Pseudo-Data type NetObject|NetObject
!1.1.7.11
--
The pseudo data type <!RW>NetObject is used to notify the interpreter about an identifier which is going to be used a .Net class.

The NetObject can create with or without Parameter.
The syntax of the NetObject definition is following:
<!SYN>
<a href="1.1.1.4">Identifier</a> [, Identifier ..] : NetObject [([Namespaces.Class][,ClassSourcecode][,InstanceName])];
<!TXT>
The field <b>'Identifier'</b> defines a name for the NetObject variable.
The field <b>'Namespace.Class'</b> defines the complete .NET identifier for the class (complete with namespaces and class name)
The field <b>'ClassSourcecode'</b> defines the pfad and filename with the sourcecode for the defined class.
The field <b>'InstanceName'</b> defines the instance name of the class. This allows several instances.

The creation parameter 'Namespace.Class', 'ClassSourcecode' and 'InstanceName' are optional. To use the second and third parameter, the parameter before must be used too.
If only the first parameter is used, all .Net sourcecode from the 'IPSteps' folder (folder of the interpreter steps, *.ips) and from a sub folder wich has the the structure of the namespaces and class. In this sourcecode the class from the first parameter must be avaiable in the right namespace.
If the firs and the second parameter is passed, additional to the folders before the folder is used which is passed with the sourcecode file name (second parameter).

<!CODE>
noToolCtrl : NetObject;							// NetObject variable with the name 'noToolCtrl', but not usable because there is no .Net instance.
oToolCtrl : NetObject ('tool.ctrl');					// The same as before, but usable because there is a .Net instance of tool.ctrl.
noToolCtrl : NetObject ('tool.ctrl', 'c:\code\tool\ctrl.cs');		// The same as before, but with path to the sourcecode. 
noToolCtrl : NetObject ('tool.ctrl', 'c:\code\tool\ctrl.cs', 'ctrl1');	// The same as before, but with instance name. 
<!TXT>
>>

<<
1.1.3
Interpretersteps|Steps
$NoSort
--
An interpreterstep (also called just step) consists of the following elements:
<!SYN>
[<a href="1.1.3.1">ParameterList</a>]
[<a href="1.1.3.2">Variable-/ConstantList/s</a>]
[<a href="1.1.3.3">LibraryIntegration</a>]
[<a href="1.1.3.4">Procedure-/FunctionsDefinition/s</a>]
STEP
  [ <a href="1.1.7">Expression</a>; ..]
END.
<!TXT>
The reserved words <b>STEP</b> and <b>END.</b> are obligatory; please note the period after the END, since this is the only position where there is a period after END!

All the other elements are optional, but, if present, they must be in the specified sequence.
>>
<<
1.1.3.1
Parameterlist
--
The parameter list determines which parameter from the test step parameter data bank is used by the interpreter step. Therefore, the parameter list can be used only in real test steps, not in system-steps.

The parameter list begins with the reserved word <!RW>PARAMETER and contains up to 32 parameter definitions.

Each parameter definitions has the following structure:
<!SYN>
<a href="1.1.1.4">Identifier</a>  : (No, Type, Information, Mask):
<!TXT
<b>'Identifier' </b>
is the name for this parameter, as used in the interpreter step.
The identifier can be selected freely, but must not be in conflict with reserved words. However, it proved to be reasonable to classify the parameter identifiers, depending on the data type of the parameter using the letters <!SW>'ps' for string parameters and <!SW>'pr' for real parameters.

<b>'No'</b>
indicates which parameter (1..32) is assigned to the identifier. Each parameter may be called in the parameter list only once. The sequence within the parameter list is arbitrary, but is proved to be reasonable to keep the list in ascending order (for readability reasons).

<b>'Type'</b>
Indicates the data type of the parameter. The only allowed data types for the parameters are <!RW>STRING and <!RW>REAL.

<b>'Information'</b>
is a string literal which contains information for the usage of the parameter. The value is transferred to the parameter editor and stored in the test step parameter table as well, but it is ignored by the interpreter.

<b>'Mask'</b>
is a string literal which represents a mask when the value is loaded from the parameter table. The value is transferred to the parameter editor but also used by the interpreter for loading the parameter value.
The following mask types can be used:
<ul indent=12>
 <li>empty mask
  an empty string, no mask, no check
  Example : <!CW>''<!TXT></li>
 <li>list of valid values
  all the valid values are listed; they are seprated by '/' 
  Example : <!CW>'apple/pear/lemon'<!TXT></li>
 <li>Value range
  Lower- and Upper limit (always inclusive), separated by '..' 
  Only for <!RW>REAL parameter
  Example : <!CW>'0..10'<!TXT></li>
</ul>

In case of <!RW>REAL parameters, it is checked independently of the mask type, whether the value in the data bank can be converted into a numeric value.
  
Example for a parameter list:
<!CODE>
PARAMETER
  prChannel  : ( 1, Real,   'Channel  (1..4)',   '1..4');
  prAverages : ( 2, Real,   'Averages (1..100)', '1..100');
  psText     : ( 5, String, 'Message',           '');
<!TXT>
>>
<<
1.1.3.2
Variable-/ConstantList
--
The Variable- and ConstantLists declare, which identifiers are used as names of variables and constants.

<!REM>
Remark: 
Constants, predefined variables and the option to define more than one list have been implemented in version V1.2.5.
<!TXT>

All variables that are defined globally in the step or any used library have the same global visibility and share the same namespace. So they all have to have different names and can be used by any used library or the step.

<!REM>
Remark:
The possibility to have globally defined variables and constants in libraries was implemented in V1.2.10 Build 978.
<!TXT>

>>

<<
1.1.3.2.1
var (variableList)/ static (static variableList)
--
The variable list determines which variable should be used by the interpreter in the following.

The variable list begins with the reserved word <!RW>VAR and contains any number of variable definitions.
<!SYN>
<!RW>VAR
  [<!SW>VariableDefinition; ..]
<!TXT>
A special form is the static variable list, which starts with the reserved Word <!RW>STATIC. Variables defined this way are called static variables (see below).
<!SYN>
<!RW>STATIC
  [<!SW>VariableDefinition; ..]
<!TXT>
Static variables can't be of the type <!RW>ComObject or <!RW>NetObject.

Every <!SW>VariableDefinition has the following structure:
<!SYN>
<a href="1.1.1.4">Identifier</a> [, Identifier ..] : <a href="1.1.2">Type</a> [= Value];
<!TXT>

<b>'Identifier'</b>
defines the name for a variable of the subsequent type.
The identifier can be selected freely, but must not conflict with reserved words or previously used identifiers.
However, it proved to be reasonable to classify the variable identifiers depending on the data type according to the following letters:
<!STBL>
<!r>Real :<!><!SW>r<!>
<!r>String :<!><!SW>s<!>
<!r>Vector :<!><!SW>v<!>
<!r>StringVector :<!><!SW>v<!>
<!r>ComObject :<!><!SW>co<!>
<!r>NetObject :<!><!SW>no<!>
<!ETBL>
Individual identifiers are separated by commas.

<b>'Type'</b> indicates the data type of the previously listed variables. The allowed types are <!RW>REAL, <!RW>STRING, , <!RW>VECTOR, <!RW>STRINGVECTOR, <!RW>COMOBJECT and <!RW>NetObject.

<b>'Value'</b> is an optional value, used to pre-define the variable. The value has to be of the same data type as the variable. ComObjects can't be predefined. All variables within one VariableDefinition will get the same predefinition value. 
'Value' can be any expression that can be calucalted at this time of the interpreter step, including constants, other variables, internal functions. Predefined variables are used the same way as not predefined ones.
If 'Value' is not present, the variables will have the following content after definition:
<!STBL>
<!r>Real :<!>0<!>zero<!>
<!r>String :<!>''<!>an empty string<!>
<!r>Vector :<!>[]<!>an empty vector, zero elements long<!>
<!r>StringVector :<!>[]<!>an empty vector, zero elements long<!>
<!r>ComObject :<!>empty<!>not assigned, can't be used like that<!>
<!r>NetObject :<!>empty<!>not assigned, can't be used like that<!>
<!ETBL>

<!CODE>
Example:
VAR
  rSingle, rSum : real;         		// two real variable, both 0
  rCount  : real = 10;          		// real variable, initialized with 10
  sCRLF   : string = #13#10;                	// string, initialized with CarriageReturn+LineFeed
  rLen    : real = len(sCRLF);               	// real variable, initialized with 2
  svNamen : stringvector = ['Hans', 'Otto']; 	// StringVector initialized with names
  vZahlen : vector = [7, 2];		     	// Vector initialized with numbers
  ncClass : NetObject ( 'TestNC.TestC');	// creates a instance of ncClass with the class TestC from the namespace TestNC
<!TXT>

<h3>Normal variable &lt;&gt; static variable</h3>
Normal variable will be lost, as soon as the IP step is finished. Their value is lost and they will be re-initialised (as given above), when the step or the library is used again.

The value of a static variable is retained between the calls of a step or a library. Their value is stored after the end of a step and will be reassigned when the step or library is used again. An assignement in the definition part is done only for the very first creation of this variable.
Static variable behave very similar to the global variables.
 <!REM>Hinweis:
Static variables have been implemented in Version V1.3.1.
<!TXT>
>>

<<
1.1.3.2.2
const (ConstantList)
--
The constant list determines which constants should be used by the interpreter in the following.
The value of a constant can't be changed after declaration. So constants can't be used on the left side of an assignment or as a <!RW>VAR parameter of a function or procedure call.

The constant list begins with the reserved word <!RW>CONST and contains any number of variable definitions.
<!SYN>
<!RW>CONST
  [<!SW>ConstantDefinition; ..]
<!TXT>
Every <!SW>ConstantDefinition has the following structure:
<!SYN>
<a href="1.1.1.4">Identifier</a> [: <a href="1.1.2">Type</a>] = Value;
<!TXT>
 <!REM>Remark: 
It is syntactically correct to have more than one identifier: This will define two ore more constants with the same value. Since the value of an constant can't be changed, you should either omit one of the constants or - if the constants are used in different contexts - make a second definition.
<!SYN>
Identifier1 [, Identifier2 ..] [: Type] = Value;
<!TXT>
 <b>'Identifier'</b>
defines the name for a variable of the subsequent type.
The identifier can be selected freely, but must not conflict with reserved words or previously used identifiers.
However, it proved to be reasonable to classify the variable identifiers depending on the data type according to the following letters:
<!STBL>
<!r>Real :<!><!SW>cr<!>
<!r>String :<!><!SW>cs<!>
<!r>Vector :<!><!SW>cv<!>
<!r>StringVector :<!><!SW>csv <!>
<!ETBL>

<!CODE>
Beispiel:
const
  crReal = 7;
  csString = 'text';
  cvConstVector = [0.017, 0.999];
  csvConstStringVector = ['Sinus', 'Cosinus'];
<!TXT>

 <b>'Type'</b> indicates the data type of the previously listed variables. The allowed types are <!RW>REAL, <!RW>STRING <!RW>VECTOR or <!RW>STRINGVECTOR. The type is optional as the data type can be calculted by the given value.
 
 <b>'Value'</b> The value stored in the constant. 'Value' can be any expression that can be calculated at this time of the interpreter step, including other constants, variables, internal functions. 

If a type was specified, the value has to be of this type. Otherwise the type of the constant will be determined by the value
>>

<<
1.1.3.3
Library Integration|Uses
--
Libraries are integrated with the help of the <!RW>Uses Clause.

The effect of the <!RW>Uses clause is somewhat the same with the includation of the library content into the interpreter step on the corresponding position.

The <!RW>Uses Clause has the following setup

<!SYN>
<!RW>USES 
  LibraryName [, LibraryName] ;
<!TXT>
<b>'LibraryName'</b> is the file name of the file which contains the library routines as string <a href="1.1.1.5.2">Stringliteral</a>. 

The library name can be automatically converted by interpreter aliases.
>>
<<
1.1.3.4
Procedure-/Function Definitions|Procedures/Functions
$NoSort
--
The name, number, type of the parameter and - in case of a <!SW>function - the type of the return value are all specified when a <!SW>procedure or <!SW>function is declared. 

This part of the declaration is also called prototype, introduction or heading. The heading is followed by the code which will be executed when the <!SW>procedure or <!SW>function is called. This part is also called the body or the block of the routine.

The standard procedure <a HREF="120.2.5">Return</a> can be called any place in the body of a function or procedure. <!RW>Return ends the relevant routine and returns the control to the routine which called that function or procedure.
>>
<<
1.1.3.4.1
Procedure Declaration
--
A procedure declaration has the following structure:

<!SYN>
<!RW>PROCEDURE Procedurename [(<a href="1.1.3.4.3">CallParameterList</a>)] ;
[<a href="1.1.3.4.4">LocalVarConstList/s</a>]
<!RW>BEGIN
  [Instructions;]
<!RW>END;
<!TXT>
 <b>Procedurename</b> is any valid, but yet unused <a href="1.1.1.4">Identifier</a>.

The <b>LocalVarConstList/s</b> defines local used variables and constants that are valid only within this procedure. They may use already applied variable/constant names, in which case they de-facto 'overlap' the external variables/constants.

 <b>Instructions</b> is a sequence of instructions which are executed when the procedure is called. 

Procedures can call themselves (recursion). In this case a new record of local variables is generated.

The <a href="1.1.3.4.3">CallParameterList</a> and the <a href="1.1.3.4.4">LocalVarConstList/s</a>are optional.

Example of a procedure:
<!CODE>
rocedure WaitForDDEIdle (rTimeout : real);
var
  sRecv : string;
  rEnde : real;
begin
  rEnde:=DateTime.ReadTimer+rTimeout;
  repeat    
    DDEClient.Request (2, 'Run', sRecv);
    sRecv := Copy(sRecv, 1, 1);  // 0=Idle, 1=Busy, 2=Ok, 3=Error
  until (sRunState <> '1') or (DateTime.ReadTimer>rEnde);
end;
<!TXT>

After this declaration the WaitForDDEIdle procedure can be called in the following way:
<!CODE>
 WaitForDDEIdle (1000);
<!TXT>

This procedure call waites for 1 second or until the DDE-Server does no longer report 'Busy', whichever happens first.

The locally defined varaibles as well as all the parameters and variables of the step can be used in the instruction block of a procedure. In addition, all the previously defined procedures and functions (as well as the libraries) can be called.
>>
<<
1.1.3.4.2
Function Declaration
--
A function declaration is similar to a procedure declaration, except that, it defines a return type too. 

Function declarations have the following structure:
<!SYN>
<!RW>FUNCTION FunctionName [(<a href="1.1.3.4.3">CallParameterList</a>)] : ReturnType; 
[<a href="1.1.3.4.4">LocalVarConstList/s</a>]
<!RW>BEGIN
  [Instructions;]
<!RW>END;
<!TXT>
 <b>FunctionName</b> is any valid identifier which has not been used so far.

 <b>ReturnType</b> is either <!RW>REAL, <!RW>STRING, <!RW>VECTOR oder <!RW>STRINGVECTOR.

The <b>LocalVarConstList/s</b> defines local used variables and constants that are valid only within this procedure. They may use already applied variable/constant names, in which case they de-facto 'overlap' the external variables/constants.

 <b>Instructions</b> is a series of instructions which are executed when the procedure is called. 

Functions may call themself (Recursion). A new set of local variables will be create for every recursive call.

The <a href="1.1.3.4.3">CallParameterList</a> and the <a href="1.1.3.4.4">LocalVarConstList/s</a> are optional.

<!REM>
Note:
In some older program versions, for functions without parameters an empty CallParameterList () had to be specified. Newer program versions do not need this brackets, but accept the syntax of older versions. 
<!TXT>

A local variable with the name <!CW>Result of the ReturnDataType is automatically defined. This variable receives the value which will be returned by the function.
Alternatively, the return value can be transferred to the return procedure <a HREF="120.2.5">Return</a> as well.

The locally defined variables as well as all the parameters and variables of the step can be used in the instruction block of a function. In addition, all the previously defined procedures and functions (also the ones from libraries) can be called too.

Example of a simple function:
<!CODE>
function Three : real; 
begin
  Result:=3;
end;

// in old version of the program:
function Three2 () : real;
begin
  Result:=3;
end;

// realized with Return
function Three3 () : real;
begin
  Return (3);
end;
<!TXT>

All these functions return 3.

Functions can call themselves (recursion):
<!CODE>
function nFactorial (r : real) : real;
begin
  r:=abs(int(r));       // nFactorial only for natural numbers!
  if r<=1 then begin
    return (r);         // returns r 
                        // the function is left here!
  end;
  Result := r * nFactorial  (r-1);  // recursion
end;
<!TXT>
>>
<<
1.1.3.4.3
Call Parameter List|CallParameterList
--
Most of the procedure and function headers contain a CallParameterList. In the header
<!CODE>
function Power (X: real; Y: real): real;
<!TXT>

the parameter list is  <!CW>(X: <!RW>real; <!CW>Y: <!RW>real).

Syntax:
<!SYN>
CallParameterList :=
  ( [Parameterdeclaration [; Parameterdeclaration ..] )

Parameterdeclaration :=
  [<!RW>VAR] Identifier [, Identifier ..] : Datatype
<!TXT>
A CallParameterList is a sequence of Parameterdeclarations which are separated by semicolons and enclosed in brackets. Each declaration consists of a sequence of parameter names which are separated by commas. After the last parameter name follows a colon and a type identifier. Parameter names must be valid identifiers. A declaration can be prefixed with the reserved word var. 

Declarations with var are designated as variable parameters, while the ones without var as value parameters (see there).

Declarations with <!RW>VAR are called  <a href="1.1.3.4.3.2">Reference Parameter</a>, such without <!RW>VAR are called <a href="1.1.3.4.3.1">Value Parameter</a>.

Some examples:
<!CODE>
(X, Y : Real)
(var S : string; X : real)
(HWnd : real; Text, Caption : string; Flags : vector)
<!TXT>

The parameter list indicates the number, sequence and type of the parameters which must be transferred to the routine when the call is made. If a routine does not accept any of the parameters, do not indicate in the declaration either the identifier list or the brackets:
<!CODE>
procedure UpdateRecords;
begin
        ...
end;
<!TXT>

(Very old program versions needed an empty list <!CW>() )

In the body of the procedure or function, the parameter names (X and Y in the first example) can be used just like local variables. The parameter names may not be declared again in the section with the local declarations.
>>
<<
1.1.3.4.3.1
Value Parameters (call-by-value)|Value parameters
--
Value parameters are specified in the call-parameter-list <b>without</b> <!RW>VAR.
<!CODE>
function Power (X: real; Y: real): real;
<!TXT>

A value parameter behaves as a local variable which is initialized with the value transferred by calling the function or procedure. If a variable is transferred as value parameter, the procedure or the function makes a copy of this variable. Modifications of this variable's value do not effect the original variable. 

When called, value parameters can take any (type compatible) expression.
<!CODE>
function DoubleByValue (X : real) : real;     
// X is here a value parameter
begin
  X := X * 2;   // does not have an external effect 
  Result := X;
end;
<!TXT>

The function returns the doubled value of the call parameter. The value of the call parameter is not modified, since, internally, there is a separate variable X.

Example of a call:
<!CODE>
var
  i, j : real;
step
  i:=4;
  j:=DoubleByValue (i); // i=4, j=8
  j:=DoubleByValue (6); // j=12
  j:=DoubleByValue (1+2+3+4);   // j=20
end.
<!TXT>
>>
<<
1.1.3.4.3.2
Reference Parameters (call-by-reference)|Reference Parameter
--
Reference parameters are specified in the call-parameter-list <b>with</b> <!RW>VAR.
<!CODE>
function Power (VAR X: real; VAR Y: real): real;
<!TXT>

A reference parameter is like a reference to an external variable (hence the name). Modifications of the parameter in the body of a procedure or function are therefore persistent and affect the external variable.

When called, the variable parameters must have matching (type compatible) variables.
<!CODE>
function DoubleByRef (var X : real) : real;     
// X is here a reference parameter
begin
  X := X * 2;   // has an external effect!
  Result := X;
end;
<!TXT

The function returns the doubled value of the call parameter. Thereby, the value of the call parameter is also modified.

Example of a call:
<!CODE>
var
  rA, rB : real;
step
  rA:=4;
  rB:=DoubleByRef (rA); // rA=8, rB=8
  rB:=DoubleByRef (6);  // Syntax error!
end.
<!TXT>

With the help of reference parameters, procedures and functions can change several values of the calling step. 

Even if the same variable is tranferred in several var-parameters, there will be no copies made. This behaviour is illustrated in the following example:
<!CODE>
procedure AddOne(var rA, rB : real);
begin
  rA := rA + 1;
  rB := rB + 1;
end;

var 
  rC: real;
step
  rC := 1;
  AddOne(rC, rC);
end;
<!TXT>
After this code has executed, the variable rC will have the value 3.
>>

<<
1.1.3.4.4
Local Variable and Constant Lists|LocalVarConstList/s 
--
The local variable and constants lists are similar to the <a href="1.1.3.2">global variable and constant lists</a>. 

The difference is, that local definitions are only valid for the procedure or function they belong to.

Plus, there are some restrictions (calculation of const values, no predefined variables)

 <!REM>Remark: 
Locale constants have been implemented in version V1.2.6.
<!TXT>
>>

<<
1.1.3.4.4.1
Locale Variable List|LocaleVarList
--
The locale variable list determines which variable should can be used inside the procedure or function.

The variable list begins with the reserved word <!RW>VAR and contains any number of variable definitions.
<!SYN>
<!RW>VAR
  [<!SW>VariableDefinition; ..]
<!TXT>
A special form is the static variable list, which starts with the reserved Word <!RW>STATIC. Variables defined this way are called static variables (see below).
<!SYN>
<!RW>STATIC
  [<!SW>VariableDefinition; ..]
<!TXT>
Static variables can't be of the type <!RW>ComObject and <!RW>NetObject.

Every <!SW>VariableDefinition has the following structure:
<!SYN>
<a href="1.1.1.4">Identifier</a> [, Identifier ..] : <a href="1.1.2">Type</a>;
<!TXT>

 <b>'Identifier'</b>
defines the name for a variable of the subsequent type.

The identifier can be selected freely, but must not conflict with reserved words. The identifier can be identival with another one used outside of the procedure or function. In this case, the locale identifier hides the external one.

However, it proved to be reasonable to classify the variable identifiers depending on the data type according to the following letters:
<!STBL>
<!r>Real :<!><!SW>r<!>
<!r>String :<!><!SW>s<!>
<!r>Vector :<!><!SW>v<!>
<!r>StringVector :<!><!SW>sv<!>
<!r>Comobject :<!><!SW>co<!>
<!r>NetObject :<!><!SW>no<!>
<!ETBL>
Individual identifiers are separated by commas.

<b>'Type'</b>
indicates the data type of the previously listed variables. The allowed types are <!RW>REAL, <!RW>STRING, <!RW>VECTOR, <!RW>COMOBJECT and <!RW>NetObject.

Variables will have the following content after definition:
<!STBL>
<!r>Real :<!>0<!>zero<!>
<!r>String :<!>''<!>an empty string<!>
<!r>Vector :<!>[]<!>an empty vector, zero elements long<!>
<!r>StringVector :<!>[]<!>an empty vector, ero elements long<!>
<!r>Comobject :<!>empty<!>not assigned, can't be used like that<!>
<!r>NetObject :<!>empty<!>not assigned, can't be used like that<!>
<!ETBL>


<h3>Normal variable &lt;&gt; static variable</h3>
Normal variable will be lost, as soon as the IP step is finished. Their value is lost and they will be re-initialised (as given above), when the step or the library is used again.
It is not possible to have predefined normal locale variables.

The value of a static variable is retained between the calls of a step or a library. Their value is stored after the end of a step and will be reassigned when the step or library is used again. An assignement in the definition part is done only for the very first creation of this variable.
Static variable behave very similar to the global variables.
 <!REM>Hinweis:
Static variables have been implemented in Version V1.3.1.
<!TXT>
>>

<<
1.1.3.4.4.2
Locale Constant List|LocaleConstList
--
The locale constant list determines which constants should can used by the interpreter in procedure or function.

The value of a constant can't be changed after declaration. So constants can't be used on the left side of an assignment or as a <!RW>VAR parameter of a function or procedure call.

The constant list begins with the reserved word <!RW>CONST and contains any number of variable definitions.
<!SYN>
<!RW>CONST
  [<!SW>ConstantDefinition; ..]
<!TXT>
Every <!SW>ConstantDefinition has the following structure:
<!SYN>
<a href="1.1.1.4">Identifier</a> : [<a href="1.1.2">Type</a>] = Value;
<!TXT>
 <!REM>Remark: 
It is syntactically correct to have more than one identifier: This will define two ore more constants with the same value. Since the value of an constant can't be changed, you should either omit one of the constants or - if the constants are used in different contexts - make a second definition.
<!SYN>
Identifier1 [, Identifier2 ..] [: Type] = Value;
<!TXT>
 <b>'Identifier'</b>
defines the name for a variable of the subsequent type.

The identifier can be selected freely, but must not conflict with reserved words. 

The identifier can be identival with another one used outside of the procedure or function. In this case, the locale identifier hides the external one.

However, it proved to be reasonable to classify the variable identifiers depending on the data type according to the following letters:
<!STBL>
<!r>Real :<!><!SW>cr<!>
<!r>String :<!><!SW>cs<!>
<!r>Vector :<!><!SW>cv<!>
<!r>StringVector :<!><!SW>csv<!>
<!ETBL>
Individual identifiers are separated by commas.

 <b>'Type'</b>
indicates the data type of the previously listed variables. The allowed types are <!RW>REAL, <!RW>STRING and <!RW>VECTOR. The type is optional as the data type can be calculted by the given value.

 <b>'Value'</b> 
The value stored in the constant. 'Value' can be any expression that can be calculated at this time of the interpreter step, including other constants, internal and selfdefined functions. 

If a type was specified, the value has to be of this type. Otherwise the type of the constant will be determined by the value
>>

<<
1.1.4
Libraries
$NoSort
--
A <b>Library</b> is used to keep routines, taht will be used in more than only one interpreter step.
Instead of re-writing the routines in every single step, the code of the routine is defined only in the library and the library is included to the step with the <!RW>USES command.
This way, the code has to be written (and maintained!) only one time.
Libraries can use other libraries themself. Only a backward reference is not posible. I.e. if <!SW>LibraryA uses <!SW>LibraryB, then <!SW>LibraryB can't use <!SW>LibraryA.

A library has the following structure:
<!SYN>
LIBRARY;
[<a href="1.1.3.2">Variable/Constant List/s</a>]
[<a href="1.1.3.3">Library Calls</a>]
[<a href="1.1.3.4">Procedure/Function Definitions</a>]
END.
<!TXT>

Mandatory are only the reserved Words <b>LIBRARY</b> and <b>END.</b> - Mind the dot after the END, it's the only place, where the END is followed by a dot (except of the END of a step)!

All other elements are optional, but they have to be in the shown order, if they are used.

The option to define constants and variables inside a library, but outside of a procedure or function was implemented in build 978.

Since the variables and constants are defined before the call to other libraries, they are 'visible' and usable in called and calling libraries resp. the calling step.

Procedures and functions in the librarie can only be used by the calling library/step, because they are not defined when the called libraries are scanned.
>>

<<
1.1.6
Operators
$NoSort
--
If not specified differently, the operators are defined only for numeric operands
>>
<<
1.1.6.1
Operators with numeric result|numeric
$NoSort
--
These operators return a REAL value as result.
>>
<<
1.1.6.1.1
- Numeric Negation| (unary)
--
Inverts the algebraic sign of the operand
<!CODE>
 rA:=3;
 rB:=-rA;   // Result : rB = -3
>>
<<
1.1.6.1.2
+ Addition|+
--
Adds two numeric values:

<!CODE>
 rA:=3;  rB:=4;
 rC:=rA + rB;   // Result : rC = 7
>>
<<
1.1.6.1.3
- Substraction|-
--
Substracts the second operand from the first

<!CODE>
 rA:=3;  rB:=4;
 rC:=rA - rB;   // Result : rC = -1;
>>
<<
1.1.6.1.4
* Multiplication|*
--
Multiplies the two operands

<!CODE>
 rA:=3;  rB:=4;
 rC:=rA * rB;   // rC = 12;
>>
<<
1.1.6.1.5
/ Division |/
--
Divides the first operand by the second

<!CODE>
 rA:=3;  rB:=4;
 rC:=rA / rB;   // rC = 0.75;
<!TXT>

<!REM>
Important: the second operand must not be zero!
>>
<<
1.1.6.1.6
DIV Integer Division|DIV
--
Divides the first operand with the second (like /), but returns only the integer part of the result.

<!CODE>
 rA:=7;  rB:=3;
 rC:=rA DIV rB; // rC = 2; (7/3=2 Remainder 1)
<!TXT>

<!REM>
Important: 
The second operand must not be zero!
>>
<<
1.1.6.1.7
MOD Remainder of Integer Division|MOD
--
Divides the first integer operand with the second integer operand and returns the remainder.

<!CODE>
 rA:=7;  rB:=3;
 rC:=rA MOD rB; // rC = 1; (7/3=2 Remainder 1)
<!TXT>

<!REM>
Important: 
The second operand must not be zero!
>>

<<
1.1.6.2
Bit Operators|bitwise
$NoSort
--
These operators return a 32 bit integer as result.
The operands are converted automatically into a 32 bit integer.

<h4>Important!</h4>
There is an important difference between bitwise operationen like <!SW>!, <!SW>&, <!SW>| and <!SW>^ and their binary counter parts <!SW>NOT, <!SW>AND, <!SW>OR and <!SW>XOR !

For bitwise (binary) operations the operands will be converted in 32 bit integrs and the operands will be modified bit-by-bit, the return value is a 32 bit integer. 

For logical operations the operands will be converted in a logical value (<!RW>TRUE or <!RW>FALSE) and the returned value is a logical value too.

Beispiel 
<!CODE>
var
  rA : real = 3;
  rB : real = 4;
  rC : real;
begin
  // AND - combination
  rC := rA & rB;        // binary  rC=0
  rC := rA AND rB;      // logical rC=1 (true)

  // OR - combination
  rC := rA | rB;        // binary  rC=7
  rC := rA OR rB;       // logical rC=1 (true)

  // NOT - combination
  rC := !rA;            // binary  rC=$FFFFFFF8
  rC := NOT rA;         // logical rC=0 (false)
<!TXT>
>>
<<
1.1.6.2.1
! Binary Negation|!
--
Returns the ones complement of the operands as 32 Bit integer

<!CODE>
rA:=$00000001;
rB:=!rA;   // rB = $FFFFFFFE
>>
<<
1.1.6.2.2
Binary AND|&
--
Executes a bit by bit AND of the two operands

<!CODE>
rA:=6;  rB:=5;
rC:=rA & rB;   // rC = 4;
>>
<<
1.1.6.2.3
Binary OR||
--
Executes a bit by bit OR of the two operands

<!CODE>
rA:=6;  rB:=5;
rC:=rA | rB;   // rC = 7;
>>
<<
1.1.6.2.4
^ Binary XOR |^
--
Executes a bit by bit Exclusive OR of the two operands

<!CODE>
rA:=6;  rB:=5;
rC:=rA ^ rB;   // rC = 3;
>>
<<
1.1.6.2.5
SHL SHift-Left - Binary Left-Shift|SHL
--
Shifts the first operand to the left by the number of bits indicated by the second operand. The 'new', filling bits are 0. Per bit, this corresponds to a multiplication by 2, as long as no bits are shifted out to the left. No error occurs during the shiftout (error-free overrun). If the second operand is greater than 31, then the result is guaranteed to be 0. The second operand must be greater than or equal to 0.

<!CODE>
rA:=6;  rB:=2;
rC:=rA SHL rB;   // rC = 24;  (6 *2 *2)
>>
<<
1.1.6.2.6
SHR SHift-Right - Binary Right-Shift|SHR
--
Shifts the first operand to the right with the number of bits indicated by the second operand. The 'new', shifted bits are 0. Per bit, this corresponds to a division by 2, with integers. If the second operand is greater than 31, then the result is guaranteed to be 0. The second operand must be greater than or equal to 0.

<!CODE>
rA:=6;  rB:=2;
rC:=rA SHR rB;   // rC = 1;  ((6 DIV 2) DIV 2)
>>
<<
1.1.6.3
Logical Operators|Logical
$NoSort
--
These operators return the result of as logical value <!RW>TRUE or <!RW>FALSE. 
Since there are only <!RW>REAL data type values available, the operators return 1 for <!RW>TRUE and 0 for <!RW>FALSE.

The operands are converted automatically into a logical value. Thus: 0 = <!RW>FALSE, <b>every (sic!)</b> other value is <!RW>TRUE.

A special form of the logical operators are the relational operators, which are described separately.
>>
<<
1.1.6.3.1
NOT Logical Negation|NOT
--
Returns the logical opposite of the operand

<!CODE>
rA:=TRUE;
rB:=NOT rA;   // rB = FALSE
>>
<<
1.1.6.3.2
AND Logical|AND
--
Considers the operands to be logical values and carries out an AND-connection.

<!CODE>
rA:=6;  rB:=5;
rC:=rA AND rB;   // rC = 1; (TRUE)
>>
<<
1.1.6.3.3
OR Logical|OR
--
Considers the operand to be logical values and carries out an OR-connection.

<!CODE>
rA:=6;  rB:=5;
rC:=rA OR rB;   // rC = 1; (TRUE)
>>
<<
1.1.6.3.3
XOR Logical|XOR
--
Considers the operands to be logical values and carries out an Exclusive-OR-connection

<!CODE>
rA:=6;  rB:=5;
rC:=rA XOR rB;   // rC = 0; (FALSE)
>>

<<
1.1.6.4
String Operators|String
$NoSort
--
These operators return a string value.is a string.
>>
<<
1.1.6.4.1
+ Concatenation|+
--
Concatenates two strings 

<!CODE>
sA:='Hello';  sB:='World';
sC:=sA + ' '+ sB;   // sC = 'Hello World'
>>

<<
1.1.6.4.2
[ ] Access to String Element|[ ]
--
Returns one character of a string. The characters of the string are addressed by their index (their position in the string). The first character's index is 1.
The result of a read access after the end of a string is always ''. The write access after the end of the string is ignored.

<!CODE>
sA:='Hall';
sC:=sA[2];     // sC = 'a' (the 2. element of the string)
sC:=sA[7];     // sc = ''  (empty, because it was read beyond the end)
sA[2]:='i';    // sA = 'Hill' (2. element of the string is modified)
sA[7]:='e';    // sA = 'Hill' (no modification, because it was beyond the end)
>>


<<
1.1.6.5
Vector / StringVectpr Operators|Vector / StringVector
$NoSort
--
These operators return a vector or a stringvector.
>>

<<
1.1.6.5.1
+ Concatenation|+
--
Concatenates two vectors or stringvectors

<!CODE>
vA:=[1,2,3];  vB:=[4,5];
vC:=vA + vB;   // vC = [1,2,3,4,5]

svA:=['Hello','World'];  svB:=['with','cPCI'];
svC:=vA + vB;   // svC = ['Hello','World','with','cPCI']
>>

<<
1.1.6.5.2
[ ] Access to Vectors Element|[ ]
--
Returns an element of a vector / stringvector. The elements of the vector / stringvector are addressed over their index (their position in the vector / stringvector). The first element's index is 1.
The result of a read access after the end of a vector / stringvector is always 0. The write access after the end of the vector / stringvector extends the vector / stringvector to the suitable length.

<!CODE>
vA:=[1,2,4,8,16];
rC:=vA[3];      // rC = 4 (the 3. element of the vector)
rC:=vA[7];      // rC = 0 (read over the end)
vA[3]:=12;      // vA = [1,2,12,8,16] (the 3. element is now 12)
vA[7]:=12;      // vA = [1,2,12,8,16,0,12] (the 7. element is now 12, new elements are 0)

svA:=['Hello','World','with','cPCI'];
rC:=svA[3];     // rC = 'with' (the 3. element of the Vector)
rC:=svA[6];     // rC = '' (read over the end)
svA[3]:='in';   // vA = ['Hello','World','in','cPCI'] (3. element is now 'in')
svA[6]:='now';  // vA = ['Hello','World','in','cPCI','','now'] (6. element is now 'now', new element is '')
>>

<<
1.1.6.6
relational operators|relational
$NoSort
--
These operators compare the two operands and return a logical value <!RW>TRUE (1) or <!RW>FALSE (0).

Only operands of the same data type (Real with Real, String with String etc.) can be compared.

Strings are compared character by character based on the index in the extended ASCII set.  
>>
<<
1.1.6.6.1
= Equal|=
--
Returns <!RW>TRUE (1), if the left operand is equal to the right operand, otherwise <!RW>FALSE (0)

numeric 
<!CODE>
rA:=3;  rB:=4;
rC:=rA = rB;   // rC = FALSE (0)
<!TXT>

String 
<!CODE>
sA:='Hallo';  sB:='Welt';
rC:=sA = sB;   // rC = FALSE (0)
<!TXT>
 
Vector
<!CODE>
vA:=[1,2];  vB:=[3,4];
rC:=vA = vB;   // rC = FALSE (0)
<!TXT>

StringVector
<!CODE>
svA:=['Hello','World'];  svB:=['Hans','Otto'];
rC:=vA = vB;   // rC = FALSE (0)
<!TXT>
>>
<<
1.1.6.6.2
&lt;&gt; Unequal|<>
--

Returns <!RW>TRUE (1), if the left operand is not equal to the righ operand, otherwise <!RW>FALSE (0)

numeric
<!CODE>
rA:=3;  rB:=4;
rC:=rA &lt;&gt; rB;   // rC = TRUE (1)
<!TXT>

String
<!CODE>
sA:='Hallo';  sB:='Welt';
rC:=sA &lt;&gt; sB;   // rC = TRUE (1)
<!TXT>

Vector
<!CODE>
vA:=[1,2];  vB:=[3,4];
rC:=vA &lt;&gt; vB;   // rC = TRUE (1)
<!TXT>

StringVector
<!CODE>
vA:=['Hello','World'];  vB:=['Hans','Otto'];
rC:=vA &lt;&gt; vB;   // rC = TRUE (1)
<!TXT>
>>
<<
1.1.6.6.3
&lt; Less Than|<
--

Returns <!RW>TRUE (1), if the left operand is less than the right operand, otherwise <!RW>FALSE (0)

numeric
<!CODE>
rA:=3;  rB:=4;
rC:=rA &lt; rB;   // rC = TRUE (1)
<!TXT>

String
<!CODE>
sA:='Hallo';  sB:='Welt';
rC:=sA &lt; sB;   // rC = TRUE (1)
<!TXT>

Vector and stringvector are not allowed
>>
<<
1.1.6.6.4
&lt;= Less Than or Equal|<=
--

Returns <!RW>TRUE (1), if the left operand is less than or equal to the right operand, otherwise <!RW>FALSE (0)

numeric
<!CODE>
rA:=3;  rB:=4;
rC:=rA &lt;= rB;   // rC = TRUE (1)
<!TXT>

String
<!CODE>
sA:='Hallo';  sB:='Welt';
rC:=sA &lt;= sB;   // rC = TRUE (1)
<!TXT>

Vector and stringvector are not allowed
>>
<<
1.1.6.6.5
&gt; Greater Than|>
--

Returns <!RW>TRUE (1), if the left operand is greater than the right operand, otherwise <!RW>FALSE (0)

numeric
<!CODE>
rA:=3;  rB:=4;
rC:=rA &gt; rB;   // rC = FALSE (0)
<!TXT>

String
<!CODE>
sA:='Hallo';  sB:='Welt';
rC:=sA &gt; sB;   // rC = FALSE (0)
<!TXT>

Vector and stringvector are not allowed
>>
<<
1.1.6.6.5
&gt;= Greater Than or Equal|>=
--

Returns <!RW>TRUE (1), if the left operand is !!less!! than or equal to the right operand, otherwise <!RW>FALSE (0)

numeric
<!CODE>
rA:=3;  rB:=4;
rC:=rA &gt;= rB;   // rC = FALSE (0)
<!TXT>

String
<!CODE>
sA:='Hallo';  sB:='Welt';
rC:=sA &gt;= sB;   // rC = FALSE (0)
<!TXT>

Vector and stringvector are not allowed
>>

<<
1.1.6.7
Conditional operator ?:|Conditional operator
$NoHelpDebug
--
The ternary conditional operator is written as follows:
<!SYN>
Condition <!TW>? TrueValue <!TW>: FalseValue
<!TXT>
If the <!PW>Condition is <!RW>True, the operator will return the <!PW>TrueValue zurck, otherwise the <!PW>FalseValue. This operator has been taken from the programming language C.

 <!PW>TrueValue and <!PW>FalseValue can be of different data type, if the receiver of the resulting values allows so.

The operator works as this (hypothetical) function:
<!CODE>
function ConditionOperator (Condition : real; TrueValue, FalseValue : real|string|vector|stringvector) : real|string|vector\stringvector;
begin
  if Condition then return (TrueValue)
               else return (FalseValue);
end;
<!TXT>
        
<!REM>
implemented in build 1003
<!TXT>
>>

<<
1.1.7
Instruction
$NoSort
--
<h3>Instructions</h3>
Instructions define the actions in an interpreter step.
The interpreter executes the specified instructions consecutively.

Several instructions (e.g.assignemnts and procedure calls) can be combined. This is how loops, conditioned instructions and other structured instructions are created.

Several instructions are separated by semicolons.

Syntactically, an instruction is expressed as follows:

<!SYN>
Instruction :=
   SimpleInstruction |
   StructuredInstruction

SimpleInstruction :=
   <a HREF="1.1.7.1">Assignment</a> |
   <A HREF="1.1.7.2">VOIDAssignment</a> |
   <A HREF="1.1.7.3">ProcedureCall</a> |
   <A HREF="1.1.7.4">COMInstruction</a> |
   <A HREF="1.1.7.4">NETInstruction</a>

StructuredInstruction :=
   <A HREF="1.1.7.5">RepeatUntilLoop</a> |
   <A HREF="1.1.7.6">WhileDoLoop </a> |
   <A HREF="1.1.7.7">ForLoop</a> |
   <A HREF="1.1.7.8">CaseBranch </a> |
   <A HREF="1.1.7.9">IfBranch</a> |
   <A HREF="1.1.7.10">BeginEndBlock</a>
<!TXT>
>>
<<
1.1.7.1
Assignment
--
<h3>Assignments</h3>
An assignment is used to give a variable or an element of a variable a new value.

An assignemnt has the following structure:
<!SYN>
Variable := Expression
<!TXT>
where Variable is any element whose value can be modified. This variable can be a 'real' variable defined with VAR, an element of a variable which has several elements or a property of a COM- or Net- Object. 
The data type of the expression must match the data type of the variable.

The symbol <b><!CW>:=</b> is the assignment operator.
An assignment replaces the current value of the variable with the value of the expression. The following assignment replaces e.g. the current value of the variable rI with the value 3:
<!CODE>
rI := 3;
<!TXT>

The variable reference on the left side of the assignment can be present in the expression on the right side as well:
<!CODE>
rI := rI + 1;
<!TXT>
This assignment increases the value of rI by 1. 

Here are some other examples of assignments:
<!CODE>
rX := rY + rZ;
rDone := (rI >= 1) and (rI < 100);
rI := Sqr(rJ) - rI  * rK;
sMyString := 'A';
vSomeVector[I + 1] := rP;
MyCOMObject.SomeProperty := True;
MyNetObject.SomeProperty := True;
<!TXT>
>>
<<
1.1.7.2
VOID Assignment |VOID
--
With the help of a VOID assignment the result of a function call can be ignored.

A VOID assignment has the following structure:
<!SYN>
VOID Expression
<!TXT>
This form can be used if the called function has a wanted side-effect but the return value of the function is not used. Thus, the function becomes a procedure practically. 

The <b>expression</b> must not necessarily be a function call; a <!RW>VOID instruction like:
<!SYN>
VOID 1+2*3+4;
<!TXT>
is syntactically valid, but it doesn't make much sense.
>>
<<
1.1.7.3
ProcedureCall
--
A procedure call consists of the name of the procedure (if necessary, with interpreter-Object-Name) and (if required) the parameter list. 
The number and the data type of the parameters must match the called procedure. The parameters transferred to a routine are called real parameters - contrary to the formal parameters in the declaration of the routine.

Here are some examples of procedure calls:
<!CODE>
StartTest;
SetValue (rMW);
ME3000.ADC.Sample.Setup (10000, 1000, 0);
<!TXT>

When a procedure is called, the control is transferred from the point of call to the body of the routine, the procedure is processed until its end or until a Return and afterwards the instruction following the procedure call is processed.
>>
<<
1.1.7.4
COMInstruction
!128.118
--
With the help of ComInstructions the properties of the COM-Objects referenced in COMObject Variables can be modified or the methods of these objects can be called. 
The exact syntax of this access depends on the respective COM-Object.

Assignment to properties:
<!SYN>  
ComVariable[.SubObject[...]].Property := Expression
<!TXT>
Thus the popertiy of a COM-Object (or of one of its sub-objects) is used similarly to a variable.

Call of a method:
<!SYN>  
ComVariable[.SubObject[...]].Methode [(ParameterListe)]
<!TXT>
>>
<<
1.1.7.5
Repeat-Until Loop|Repeat Until
--
The syntax for a repeat-instruction is:
<!SYN>
<!RW>repeat 
  Instruction1; 
  ...; 
  InstructionN; 
<!RW>until Expression
<!TXT>
The <b>expression</b> must return a Real value which is evaluated logically (0=<!RW>false, Not-0=<!RW>true). All the instructions between <!RW>repeat and <!RW>until are executed sequentially. The specified expression is evaluated after each run. If the expression returns the value <!RW>True, then the repeat-instruction is ended. Since the expression is valuated only at the end of the first iteration, the instruction sequence is run at least once.

Here are some examples of repeat-instructions:
<!CODE>
repeat
  rK := rI mod rJ;
  rI := rJ;
  rJ := rK;
until rJ = 0;

repeat
  SetValue (ME3000.ADC.Get (1));
until StepContinue;
<!TXT>

Empty Repeat-loop, only waites for <a href="128.10.2.1">StepContinue</a> is <!RW>true:
<!CODE>
repeat
until stepcontinue;
<!TXT>
in this empty Repeat Until Loop a doze is executed automatically; thus the loop corresponds to the following loop
<!CODE>
repeat
  Doze;
until stepcontinue;
<!TXT>
>>

<<
1.1.7.6
While-Do Loop |While Do
--
A while-instruction resembles in many aspects to a repeat-instruction. However the condition is valuated before the first execution of the instruction sequence. If the result of the condition is <!RW>False, then the instruction sequence is not carried out.

The syntax of a while-instruction is:
<!SYN>
while Expression do Instruction
<!TXT>
The <b>expression</b> must return a real-value which is evaluated logically (0=<!RW>false, Not-0=<!RW>true).

The <b>instruction</b>, out of readability and maintainability reasons, should be always a CompoundInstruction (<a href="1.1.7.10">Begin-End</a>). 
The <!RW>while instruction executes the <b>instruction</b> repeatedly and evaluates the specified expression before each new run. If the result of the expression is <!RW>True, then the execution is continued after the <!RW>While instruction.

Here are some examples of while-instructions:
<!CODE>
while vData[rI] &lt;&gt; rX do Inc(rI);

while rI &gt; 0 do begin
  if Odd(rI) then rZ := rZ * rX;
  rI := rI div 2;
  rX := Sqr(rX);
end;

MeasData.First;
while not MeasData.Eof do begin
  ProcessMeasValue;
  MeasData.Next;
end;
<!TXT>

Empty While-Do loop, only waites for <a href="128.10.2.1">StepContinue</a>=<!RW>TRUE:
<!CODE>
while not StepContinue do;
<!TXT>
>>

<<
1.1.7.7
For-To-Do Loop|For To Do
--
Contrary to the repeat- and while-instruction, in case of a for-instruction it is specified, how many times should the loop be run. 

The syntax of a for-instruction:
<!SYN>
for Counter := InitialValue to FinalValue [Step Increment] <!RW>DO instruction
<!TXT>

The <b>counter</b> is a local Real-Variable. 

 <b>InitialValue</b>, <b>FinalValue</b> and the optional <b>Increment</b> are real expressions.

 <b>Instruction</b> is a simple or structured instruction. For readability and maintainability reasons a Begin-End Block should always be used.

The <!RW>FOR-instruction assigns the InitialValue to Counter and then executes repeatedly the instruction. After each run the Increment (1, if not specified) is added to the counter variable. If the value of the Counter reaches or exceeds the FinalValue (resp. falls below it, if the Increment is negative), the <!RW>FOR-instruction is ended. Thus the instruction is executed once for each step value which is within the range of the InitialValue and FinalValue. If the initial and the final value are identical, then the instruction is executed just once. If the initial value in a for-instruction with positive increment is greater than the final value, then the instruction is not executed at all. The same applies to a for-instruction with negative increment where the initial value is less than the final value. An increment of 0 is not allowed.

The expressions InitialValue and FinalValue are evaluated only one time for the activation of the loop execution before the beginning of the loop. The for...to-instruction strongly resembles the following while-structure:
<!CODE>
begin
  Counter := InitialValue;
  while Counter &lt;= FinalValue do begin
    Instruction;
    Counter := Counter+Increment;
  end;
end
<!TXT>

Contrary to the for...to-instruction, the FinalValue in the while-loop is valuated before each run. If the FinalValue is a complex expression, then this can yield a slowdown of the execution speed. In addition, the modifications generated by the instruction to the final value can affect the execution of the loop.

Here some examples of for-instructions:
<!CODE>
for rI := 2 to 63 do begin
  if vData[rI] > rMax then begin
    rMax := vData[rI];
  end;
end;

rSum:=0;
for rI := 1 to prAverages do begin
  rSum:=rSum+sqr(ME3000.ADC.Get(1));
end;
SetValue (sqrt(rSum/prAverages));
<!TXT>
>>

<<
1.1.7.8
Case Branch |Case
--
The case-instruction is an alternative to the if-instruction which should be implemented used due to better readability in case of complex nestings. 

The syntax of a case-instruction:
<!SYN>
<!RW>CASE Selector <!RW>OF
  CaseList : Instruction;
 [CaseList : Instruction;
  ..]
 [<!RW>ELSE Instruction;]
<!RW>END
<!TXT>

where <b>Selector</B> is Real or String expression. 

 <b>CaseList</b> can be:

If the expression is of the <!RW>Real type:
<ul indent=12>
<li>a Real expression</li>
<li>a range, specified with RealExpression .. RealExpression</li>
<li>a list of the two mentioned possibilities, separated by comma</li>
</ul>

If the expression is of the <!RW>String type: 
<ul indent=12>
<li>a StringExpression</li>
<li>a list of StringExpressions, separated by comma</li>
</ul>

If the interpreter finds a <!RW>CASE instruction, it will evaluate the  value of the <b>Selector</b> one time. Afterwards a search is started for the first <b>CaseList</b> where the expression is included. The instruction for this list is executed. Then the entire Case-instruction is quitted. 

Thus, maximum one instruction is executed (this instruction can of course be a Begin-End block)

If the expression is not found in any of the CaseLists, then the optional <!RW>Else instruction is executed. If no Else branch is specified, nothing is done.

The <!RW>CASE Instruction
<!CODE>
case rI of
  1..5      : sText := 'Low';
  6..9      : sText := 'High';
  0, 10..99 : sText := 'Out of range';
  else        sText := '';
end;
<!TXT>
is identical to the following nested if...then...else-instruction:
(but much more simple to understand and maintain)
<!CODE>
if (rI&gt;=1) and (rI&lt;=5) then begin
  sText := 'Low';
end
else begin
 if (rI&gt;=6) and (rI&lt;=10) then begin
    sText := 'High'
  end
  else begin
    if (rI=0) or ((rI&gt;=10) and (rI&lt;=99)) then begin
      sText := 'Out of range'
    end
    else begin
      sText := '';
    end;
  end;
end;
<!TXT>

Another example:
<!CODE>
case sData[1] of
  'P' : Result:=1;
  'F' : Result:=2;
  'I' : Result:=3;
  else  Result:=0;
end;
<!TXT>
>>
<<
1.1.7.9
If-Then / If-Then-Else Branch|If Then
--
The syntax of an <!RW>if-instruction:
<!SYN>
<!RW>IF LogicalExpression <!RW>THEN TrueInstruction [<!RW>ELSE FalseInstruction]
<!TXT>
The result of <b>LogicalExperssion</b> has to be a real value which is valuated logically (0=<!RW>false, Not-0=<!RW>true). 
The <b>TrueInstruction</b> will be excuted only if the expression was <!RW>true. 
The <b>FalseInstruction</b> is only exectued, if the expression was <!RW>false.

The then- and else-clauses can be followed only by one instruction. This can be (and should always be) a compound instruction (<a href="1.1.7.10">BEGIN-END</a>).
<!CODE>
if J <> 0 then begin
  Result := I/J;
  Count := Count + 1;
end
else begin
  if Count = Last then begin
    Done := True
  end;
end;
<!TXT>

A semicolon (;) is not allowed between <!RW>THEN-clause and the word <!RW>ELSE. The semicolon is used to seperate the complete <!RW>IF instruction from the next instruction. Between <!RW>THEN and <!RW>ELSE  only a blank or a carriage return character is required. 

Using a semicolon before the word <!RW>ELSE (in an IF-instruction) is one of the most frequent programming errors, because this way the short form of the IF-instruction is terminated and the interpreter tries to process ELSE as an instruction of its own.

Nested IF-instructions (without Begin-End Blocks) can also lead to programming errors if some IF-instructions may have ELSE-clauses while others don't. If in a sequence of IFs there are less ELSE-clauses than IF-clauses, then it is possible that the assignment of the ELSE-clause to the IF-clause cannot be clearly identified. Thus the instruction:
<!CODE>
if Expression1 then if Expression2 then Instruction1 else Instruction2;
<!TXT>
could be interpreted in two ways:
<!CODE>
if Expression1 then [ if Expression2 then Instruction1 else Instruction2 ];
<!TXT>
<font size=-1>oder</font>
<!CODE>
if Expression1 then [ if Expression2 then Instruction1 ] else Instruction2;
<!TXT>

The compiler always uses the first interpretation. This means that the instruction
<!CODE>
if Expression1 then if Expression2 then Instruction1 else Instruction2
<!TXT>
is identical to this structure:
<!CODE>
if Expression1 then begin
  if Expression2 then begin
    Instruction1;
  end
  else begin
    Instruction2;
  end;
end;
<!TXT>

However the second form is easier to understand and maintain.
>>
<<
1.1.7.10
Compound Instructions / Begin-End Block|Begin End
--
A compound instruction is made up of a sequence of other (simple or structured) instructions which are executed in the specified sequence. The individual instructions contained by a compound instruction are enclosed between the reserved words <!RW>BEGIN and <!RW>END and separated by semicolons. 

Syntax:
<!SYN>
<!RW>BEGIN
  [Anweisung; ..]
<!RW>END
<!TXT>
Compound instructions are important if the syntax requires precisely an instruction. They can be integrated into program-, function- and procedure blocks and in other structured instructions (e.g. conditional instructions or loops):

<!CODE>
I := SomeConstant;
while I > 0 do  begin
  ...
  I := I - 1;
end;
<!TXT>

There are also compound instructions which contain only one instruction. Similar to the parenthesis used in complex expressions, the words <!RW>begin and <!RW>end can prevent ambiguity and ensure a better readability. 
<!CODE>
if i &lt; 10 then begin
  SendAndWait;
end;
<!TXT>  

With an empty compound instruction, it is also possible to generate a block which does not carry out any actions:
<!CODE>
begin
end;
<!TXT>
>>
<<
1.1.7.11
NetInstruction
!128.118
--
With NetInstructions Properties and methods of .Net classes could be used. The exactly syntax is dependent of the used .Net Class.

Assignment to properties:
<!SYN>  
NetVariable[.UnterObjekt[...]].Property := Expression
<!TXT>

Call of a method:
<!SYN>
NetVariable[.UnterObjekt[...]].Methode [(ParameterListe)]
<!TXT>
>>
<<
128 
IP-Objects
$Open
--
>>


<<
200
IP Error Messages
$NoSort
--
>>
<<
200.1
1 EXIT-Command
--
The step has been aborted with the <!RW>EXIT command
>>
<<
200.2
2 ABORT
--
The step was aborted manually with the ABORT button.
>>
<<
200.3
3 unexpected exception
--
The step was stopped by an unexpected exception. Please inform MCD.

The exception might have been thrown in an external DLL, a COM object or a .Net class. If this DLL, COM object or .Net class was not supplied by MCD, please contact the supplier of the DLL / COM object / .Net class.
>>
<<
200.4
4 test aborted
--
A running test was aborted. That canceled the IP step.
>>
<<
200.5
5 Callstack overflow
--
The IP step uses a group of functions or procedures that call themself again and again. (Catchword: Recursive programming) 
This only possible up to a certain limit. Most probably there is a programming error (for example a missing stop condition). 

Example:
<!CODE>
// Calculate x! (no stop condition)
function FAK (n : real) : real;
begin
  Result:=FAK(n-1)*n;
end;

// correct would be:
// (but still limited to the maximum call depth)
function FAK2 (n : real) : real;
begin
  if n&lt;=1 then return (n);
  Result:=FAK2(n-1)*n;
end;

// or (better and faster, since without recursion)
// (only limited by the value range of the datatype)
function FAK3 (n : real) : real;
begin
  Result:=1;
  for n:=2 to n do begin
    Result:=n*Result;
  end; 
end;
<!TXT>
>>
<<
200.11
11 identifier already used as name of variable
--
The identifier, that should be used as name of a variable, has already been used as name of a parameter or variable.

ExampleBeispiel:
<!CODE>
parameter
  rDelay : (1, real, 'Pre-Step-Delay [ms]', '1..100');

var
  rLoop : real;
  <font color=red>rDelay</font> : real;

static
  <font color=red>rLoop</font> : real;
<!TXT>

Remedy:
<ul indent=12>
<li>use another name</li>
<li>stick to the recommended naming scheme (Variables start with v, r, s or co depending on the data type, parameters with ps, and pr)</li>
</ul>
>>

<<
200.12
12 identifier already used as name of parametername
--
The identifier, that should be used as name of a parameter, has already been used as name of a parameter.

Example:
<!CODE>
parameter
  psDelay : (1, real, 'Pre-Step-Delay [ms]', '1..100');
  <font color=red>psDelay</font> : (3, real, 'Repeat-Delay [ms]',   '10..1000');
<!TXT>

Remedy:
<ul indent=12>
<li>use another name</li>
</ul>
>>

<<
200.13
13 identifier is a reserved word
--
The identifier is used by the interpreter internally as a reserved word.

Example:
<!CODE>
parameter
  <font color=red>Delay</font> : (1, real, 'Pre-Step-Delay [ms]', '1..100');

procedure <font color=red>Option</font>;
begin
end;
<!TXT>

This error can happen, if the interpreter learns new functions, and words that hitherto were not reserved get reserved words.

Remedy:
<ul indent=12>
<li>use another name</li>
</ul>

Precautionary:
<ul indent=12>
<li>stick to the recommended naming scheme (Variables start with v, r, s or co depending on the data type, parameters with ps, and pr)</li>
<li>use expressive and non-trivial procedure and function names. Reserved words will be always short and simple. So it is better to use Names that consist of more than one word as function and procedure names.</li>
</ul>

Example:
<!CODE>
parameter
  prDelay : (1, real, 'Pre-Step-Delay [ms]', '1..100');

procedure ReadOption;
begin
end;
<!TXT>
>>

<<
200.14
14 symbol already defined
--
The name is already used for something else or is used internally.

Example:
<!CODE>
var
  ReadData : string;

function <font color=red>ReadData</font> : string;
begin
end;
<!TXT>

Remedy:
<ul indent=12>
<li>use another name</li>
</ul>

Precautionary:
<ul indent=12>
<li>stick to the recommended naming scheme (Variables start with v, r, s or co depending on the data type, parameters with ps, and pr)</li>
<li>use expressive and non-trivial procedure and function names. Reserved words will be always short and simple. So it is better to use Names that consist of more than one word as function and procedure names.</li>
</ul>
>>

<<
200.15
15 circular uses reference
--
A library calls itself in its <!RW>uses part, or more than one library have a cyclic <!RW>uses construct.

Example:
File: <pre>LIB_ONE.IPS</PRE>
<!CODE>
library;

uses
  'LIB_TWO';
<!TXT>

File: <pre>LIB_TWO.IPS</PRE>
<!CODE>
library;

uses
  <font color=red>'LIB_ONE'</font>;
<!TXT>

Remedy:
Remove the cyclic calls.

Libraries may call other libraries, but not in a way that a cyclic structure evolves.

A diagram of the used libraries must always rlead to a tree without loops.

In very special cases, code out of two libraries depending on each other has to be copied in one library.
>>

<<
200.20
99 ERROR
--
This error is triggered with the <!RW>Error command.

It is not reported by the syntax check.
>>

<<
200.41
2002 ':=' expected
--
The interpreter expected the assignment operator (:=) here (after a variable).
>>
<<
200.42
2003 ';' expected
--
The interpreter expected a semicolon (;) here (after a complete instruction).
>>
<<
200.43
2004 ':' expected
--
The interpreter expected a colon here.
>>
<<
200.44
2005 '[' expected
--
The interpreter expected an opening square bracket here.
>>
<<
200.45
2006 invalid symbol
--
The symbol is invalid. Most probably the character in the source code in not allowed (e.g. an umlaut).
>>
<<
200.46
2007 '(' expected
--
The interpreter expected an opening round bracket here.
>>
<<
200.47
2008 ')' expected
--
The interpreter expected a closing round bracket here.
>>
<<
200.48
2009 '.' expected
--
The interpreter expected a period.

Periods are needed after the last END of a step or a library and as separator in IP object calls.
>>
<<
200.49
2010 '..' expected
--
The interpreter expected two periods (..).
>>
<<
200.50
2011 ',' expected
--
The interpreter expected a comma as separator of two parameter or identifiers.
>>
<<
200.51
2012 'STEP' expected
--
The interpreter is looking for the start of a step and expects the reserved word <!RW>STEP.
>>
<<
200.52
2013 'THEN' expected
--
The interpreter is looking for the reserved word <!RW>THEN after the expression of an <!RW>IF instruction.
>>
<<
200.53
2014 'DO' expected
--
The interpreter is looking for the reserved word <!RW>DO after the expression of an <!RW>WHILE instruction.
>>
<<
200.54
2015 'UNTIL' expected
--
The interpreter is looking for the reserved word <!RW>UNTIL after the body of an <!RW>REPEAT instruction.
>>
<<
200.55
2016 'END' expected
--
The interpreter is looking for the reserved word <!RW>END after the reserved word <!RW>BEGIN. Most probably, a <!RW>BEGIN-<!RW>END block was opened but not closed.
>>
<<
200.56
2017 'TO' expected
--
The interpreter is looking for the reserved word <!RW>TO after the start expression of an <!RW>FOR instruction.
>>
<<
200.57
2021 'OF' expected
--
The interpreter is looking for the reserved word <!RW>OF after the selector expression of an <!RW>CASE instruction.
>>
<<
200.58
2022 address expected
--
The interpreter expected an addresse out of the <!SW>UMSCards.DAT or the <!SW>UMSAdres.DAT file.
>>
<<
200.59
2023 invalid string
--
The string given is not correct. For example, the closing <b>'</b> could be missing.
>>
<<
200.60
2024 real expression expected
--
The interpreter expected an expression that has a numeric value.
>>
<<
200.61
2025 variable expected
--
The interpreter expected a variable.
>>
<<
200.62
2026 string expression expected
--
The interpreter expected an expression that has a string value.
>>
<<
200.63
2028 expression expected
--
The interpreter expected an expression.
>>
<<
200.64
2029 real variable expected
--
The interpreter expected a <!RW>REAL variable.
>>
<<
200.65
2030 string Variable expected
--
The interpreter expected a <!RW>STRING variable.
>>
<<
200.66
2031 parameter name expected
--
The interpreter expected a name of a parameter.
>>
<<
200.67
2032 parameter name already used
--
This name is already used for another parameter.
>>
<<
200.68
2033 boolean expression expected
--
The interpreter expected an expression that has a boolean value (<!RW>TRUE or <!RW>FALSE).
>>
<<
200.69
2034 parameterlist expected
--
The interpreter expected the parameter list (starting with <!RW>Parameter).
>>
<<
200.70
2035 type identifier expected
--
The interpreter expected a type designator. (<!RW>REAL, <!RW>STRING, <!RW>VECTOR, <!RW>STRINGVECTOR)
>>
<<
200.71
2036 parameter number already used
--
This parameter number was already used for another parameter.

Example:
<!CODE>
Parameter
  psWait  : (1, string, 'Delay', '');
  prDelay : (<font color=red>1</font>, real,   'Delay', '');
<!TXT>
>>
<<
200.72
2037 empty string not allowed
--
The expression did return an empty string, but an empty string is not allowed here.

Example:
<!CODE>
var
  sAlpha, sBeta : string;
step
  sAlpha:='12345';
  sBeta:='';
  sAlpha[2]:=<font color=red>sBeta</font>;
  // Assignment of an empty string to a character is not allowed
<!TXT>
>>
<<
200.73
2038 string or real value expected
--
The interpreter expected an expression that has a numeric or a string value.
>>
<<
200.74
2039 ComObject variable expected
--
The interpreter expected a <!RW>ComObject variable.
>>
<<
200.75
2040 String literal expected
--
The interpreter expected a string literal (fixed test in '').

Example:
<!CODE>
const
  sLib = 'MyLib';

uses
  <font color=red>sLib</font>;
<!TXT>
>>
<<
200.76
2041 vector/StringVector variable expected
--
The interpreter expected a <!RW>Vector or <!RW>StringVector variable.
>>
<<
200.77
2042 variable type conflict
--
The data type of the variable is not allowed here.
>>
<<
200.78
2048 typeconflict
--
The datatype given conflicts with the expected one.

Most probably, an expression resulting in one data type (e.g. string) was assigned to a variable of another data type (e.g. real).

Example:
<!CODE>
var
  sData : string;

step
  sData:=1;
<!TXT>
>>
<<
200.79
2049 Parameter out of range
--
The value of the expression here is not in the allowed range. It might be too big, too small, or not in the list of allowed values.
>>
<<
200.80
2050 step=0 not allowed
--
Since a step width of 0 would lead to an endless loop, it is not allowed in a <!RW>FOR loop.
>>
<<
200.81
2051 command expected
--
The interpreter expected the start of an instruction.
>>
<<
200.82
2052 char expected (empty string not allowed)
--
The string expression is not exatcky one character long.

No longer or empty string allowed here.
>>
<<
200.83
2053 Vector / StringVector to large
--
The number of elements in a vector/stringvector is limited to 65535.
>>
<<
200.84
2054 vector expected
--
The interpreter expected an expression that has a vector value.
>>
<<
200.85
2055 value in vector out of range
--
An element of the vector is out of range
>>
<<
200.86
2056 string or vector expected
--
The interpreter expected an expression that has a string or vector  value.
>>
<<
200.87
2057 name of address already used
--
This name is already used as name of an UMS address.
>>
<<
200.88
2058 addresses are of different type
--
The two addresses are of different types and can not be combined.
>>
<<
200.89
2059 addresses are on different boards
--
The two addresses are from different cards and can not be combined.
>>
<<
200.90
2060 CLR / SET / FLIP / NOP or (0..3) expected
--
The interpreter expected an numerical value (0/1/2/3) or one of the sereved words  <!RW>CLEAR, <!RW>SET, <!RW>FLIP or <!RW>NOP.
>>
<<
200.91
2061 STORE / SEND or (0..1) expected
--
The interpreter expected an numerical value (0/1) or one of the sereved words <!RW>STORE or <!RW>SEND.
>>
<<
200.92
2062 wrong type of address
--
The given UMS address is not of the correct type (e.g. other kind of card)
>>
<<
200.93
2063 no card at this address found
--
There is no card with this address.
>>
<<
200.94
2067 wrong type of card at this address
--
The card defined by the address is not of the correct kind for this command.
>>
<<
200.95
2068 OFF / ON or (0..1) expected
--
The interpreter expected an numerical value (0/1) or one of the sereved words <!RW>OFF or <!RW>ON.
>>
<<
200.96
2069 addresses of this type can't be ored
--
The addresses can't be combined in one command. They can be of a different type or relate to different cards.
>>
<<
200.97
2070 invalid combination or number of parameters
--
The actiual list of parameters does not match the wanted structure.
>>
<<
200.98
2071 LOW / MID / HIGH or (0..2)  expected
--
The interpreter expected an numerical value (0/1/2) or one of the sereved words <!RW>LOW, <!RW>MID or <!RW>HIGH.
>>
<<
200.99
2072 ABS/ REL or (0..1) expected
--
The interpreter expected an numerical value (0/1) or one of the sereved words <!RW>ABS or <!RW>REL.
>>
<<
200.100
2073 CONST value not allowed here
--
The interpreter expected a variable, but found a constant.
>>
<<
200.101
2074 "=" expected
--
The interpreter expected an equal sign.
>>
<<
200.102
2111 'BEGIN' expected
--
The interpreter expected a <!RW>BEGIN.
>>
<<
200.103
2112 file not found
--
The mentioned interpreter file (<!RW>STEP or <!RW>LIBRARY) could not be found.
>>
<<
200.104
2113 file is empty
--
The interpreter file (<!RW>STEP or <!RW>LIBRARY) is empty. 
>>
<<
200.105
2114 can't execute Library as STEP
--
A library can't be executed as step.

Either the test step parameter called a library directly or inside the interpreter editor, the syntax check was start for a library directly.
>>
<<
200.106
2115 'LIBRARY' expected
--
The library doesn#t start with the reserved word <!RW>LIBRARY;
>>
<<
200.107
2116 method expected
--
The interpreter object has no method with this name.
>>
<<
200.108
2117 Return not allowed in main block - use Exit instead
--
 <!RW>Return is only allowed in functions and procedures. Use <!RW>EXIT to quit from the main block.
>>
<<
200.109
2118 code after 'END.' is not allowed
--
There is unexecuted code after the <!RW>END. This code should be removed of commented out.
>>
<<
200.111
2119 unused variable
--
The variable was defined, but never used. It should be removed.
>>
<<
200.112
2120 unused parameter
--
The parameter was defined, but never used. It should be removed.
>>
<<
200.140
2410 parameter missing
--
The value in the test step parameter table is not a numerical value but empty.
>>
<<
200.141
2411 parameter is not a vaild number
--
The value in the test step parameter table is not a numerical value.
>>
<<
200.142
2412 parameter mask invalid
--
The parameter mask is not valid.
>>
<<
200.143
2414 parameter out of range
--
The value in the test step parameter table is not inside the range defined with the parameter mask.
>>
<<
200.144
2415 parameter not in list
--
The value in the test step parameter table is not listed in the parameter mask.
>>
<<
200.145
2416 invalid parameter
--
The value in the test step parameter table is invalid, e.g not a numerical value.
>>
<<
200.146
4001 exeception in DLL.Call
--
Exception in the call of <!RW>DLL.Call

Make sure, the definition in <RW>DLL.Register is correct.
>>
<<
200.147
4002 can't open DLL
--
The DLL could not be opened. Is the file name correct?
>>
<<
200.148
4003 DLL is not open
--
The DLL was not opened with <!RW>DLL.Open 
>>
<<
200.149
4004 error in parameterdefinition
--
The parameterdefinition od the <!RW>DLL.Register callis invalid
>>
<<
200.150
4005 no alias defined
--
If the routine of a DLL is registered with the index, an alias has to be given.
>>
<<
200.151
4006 error while registering procedure
--
Error in <!RW>DLL.Register. Maybe, the wanted procedure is not present in the DLL.
>>
<<
200.152
4007 procedure not registered
--
The routine called with <!RW>DLL.Call was not registered with <!RW>DLL.Register
>>
<<
200.153
4101 no port with this name defined
--
There is no port with the given name defined.
>>
<<
200.154
4120 user defined field not found
--
There is no user defined field with the given name.
>>
<<
200.155
5001 global variable not defined
--
There is no global variable with the given name and no default value has been given in the command for this case.>>
>>
<<
200.156
5011 no field in registrationform with this name
--
There is no field in the registration form with the given name and no default value has been given in the command for this case.
>>
<<
200.157
5012 registration form entity is not a combo box
--
Since the affected field of the registration form is not a combo box, this operation is not allowed.
>>
<<
200.158
5101 error loading KI-List
--
There was a problem, when loading the KI list.
Check the file format.
>>
<<
200.159
5201 invalid frame length (to long / to short)
--
The given frame is either too short or too long.
>>
<<
200.160
5202 invalid CAN identifier
--
The CAN identifier is not within its limits.
>>
<<
200.161
5203 CAN RTR flag invalid (not 0 / 1)
--
The CAN RTR flag is not within the limits (0 / 1).
>>
<<
200.162
5204 structure of CAN RTR frames invalid
--
The given vector is not a valid CAN frame.
>>
<<
200.163
5205 CAN data byte out of range
--
The byte data of the CAN frame is not in the limits (0..255 resp. -1..255).
>>
<<
200.164
5301 no synthetic measureing value existing
--
At the moment, no synthetic measured value is exitsing. Therefor, no properties of this value can be changed.

Create a synthetic measured value with <!RW>MeasData.New 
>>
<<
200.165
5302 synthetic measureing value has no such item
--
There is no existing field of a synthetic measured value with the given name.
>>
<<
200.166
5401 can't create OLE server
--
The program was unable to craete the COM server.

Maybe, the class of the COM object is not registered with the Windows COM system.
>>
<<
200.167
5402 COM object is not assigned
--
The COM variable is not assigned, i.e. it is not connected with a COM server. Therefore, it is not possible to call methods etc.
>>
<<
200.168
5403 COM method or property of object expected
--
The COM object's IDispatch interface did not report a method or property with this name.
>>
<<
200.169
5404 COM method or property of object not found
--
The COM object's IDispatch interface did not report a method or property with this name.
>>
<<
200.170
5405 COM error in expression
--
This type of COM call is not supported.
>>
<<
200.171
5406 COM no such sub object
--
The COM object's IDispatch interface did not report a sub object with this name.
>>
<<
200.172
5407 COM exception
--
An exceptionm was generated inside the COM object.
>>
<<
200.173
5408 COM Method returned no data
--
The call to a COM method didn't return a value. 
Perhaps a procedure was called as a function.
>>
<<
200.174
5409 COM unable to handle arrays
--
(not longer in use, arrays are now allowed)
>>
<<
200.175
5410 COM unable to handle references
--
References can not be handled by COM.
>>
<<
200.176
5411 COM unable to handle this data type
--
This data type can't be used for COM.
>>
<<
200.177
5412 COM stored object not found
--
No COM object with the givenm name could be found in the global list.
>>
<<
200.178
5413 COM only Arrays with 1 dimension are supported
--
Arrays for COM object must have extacly one dimension.
>>
<<
200.179
5414 COM no support for arrays of this type
--
Only the following data types can be transfered to/from COM objects:
<ul>
<li>Smallint</li>
<li>Integer</li>
<li>Single</li>
<li>Double</li>
<li>Currency</li>
<li>Byte</li>
</ul>
>>
<<
200.180
5415 COM array too big
--
Due to the limitation of the datatype <!RW>vector, only arrays with up to 65536 elements can be handled.
>>
<<
200.181
5416 COM size of array elements is not as expected
--
The size of the elements in the array is not compatible with the expected size.
>>
<<
200.182
5417 Invalid command for current test mode
--
An interpreter command was called, which is not permitted in the current test mode.
>>
