Elementary data types

BOOL

Single bit, two values: TRUE and FALSE.

  • Default initial value is FALSE.
  • Truthy coercion does NOT exist — IF iCount THEN ... is a type error. Always compare explicitly: IF iCount > 0 THEN.
  • BOOL operands work with AND / OR / XOR / NOT as logical operators; the same operators on BYTE/WORD/DWORD are bitwise.

Integer family

Signed integers in four widths plus their unsigned cousins:

TypeWidthRange
SINT8-bit signed-128..127
INT16-bit signed-32 768..32 767
DINT32-bit signed±2¹⁰⁹ … wait, ±2³¹
LINT64-bit signed±2⁶³
USINT8-bit unsigned0..255
UINT16-bit unsigned0..65 535
UDINT32-bit unsigned0..2³²-1
ULINT64-bit unsigned0..2⁶⁴-1

Default initial value: 0.

Arithmetic does not trap on overflowSINT#127 + 1 silently wraps to -128. If overflow detection matters, use the next-wider type for the calculation.

Conversions between integer types are explicit: INT_TO_DINT, DINT_TO_INT, INT_TO_UINT, UINT_TO_INT, SINT_TO_INT, INT_TO_SINT, etc.

Bit-string family

Same widths as the unsigned integers but used for bit-pattern operations rather than arithmetic:

TypeWidth
BYTE8 bits
WORD16 bits
DWORD32 bits
LWORD64 bits

Bit-string operands work with AND / OR / XOR / NOT bitwise (in contrast with BOOL operands, which are logical). Bit access via .N syntax: bMask.0, wReg.15.

Default initial value: 0.

Conversions: BYTE_TO_INT, INT_TO_BYTE, WORD_TO_DWORD, etc. Conversion to BOOL via <> 0 test.

REAL family

IEEE-754 floating point:

TypeWidthSignificant digits
REAL32 bits~7
LREAL64 bits~15

Default initial value: 0.0.

Comparison hazard: REAL equality is unsafe due to floating-point precision. Use ABS(rA - rB) < epsilon instead of rA = rB. See comparison operators.

Time, date and time-of-day

TypeLiteral exampleMeaning
TIMET#1h30m, T#100msDuration
DATED#2026-05-14Calendar date
TIME_OF_DAY / TODTOD#14:30:00Wall-clock time
DATE_AND_TIME / DTDT#2026-05-14-14:30:00Combined timestamp

TIME is the most common — it’s the type of TON’s PT input and ET output. Write durations with the T# prefix:

T#100ms     (* 100 milliseconds *)
T#1s        (* 1 second *)
T#1m30s     (* 1 minute 30 seconds *)
T#1h        (* 1 hour *)
T#1d12h     (* 1.5 days *)
T#-500ms    (* negative duration: 500 ms in the past *)

Default initial value: T#0s, D#1970-01-01, TOD#00:00:00, DT#1970-01-01-00:00:00.

STRING

Variable-length character string with a declared maximum length:

sName : STRING(80);                 (* 80 chars max *)
sLine : STRING(255) := 'hello';    (* with initial value *)
sShort : STRING;                    (* default length, 80 on matiec *)

String literals use single quotes: 'hello'. Embedded single-quote: '$''. Escape sequences with $ prefix: $N (newline), $T (tab), $$ (literal $).

Default initial value: empty string ''.

IEC reference

IEC 61131-3 third edition (2013), clause 6.4.1 — “Elementary data types” Table 10.

matiec conformance

matiec implements all elementary types per the standard. The three pitfalls in llm_signals are the recurring LLM trap points:

  • TIME literals require T# prefix.
  • Integer-literal range vs. declared type.
  • STRING(N) needs N > 0.

ForgeIEC notes

The pool stores the IEC type as a string. When you call project.write.add_variable iecType="INT", the variable is created with type INT exactly; no remapping happens.