EcoStruxure Machine Expert version 1.1 does not support the M258, LMC058 and LMC078 controllers.

Conditional Pragmas

Overview

The ExST (Extended ST) language supports several conditional Pragma Instructions, which affect the code generation in the precompile or compile process.

NOTE: Do not use any conditional pragmas in the declaration part. They are not regarded.

The implementation code which will be regarded for compilation can depend on the following conditions:

oIs a certain data type or variable declared?

oDoes a type or variable have a certain attribute?

oDoes a variable have a certain data type?

oIs a certain POU or task available or is it part of the call tree, etc...

NOTE: It is not possible for a POU or GVL declared in the POUs Tree to use a {define...} declared in an application. Definitions in applications will only affect interfaces inserted below the respective application.

{define identifier string}

During preprocessing, all subsequent instances of the identifier will be replaced with the given sequence of tokens if the token string is not empty (which is allowed and well-defined). The identifier remains defined and in scope until the end of the object or until it is undefined in an {undefine} directive. Used for conditional compilation.

{undefine identifier}

The preprocessor definition of the identifier (by {define}, see first row of this table) will be removed and the identifier hence is undefined. If the specified identifier is not currently defined, this pragma will be ignored.

{IF expr}

...

{ELSIF expr}

...

{ELSE}

...

{END_IF}

These are pragmas for conditional compilation. The specified expressions exprs are required to be constant at compile time; they are evaluated in the order in which they appear until one of the expressions evaluates to a non-zero value. The text associated with the successful directive is preprocessed and compiled normally; the others are ignored. The order of the sections is determinate; however, the elsif and else sections are optional, and elsif sections may appear arbitrarily more often.

Within the constant expr, you can use several conditional compilation operators.

<expr>

Within the constant expression expr of a conditional compilation pragma ({if} or {elsif}) (see previous table), you can use several operators. These operators may not be undefined or redefined via {undefine} or {define}, respectively.

You can also use these expressions as well as the definition completed by {define} in the Compiler defines: text field in the Properties dialog box of an object (View > Properties > Build).

Conditional Compilation Operators

The following operators are supported:

odefined (identifier)

odefined (variable:variable) 

odefined (type:identifier)

odefined (pou:pou-name)

ohasattribute (pou: pou-name, attribute)

ohasattribute (variable: variable, attribute)

ohastype (variable:variable, type-spec)

ohasvalue (define-ident, char-string)

oNOT operator

ooperator AND operator

ooperator OR operator

ooperator

defined (identifier)

This operator affects that the expression gets value TRUE, as soon as the identifier has been defined with a {define} instruction and has not been undefined later by an {undefine} instruction. Otherwise its value is FALSE.

Example on defined (identifier):

Precondition: There are 2 applications App1 and App2. Identifier pdef1 is defined in App2, but not in App1.

{IF defined (pdef1)}
    (* this code is processed in App1 *)
    {info 'pdef1 defined'}
    hugo := hugo + SINT#1;
{ELSE}
    (* the following code is only processed in application App2 *)
    {info 'pdef1 not defined'}
    hugo := hugo - SINT#1;
{END_IF}

Additionally, an example for a message pragma is included:

Only information pdef1 defined will be displayed in the Messages view when the application is compiled because pdef1 is defined. The message pdef1 not defined will be displayed when pdef1 is not defined.

defined (variable:variable)

When applied to a variable, its value is TRUE if this particular variable is declared within the current scope. Otherwise it is FALSE.

Example on defined (variable:variable):

Precondition: There are 2 applications App1 and App2. Variable g_bTest  is declared in App2, but not in App1.

{IF defined (variable:g_bTest)}
(* the following code is only processed in application App2 *)
g bTest := x > 300;
{END_IF}

defined (type:identifier)

When applied to a type identifier, its value is TRUE if a type with that particular name is declared. Otherwise it is FALSE.

Example on defined (type:identifier) :

Precondition: There are 2 applications App1 and App2. Data type DUT is defined in App2, but not in App1.

{IF defined (type:DUT)}
(* the following code is only processed in application App1 *)
bDutDefined := TRUE;
{END_IF}

defined (pou:pou-name)

When applied to a POU name, its value is TRUE if a POU or an action with that particular POU name is defined. Otherwise it is FALSE.

Example on defined (pou: pou-name):

Precondition: There are 2 applications App1 and App2. POU CheckBounds is available in App2, but not in App1.

{IF defined (pou:CheckBounds)}
(* the following code is only processed in application App1 *)
arrTest[CheckBounds(0,i,10)] := arrTest[CheckBounds(0,i,10)] + 1;
{ELSE}
(* the following code is only processed in application App2 *)
arrTest[i] := arrTest[i]+1;
{END_IF}

hasattribute (pou: pou-name, attribute)

When applied to a POU, its value is TRUE if this particular attribute is specified in the first line of the POUs declaration part.

Example on hasattribute (pou: pou-name, attribute):

Precondition: There are 2 applications App1 and App2. Function fun1 is defined in App1 and App2, but in App1 has an attribute vision:

Definition of fun1 in App1:

{attribute 'vision'}
FUNCTION fun1 : INT
VAR_INPUT
i : INT;
END_VAR
VAR
END_VAR

Definition of fun1 in App2:

FUNCTION fun1 : INT
VAR_INPUT
i : INT;
END_VAR
VAR
END_VAR

Pragma instruction

{IF hasattribute (pou: fun1, 'vision')}
(* the following code is only processed in application App1 *)
ergvar := fun1 ivar);
{END_IF}

hasattribute (variable: variable, attribute)

When applied to a variable, its value is TRUE if this particular attribute is specified via the {attribute} instruction in a line before the declaration of the variable.

Example on hasattribute (variable: variable, attribute):

Precondition: There are 2 applications App1 and App2. Variable g_globalInt is used in App1 and App2, but in App1 has an attribute DoCount :

Declaration of g_globalInt in App1

VAR_GLOBAL
{attribute 'DoCount'}
g_globalInt : INT;
g_multiType : STRING;
END_VAR

Declaration of g_globalInt in App2

VAR_GLOBAL
g_globalInt : INT;
g_multiType : STRING;
END_VAR

Pragma instruction

{IF hasattribute (variable: g_globalInt, 'DoCount')}
(* the following code line will only be processed in App1, because there variable g_globalInt has got the attribute 'DoCount' *)
g_globalInt := g_globalInt + 1;
{END_IF}

hastype (variable:variable, type-spec)

When applied to a variable, its value is TRUE if this particular variable has the specified type-spec. Otherwise it is FALSE.

Available data types of type-spec

oLREAL

oREAL

oLINT

oDINT

oINT

oSINT

oULINT

oUDINT

oUINT

oUSINT

oTIME

oLWORD

oDWORD

oWORD

oBYTE

oBOOL

oSTRING

oWSTRING

oDATE_AND_TIME

oDATE

oTIME_OF_DAY

Example on operator hastype (variable: variable, type-spec):

Precondition: There are 2 applications App1 and App2. Variable g_multitype is declared in App1 with type LREAL and in application App2 with type STRING:

{IF (hastype (variable: g_multitype, LREAL))}
(* the following code line will be processed only in App1 *)
g_multitype := (0.9 + g_multitype) * 1.1;
{ELSIF (hastype (variable: g_multitype, STRING))}
(* the following code line will be processed only in App2 *)
g_multitype := 'this is a multitalent';
{END_IF}

hasvalue (define-ident, char-string)

If the define (define-ident) is defined and it has the specified value (char-string), then its value is TRUE. Otherwise it is FALSE.

Example on hasvalue (define-ident, char-string):

Precondition: Variable test is used in applications App1 and App2. It gets value 1 in App1 and value 2 in App2:

{IF hasvalue(test,'1')}
(* the following code line will be processed in App1, because there variable test has value 1 *)
x := x + 1;
{ELSIF hasvalue(test,'2')}
(* the following code line will be processed in App1, because there variable test has value 2 *)
x := x + 2;
{END_IF}

NOT operator

The expression gets value TRUE when the inverted value of operator is TRUE. operator can be one of the operators described in this chapter.

Example on NOT operator:

Precondition: There are 2 applications App1 and App2. POU PLC_PRG1 is used in App1 and App2. POU CheckBounds is only available in App1:

{IF defined (pou: PLC_PRG1) AND NOT (defined (pou: CheckBounds))}
(* the following code line is only executed in App2 *)
bANDNotTest := TRUE;
{END_IF}

AND operator

The expression gets value TRUE if both operators are TRUE. operator can be one of the operators listed in this table.

Example on AND operator:

Precondition: There are 2 applications App1 and App2. POU PLC_PRG1 is used in applications App1 and App2. POU CheckBounds is only available in App1:

{IF defined (pou: PLC_PRG1) AND (defined (pou: CheckBounds))}
(* the following code line will be processed only in applications App1, because only there "PLC_PRG1" and "CheckBounds" are defined *)
bORTest := TRUE;
{END_IF}

OR operator

The expression is TRUE if one of the operators is TRUE. operator can be one of the operators described in this chapter.

Example on OR operator:

Precondition: POU PLC_PRG1 is used in applications App1 and App2. POU CheckBounds is only available in App1:

{IF defined (pou: PLC_PRG1) OR (defined (pou: CheckBounds))}
(* the following code line will be processed in applications App1 and App2, because both contain at least one of the POUs "PLC_PRG1" and "CheckBounds" *)
bORTest := TRUE;
{END_IF}

(operator)

(operator) braces the operator.