El lenguaje ExST (ST ampliado) admite diversas instrucciones Pragma condicionales que afectan a la generación de código en el proceso de precompilación o compilación.
El código de implementación que se utiliza para la compilación puede depender de las condiciones siguientes:
¿Se trata de determinado tipo de datos o variables declarado?
¿Un tipo o una variable tienen un atributo determinado?
¿Tiene una variable un tipo de datos determinado?
¿Es una POU determinada, una tarea disponible o forma parte de un árbol de llamadas, etc.?
{define...}
declarado en una aplicación. Las definiciones en las aplicaciones solo afectarán a interfaces insertadas bajo la aplicación correspondiente.
|
Durante el procesamiento previo, todas las instancias del identificador que se ejecuten a partir de ese momento se sustituirán por la secuencia de tokens en cuestión si la cadena del token no está vacía (está permitida y bien definida). El identificador permanece definido y dentro del ámbito hasta el final del objeto o hasta que esté sin definir en una directiva |
|
Se eliminará la definición del preprocesador del |
...
...
...
|
Estos pragmas se utilizan para compilaciones condicionales. Las expresiones especificadas
Dentro de la constante |
|
Dentro de la expresión de la constante |
También puede utilizar estas expresiones, así como la definición completada por {define}
en el campo de texto del cuadro de diálogo de un objeto ( ).
defined (identifier)
Este operador hace que la expresión adopte el valor TRUE, en cuanto se haya definido el identifier
con una instrucción {define}
y no haya sido no definido posteriormente por una instrucción {undefine}
. En caso contrario, su valor será FALSE.
Ejemplo de defined (identifier)
:
Requisito: hay 2 aplicaciones App1
y App2
. El identificador pdef1
está definido en la App2
, pero no en la 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}
Además, se incluye un ejemplo de un pragma de mensaje:
Solo se muestra la información de pdef1 defined
en la vista al compilar la aplicación porque pdef1
está definido. El mensaje se mostrará cuando pdef1
no esté definido.
defined (variable:<variable name>)
Cuando se aplica a una variable, su valor es TRUE si esta variable en particular está declarada dentro del ámbito actual. De lo contrario, es FALSE.
Ejemplo de defined (variable:<variable name>)
:
Requisito: hay 2 aplicaciones App1
y App2
. La variable g_bTest
está declarada en la App2
, pero no en la App1
.
{IF defined (variable:g_bTest)}
(* the following code is only processed in application App2 *)
g bTest := x > 300;
{END_IF}
defined (type:identifier)
Cuando se aplica a un identificador de tipo, su valor es TRUE si existe un tipo declarado con ese nombre en particular. De lo contrario, es FALSE.
Ejemplo de defined (type:identifier)
:
Requisito: hay 2 aplicaciones App1
y App2
. El tipo de datos DUT está definido en la App2
, pero no en la App1
.
{IF defined (type:DUT)}
(* the following code is only processed in application App1 *)
bDutDefined := TRUE;
{END_IF}
defined (pou:pou-name)
Cuando se aplica a un nombre de POU, su valor es TRUE si está disponible uno de los siguientes objetos con el nombre <pou-name>
:
Bloque de funciones
Función
Programa
Acción
Método
Interfaz
De lo contrario, es FALSE.
Para obtener más información, consulte el capítulo POU.
Ejemplo de defined (pou: pou-name)
:
Requisito: hay 2 aplicaciones App1
y App2
. La POU CheckBounds
está disponible en la App2
, pero no en la 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}
defined (task:task-name)
La expresión obtiene el valor TRUE si se ha definido una tarea con el nombre <task name>
. De lo contrario, es FALSE.
Sintaxis:
{ IF defined (task: <task name> }
{ ELSIF defined (task: <task name> }
Ejemplo 1: {IF defined (task: Task_D)}
Ejemplo 2:
Requisito: hay 2 aplicaciones App1
y App2
. La tarea PLC_PRG_Task
está definida en la App1
, pero no en la App2
.
{IF defined (task: PLC_PRG_Task)}
(* the following code is only processed in App1 *)
erg := plc_prg.x;
{ELSE}
(* the following code is only processed in App2 *)
erg := prog.x;
{END_IF}
hasattribute (pou: pou-name, attribute)
Cuando se aplica a una POU, su valor es TRUE si ese attribute
en concreto se ha especificado en la primera línea de la parte de declaración de la POU.
Ejemplo de hasattribute (pou: pou-name, attribute)
:
Requisito: hay 2 aplicaciones App1
y App2
. La función fun1 está definida en la App1
y la App2
, pero en la App1
tiene un atributo vision:
Definición de fun1
en la App1
:
{attribute 'vision'}
FUNCTION fun1 : INT
VAR_INPUT
i : INT;
END_VAR
VAR
END_VAR
Definición de fun1
en la App2
:
FUNCTION fun1 : INT
VAR_INPUT
i : INT;
END_VAR
VAR
END_VAR
Instrucción Pragma
{IF hasattribute (pou: fun1, 'vision')}
(* the following code is only processed in application App1 *)
ergvar := fun1 ivar);
{END_IF}
hasattribute (variable: variable, attribute)
Cuando se aplica a una variable
, su valor es TRUE si este atributo determinado se especifica mediante la instrucción {attribute} una línea antes de la declaración de la variable.
Ejemplo de hasattribute (variable: variable, attribute)
:
Requisito: hay 2 aplicaciones App1
y App2
. La variable g_globalInt se usa en la App1
y la App2
, pero en la App1
tiene un atributo DoCount:
Declaración de g_globalInt en la App1
VAR_GLOBAL
{attribute 'DoCount'}
g_globalInt : INT;
g_multiType : STRING;
END_VAR
Declaración de g_globalInt en la App2
VAR_GLOBAL
g_globalInt : INT;
g_multiType : STRING;
END_VAR
Instrucción Pragma
{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)
Cuando se aplica a una variable
, su valor es TRUE si esta variable en concreto tiene type-spec
especificado. De lo contrario, es FALSE.
Tipos de datos disponibles de type-spec
BOOL
BYTE
DATE
DATE_AND_TIME
DINT
DWORD
INT
LDATE
LDATE_AND_TIME (LDT)
LINT
LREAL
LTIME
LTIME_OF_DAY (LTOD)
LWORD
REAL
SINT
STRING
TIME
TIME_OF_DAY (TOD)
UDINT
UINT
ULINT
USINT
WORD
WSTRING
Ejemplo en el operador hastype (variable: variable, type-spec):
Requisito: hay 2 aplicaciones App1
y App2
. La variable g_multitype se declara en App1
con el tipo LREAL y en la aplicación App2
con el tipo 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)
Si el definidor (define-ident) está definido y tiene el valor especificado (char-string), entonces su valor es TRUE. De lo contrario, es FALSE.
Ejemplo de hasvalue (define-ident, char-string)
:
Requisito: la variable test se usa en las aplicaciones App1
y App2
. Obtiene el valor 1 en la App1
y el valor 2 en la 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}
hasvalue (PackMode, '<pack mode value>')
La modalidad de paquete que se comprueba depende de la descripción del dispositivo, no del pragma que se pueda especificar para los diferentes DUT.
hasvalue (RegisterSize, '<register size>')
<register size>
: define el tamaño de un registro de CPU (en bits).
Cuando el tamaño de un registro de CPU es igual a <register size>
, la expresión devuelve el valor TRUE.
<register size>
puede presentar los siguientes valores:
16
para C16x
64
para X86-64 bits
32
para X86-32 bits
hasconstanttype(<constant name>, <boolean literal>)
El operador comprueba si la constante, que se define con <constant name>
, se ha reemplazado. El segundo parámetro (valor booleano) controla lo que se comprueba:
TRUE: comprueba si se ha reemplazado la constante.
FALSE: comprueba si se ha reemplazado la constante.
Si se detecta el caso correspondiente, el operador devuelve TRUE
.
Sintaxis:
{ IF hasconstanttype( <constant name> , <boolean literal> ) }
{ ELSIF hasconstanttype( <constant name> , <boolean literal> ) }
Ejemplo:
{IF hasconstanttype(PLC_PRG.aConst, TRUE)}
El reemplazo automático de constantes depende de lo siguiente:
La opción de compilación
El tipo de constante (los tipos STRING, por ejemplo, no se reemplazan)
El uso del atributo {attribute 'const_non_replaced'}
El uso del atributo {attribute 'const_replaced'}
Ejemplo:
VAR
iCntMAXIsReplaced: INT;
xErrorOccured : BOOL;
END_VAR
VAR CONSTANT
c_iMAX: INT := 99;
END_VAR
{IF hasconstanttype(c_iMAX, TRUE)}
iCntMAXIsReplaced := iCntMAXIsReplaced + 1; // E.g. this code will be executed in case Project Settings – Compile options – Replace constants was activated
{ELSE}
xErrorOccured := FALSE;; // E.g. this code will be executed in case Project Settings – Compile options – Replace constants was deactivated
{END_IF}
hasconstantvalue(<constant name>, <variable name>, <comparison operator>)
El operador compara el valor de la constante, que se define con <constant name>
, con el valor del segundo parámetro. El segundo parámetro se puede especificar como literal <literal>
o como variable <variable name>
.
Se admiten los siguientes operadores de comparación <comparison operator>
:
Mayor que (>
)
Mayor o igual que (>=
)
Igual a (=
)
Distinto de (<>
)
Menor o igual que (<=
)
Menor que (<
)
Sintaxis:
{ IF hasconstantvalue( <constant name> , <variable name> , <comparison operator> )
{ IF hasconstantvalue( <constant name> , <literal> , <comparison operator> )
{ ELSIF hasconstantvalue( <constant name> , <variable name> , <comparison operator> )
{ ELSIF hasconstantvalue( <constant name> , <literal> , <comparison operator> )
Ejemplo 1:
{IF hasconstantvalue(PLC_PRG.aConst, 99, >)}
{ELSIF hasconstantvalue(PLC_PRG.aConst, GVL.intconst99, =)}
Ejemplo 2:
PROGRAM PRG_ConditionConstantValue
VAR
iCntMAX: INT;
iCntGlobalMAX : INT;
iCntABC: INT;
iCntGlobalABC : INT;
xErrorOccured : BOOL;
END_VAR
VAR CONSTANT
c_iMAX: INT := 999;
c_sABC: STRING := 'ABC';
{attribute 'const_non_replaced'}
c_iNonReplaceable: INT := 888;
END_VAR
{IF hasconstantvalue(c_iMAX, 999, =)}
iCntMAX := iCntMAX + 1;
{ELSE}
xErrorOccured := FALSE;
{END_IF}
{IF hasconstantvalue(c_iMAX, GVL.gc_iMAX, =)}
iCntGlobalMAX := iCntGlobalMAX + 1;
{ELSE}
xErrorOccured := FALSE;
{END_IF}
{IF hasconstantvalue(c_sABC, 'ABC', =)}
iCntABC := iCntMAX + 1;
{ELSE}
xErrorOccured := FALSE;
{END_IF}
{IF hasconstantvalue(c_sABC, GVL.gc_sABC, =)}
iCntGlobalABC := iCntMAX + 1;
{ELSE}
xErrorOccured := FALSE;
{END_IF}
NOT operator
La expresión obtiene el valor TRUE cuando el valor invertido del operator
es TRUE. operator
puede ser uno de los operadores descritos en este capítulo.
Ejemplo de NOT operator
:
Requisito: hay 2 aplicaciones App1
y App2
. La POU PLC_PRG1 se usa en la App1
y la App2. La POU CheckBounds
solo está disponible en la 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
La expresión obtiene el valor TRUE si ambos operadores son TRUE. operator
puede ser uno de los operadores enumerados en esta tabla.
Ejemplo de AND operator
:
Requisito: hay 2 aplicaciones App1
y App2
. La POU PLC_PRG1
se usa en las aplicaciones App1
y App2
. La POU CheckBounds
solo está disponible en la 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
La expresión es TRUE si uno de los operadores es TRUE. operator
puede ser uno de los operadores descritos en este capítulo.
Ejemplo de OR operator
:
Requisito: La POU PLC_PRG1
se usa en las aplicaciones App1
y App2
. La POU CheckBounds
solo está disponible en la 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}