Assignment & operator precedence

Assignment

The assignment operator in IEC 61131-3 is := (colon-equals). This is one of the most frequent confusion points for programmers coming from other languages:

LanguageAssignmentEquality
IEC 61131-3 / Pascal:==
C / C++ / Java / JS===
BASIC / Python=== (Py) / = (BASIC)

Inside an IEC ST body:

iCount := iCount + 1;       (* assignment *)
IF iCount = 10 THEN ...     (* equality — comparison *)

= in an assignment context is a syntax error.

Operator precedence (highest to lowest)

ClassOperatorsAssociativity
Parentheses(...)n/a
Function callname(...)left
Component access.member, [index], bit.Nleft
Exponent**right
Unary- (negation), NOTn/a
Multiplicative*, /, MODleft
Additive+, - (binary)left
Comparison<, <=, >, >=left
Equality=, <>left
Bitwise/Logical ANDAND, &left
Bitwise/Logical XORXORleft
Bitwise/Logical ORORleft

** is the only right-associative operator: 2 ** 3 ** 2 is 2 ** (3 ** 2) = 2 ** 9 = 512, not (2 ** 3) ** 2 = 64.

Precedence in practice

When in doubt, parenthesise. The IEC standard’s precedence is identical to most C-family languages except for the unified binding of AND / OR / XOR (in C, && and || bind differently from & and |).

(* These two are equivalent — AND binds tighter than OR *)
xResult := xA OR xB AND xC;
xResult := xA OR (xB AND xC);

(* This is something else *)
xResult := (xA OR xB) AND xC;

(* Comparison binds tighter than equality, both bind tighter
   than AND/OR. So this works as expected: *)
xInRange := (iValue > 0) AND (iValue <= 100);

(* But the inner parens are STYLE, not necessary — a > b
   already returns BOOL before AND looks at it. *)
xInRange := iValue > 0 AND iValue <= 100;

Multiple assignment

IEC 61131-3 third edition (2013) does not support chained assignment in the C sense (a = b = c = 0;). Each assignment is a separate statement:

(* not legal *)
(* iA := iB := iC := 0; *)

(* legal *)
iA := 0;
iB := 0;
iC := 0;

IEC reference

  • Assignment: clause 6.6.3.1 of IEC 61131-3 third edition (2013).
  • Operator precedence: clause 6.6.1 Table 55.

matiec conformance

matiec implements assignment and the precedence table per the standard. The most common LLM mistakes (= instead of :=, type-mismatch in assignment) are caught early by the local FStCompiler — see the llm_signals block above for the canonical fix patterns.