IF / ELSIF / ELSE
Definition
Conditional branching: evaluate a BOOL expression and, if it
is TRUE, run the statements between THEN and the next
ELSIF / ELSE / END_IF. Up to one ELSIF block per
extra condition; up to one optional ELSE block as the final
catch-all.
The IF statement always commits to exactly one branch.
The first THEN whose condition evaluates TRUE wins; later
ELSIF conditions are not even evaluated.
Syntax
IF <bool_expr> THEN
<statement_list>
[ELSIF <bool_expr> THEN
<statement_list>]*
[ELSE
<statement_list>]
END_IF;
<bool_expr> evaluates to a single BOOL. Both branches'
<statement_list> may be empty.
Example
(* Bit-mask lookup by step index — see CASE-statement for the
alternative spelling. *)
IF iStep = 0 THEN
bMask := INT_TO_BYTE(1);
ELSIF iStep = 1 THEN
bMask := INT_TO_BYTE(2);
ELSIF iStep = 2 THEN
bMask := INT_TO_BYTE(4);
ELSE
bMask := INT_TO_BYTE(0);
END_IF;
Semantics
Conditions evaluate left-to-right, top-to-bottom. As soon as
one condition returns TRUE, that branch’s statement list runs
and execution leaves the IF block. No fall-through. If no
condition is TRUE and no ELSE branch exists, the IF
block is a no-op.
BOOL is a real two-valued type, not a numeric tested for
non-zero. IF iCounter THEN … is a type error in IEC 61131-3
even though many vendor-specific dialects accept it.
IEC reference
IEC 61131-3 third edition (2013), clause 6.6.3.1 — “IF
statement”. The keywords IF, THEN, ELSIF, ELSE,
END_IF are reserved.
matiec conformance
matiec implements IF / ELSIF / ELSE exactly as the
standard requires. No known emit-bugs.
The strict typing rule is enforced more aggressively than some
operators: IF a = b THEN … with a: INT and b: UINT will
fail at the matiec layer (after the local FStCompiler accepts
it). Always wrap one side in the explicit conversion call —
see comparison of integer expressions of different types in
the llm_signals block.
ForgeIEC notes
- ForgeIEC’s editor highlights
THEN/ELSIF/ELSE/END_IFvia tree-sitter (Memory:feedback_treesitter_rename_refactor). - A nested IF that crosses task boundaries is not special — the IF runs entirely within one task cycle.
- For repetitive multi-way dispatch on a single integer
expression, prefer
CASEover a longELSIFcascade. The IF cascade exists because matiec has emit-bugs with certainCASE-list literal forms (see theCASEpage); when the inputs are clean,CASEreads better.