Die Programmiersprache ExST (Extended ST) unterstützt mehrere bedingte Pragma-Anweisungen, die die Code-Generierung im Prä-Kompilierungs- oder Kompilierungsprozess beeinflussen.
HINWEIS: Verwenden Sie keine bedingten Pragmas im Deklarationsteil. Sie werden nicht beachtet.
Ob ein Implementierungs-Code bei der Kompilierung berücksichtigt wird, kann von den nachstehenden Bedingungen abhängig sein, nämlich ob:
oein bestimmter Datentyp oder eine bestimmte Variable deklariert ist
oein Datentyp oder eine Variable ein bestimmtes Attribut hat
oeine Variable einen bestimmten Datentyp hat
oein bestimmter POU oder ein oder ein Task vorhanden bzw. Teil des Aufrufbaums sind usw.
HINWEIS: Es ist nicht möglich für eine POU oder GVL, die im POU-Baum deklariert ist, eine {define...} zu verwenden, die in einer Applikation deklariert ist. Definitionen in Applikationen wirken sich nur auf Schnittstellen unterhalb der entsprechenden Applikation aus.
{define identifier string} |
Während des Prä-Kompilierungsprozesses werden alle nachfolgenden Instanzen des Bezeichners (identifier) mit der angegebenen Zeichenfolge (string) ersetzt, wenn diese nicht leer ist (was erlaubt ist). Die Kennung bleibt definiert und im Umfang bis zum Ende des Objektes oder bis sie in einer {undefine} -Weisung undefiniert wird. Wird für eine bedingte Kompilierung benötigt. |
{undefine identifier} |
Die Präprozessordefinition der identifier (nach {define}, siehe erste Seile dieser Tabelle) wird entfernt und die Kennung ist demzufolge undefiniert. Wenn der angegebene Bezeichner gerade gar nicht definiert ist, wird das pragma ignoriert. |
{IF expr} ... {ELSIF expr} ... {ELSE} ... {END_IF} |
Dies sind pragmas für die bedingte Kompilierung Die angegebenen Ausdrücke exprs müssen zur Kompilierungszeit konstant sein; sie werden in der Reihenfolge ausgewertet, in der sie hier erscheinen, bis einer der Ausdrücke einen nicht-Null-Wert zeigt. Der mit der Anweisung verknüpfte Text wird vorverarbeitet und dann übersetzt; die anderen Zeilen werden ignoriert. Die Reihenfolge der Abschnitte ist festgelegt; jedoch sind die Abschnitte elsif und else optional, und die elsif-Abschnitte dürfen beliebig oft vorkommen. Innerhalb der Konstante expr können mehrere bedingte Kompilierungsoperatoren verwendet werden. |
<expr> |
Innerhalb des konstanten Ausdrucks expr einer bedingten Kompilierung pragma ({if} oder {elsif}) (siehe vorherige Tabelle) können Sie verschiedene Operatoren verwenden. Diese Operatoren dürfen nicht via {undefine} oder {define} undefiniert oder redefiniert werden. |
Sie können diese Ausdrücke genau wie die von {define} vervollständigte Definition im Textfeld Compiler definiert: im Dialogfeld Eigenschaften eines Objektes verwenden (Ansicht > Eigenschaften > Build).
Bedingte Kompilierungsoperatoren
Folgende Operatoren werden unterstützt:
ohasattribute (pou: pou-name, attribute)
ohasattribute (variable: variable, attribute)
ohastype (variable:variable, type-spec)
ohasvalue (define-ident, char-string)
Dieser Operator bewirkt, dass der Ausdruck den Wert TRUE erhält, sobald identifier mit einer {define} -Anweisung definiert und nicht zu einem späteren Zeitpunkt durch eine {undefine} -Anweisung undefiniert wurde. Andernfalls wird der Wert FALSE ausgeliefert.
Beispiel zu defined (identifier):
Vorbedingung: Es gibt zwei Applikationen; App1 und App2. Der Bezeichner pdef1 wird in App2 deklariert, aber nicht 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}
Außerdem wird ein Beispiel für eine Meldung pragma hinzugefügt:
Nur die Information pdef1 defined wird beim Kompilieren der Applikation in der Ansicht Meldungen angezeigt, weil pdef1 definiert ist. Die Meldung nicht definiert erscheint, wenn pdef1pdef1 nicht definiert ist.
Bei einer Anwendung auf eine Variable, bewirkt dieser Operator, dass der Ausdruck den Wert TRUE erhält, wenn diese Variable im aktuellen Bereich deklariert ist. Anderenfalls entspricht der Wert FALSE.
Beispiel zu defined (variable:variable):
Vorbedingung: Es gibt zwei Applikationen; App1 und App2. Variable g_bTest wird in App2 deklariert, aber nicht in App1.
{IF defined (variable:g_bTest)}
(* the following code is only processed in application App2 *)
g bTest := x > 300;
{END_IF}
Bei einer Anwendung auf einen Datentyp Kennung, bewirkt dieser Operator, dass der Ausdruck den Wert TRUE erhält, wenn ein Datentyp mit diesem bestimmten Namen deklariert ist. Anderenfalls entspricht der Wert FALSE.
Beispiel zu defined (type:identifier) :
Vorbedingung: Es gibt zwei Applikationen; App1 und App2. Datentyp DUT wird in App2 deklariert, aber nicht in App1.
{IF defined (type:DUT)}
(* the following code is only processed in application App1 *)
bDutDefined := TRUE;
{END_IF}
Bei einer Anwendung auf einen POU-Namen, bewirkt dieser Operator, dass der Ausdruck den Wert TRUE erhält, wenn ein POU oder eine Aktion mit diesem bestimmten POU-Namen definiert ist. Anderenfalls entspricht der Wert FALSE.
Beispiel zu defined (pou: pou-name):
Vorbedingung: Es gibt zwei Applikationen; App1 und App2. POU CheckBounds ist in App2 verfügbar, aber nicht 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)
Bei einer Anwendung auf einen POU bewirkt dieser Operator, dass der Ausdruck den Wert TRUE erhält, wenn dieses besondere attribute in der ersten Zeile des POU-Deklarationsteile angegeben ist.
Beispiel zu hasattribute (pou: pou-name, attribute):
Vorbedingung: Es gibt zwei Applikationen; App1 und App2. Funktion fun1 ist in App1 und App2 definiert, hat in App1 jedoch ein Attributvision:
Definition von fun1 in App1:
{attribute 'vision'}
FUNCTION fun1 : INT
VAR_INPUT
i : INT;
END_VAR
VAR
END_VAR
Definition von fun1 in App2:
FUNCTION fun1 : INT
VAR_INPUT
i : INT;
END_VAR
VAR
END_VAR
Pragma- Anweisung
{IF hasattribute (pou: fun1, 'vision')}
(* the following code is only processed in application App1 *)
ergvar := fun1 ivar);
{END_IF}
hasattribute (variable: variable, attribute)
Wenn auf ein variable angewendet, ist der Wert TRUE, wenn dieses bestimmte Attribut durch die {attribute}-Anweisung in einer Zeile vor der Deklaration der Variable spezifiziert wird.
Beispiel zu hasattribute (variable: variable, attribute):
Vorbedingung: Es gibt zwei Applikationen; App1 und App2. Variable g_globalInt wird in App1 und App2 verwendet, hat in App1 jedoch ein AttributDoCount:
Deklaration von g_globalInt in App1:
VAR_GLOBAL
{attribute 'DoCount'}
g_globalInt : INT;
g_multiType : STRING;
END_VAR
Deklaration von g_globalInt in App2:
VAR_GLOBAL
g_globalInt : INT;
g_multiType : STRING;
END_VAR
Pragma- Anweisung
{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)
Bei einer Anwendung auf eine variable, ist dieser Wert TRUE, wenn diese Variable das spezifizierte type-spec hat. Anderenfalls entspricht der Wert FALSE.
Verfügbare Datentypen von 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
Beispiel zu Operator hastype (variable: variable, type-spec):
Vorbedingung: Es gibt zwei Applikationen; App1 und App2. Variable g_multitype wird in App1 mit dem Typ LREAL und in der Applikation App2 mit dem Typ STRING deklariert:
{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)
Dieser Operator bewirkt, dass der Ausdruck den Wert TRUE erhält, wenn eine Variable mit dem Bezeichner (define-ident) definiert ist und den Wert (char-string) hat. Anderenfalls entspricht der Wert FALSE.
Beispiel zu hasvalue (define-ident, char-string):
Vorbedingung: Variable test wird in den Applikationen App1 und App2 verwendet. Es erhält in App1 den Wert 1 und in App2 den Wert 2:
{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}
Dieser Ausdruck erhält den Wert TRUE, wenn der Umkehrwert von operator den Wert TRUE liefert. operator kann jeweils einer der in der vorliegenden Tabelle beschriebenen Operatoren sein.
Beispiel zu NOT operator:
Vorbedingung: Es gibt zwei Applikationen; App1 und App2. POU PLC_PRG1 wird in App1 und App2 verwendet. POU CheckBounds ist nur in App1 verfügbar:
{IF defined (pou: PLC_PRG1) AND NOT (defined (pou: CheckBounds))}
(* the following code line is only executed in App2 *)
bANDNotTest := TRUE;
{END_IF}
Der Ausdruck erhält den Wert TRUE, wenn beide Operationen den Wert TRUE haben. operator kann einer der in dieser Tabelle beschriebenen Operatoren sein.
Beispiel zu AND operator:
Vorbedingung: Es gibt zwei Applikationen; App1 und App2. POU PLC_PRG1 wird in den Applikationen App1 und App2 verwendet. POU CheckBounds ist nur in App1 verfügbar:
{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}
Der Ausdruck erhält den Wert TRUE, wenn einer der Operatoren TRUE liefert. operator kann jeweils einer der in der vorliegenden Tabelle beschriebenen Operatoren sein.
Beispiel zu OR operator:
Vorbedingung: POU PLC_PRG1 wird in den Applikationen App1 und App2 verwendet. POU CheckBounds ist nur in App1 verfügbar:
{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) umklammert den Operator.