Skip to content

Turck Structured Text

Turck Structured Text (TST) is the main programming language for MARGEE projects.

TypeDescriptionSmallest ValueBiggest ValueSize
REALFloating point1.175494 * 10⁻³⁸3.4028237 * 10³⁸32 bit
UDINTUnsigned double integer0429496729532 bit
UINTUnsigned integer06553516 bit
USINTUnsigned small integer02558 bit
DINTSigned double integer-2147483647214748364732 bit
INTSigned integer-327683276716 bit
SINTSigned small integer-1281278 bit
DWORDAlias of UDINT0429496729532 bit
WORDAlias of UINT06553516 bit
BYTEAlias of USINT02558 bit
TIMERTimer64 bit
ARRAYArrayx+4 bit
COMPLEXSTRUCT or FUNCTION_BLOCKx bit

Variable segments are used to define variable which can be used in the MARGEE program. Global segments (VAR_GLOBAL, VAR_RETAIN, VAR_RETAIN & VAR_CONSTANT) can be declared at any top-level location. VAR, VAR_INPUT, VAR_OUTPUT, VAR_IN_OUT can only be used in FUNCTION, FUNCTION_BLOCK, or TASK right after the initial declaration.

<segment type>
<variable name> : <type> {:= <value>}; //Simple
<name> : ARRAY[0..<end index>] OF <type> {:= [<value>, ... ]}; //Array
<name> : <complex name> {:= [<value>, ... ]}; //Complex
...
END_<segment_type>
TypeDescription
VARVariables declared here can be reached in the local scope.
VAR_GLOBALGlobal variables can be reached anywhere in the program. A VAR_GLOBAL segment can only be declared at the top-level scope.
VAR_RETAINRetain variables can be reached anywhere in the program. Values stored in this segment will be retained between power cycles. A VAR_RETAIN segment can only be declared at the top-level scope.
VAR_CONSTANTConstant variables can be reached anywhere in the program. A VAR_CONSTANT segment can only be declared at the top-level scope.
VAR_INPUTA VAR_INPUT segment can only be declared in FUNCTION or FUNCTION_BLOCK. Used to pass variables by value. ARRAY or COMPLEX cannot be declared here.
VAR_OUTPUTA VAR_OUTPUT segment can only be declared in FUNCTION or FUNCTION_BLOCK. Used to return variables by value. ARRAY or COMPLEX cannot be declared here.
VAR_IN_OUTA VAR_IN_OUT segment can only be declared in FUNCTION or FUNCTION_BLOCK. Used to pass variables by reference. When using ARRAY type, the length cannot be set.

A task is automatically called by the operating system. Any unique name can be used to create a task. Multiple tasks can be created, which will be called in sequence.

TASK <task name>
<variable segments>
...
statements
...
END_TASK

A function block cannot be called directly. It must first be declared in the local scope. The statements are declared once. Variables are declared and reserved for each function block declaration. Local variables are retained between calls. A function block is able to halt a task. ARRAY or COMPLEX cannot be used as a return type.

FUNCTION_BLOCK <function block name> {: <return type>}
<variable segments>
...
statements
...
END_FUNCTION_BLOCK

A function is created at the top-level. A function can be called from anywhere. FUNCTION_BLOCK types cannot be declared in a function. The statements and variables are declared and reserved once. A function is unable to halt a task (WAIT_UNTIL or CONTEXT SWITCH cannot be used). ARRAY or COMPLEX cannot be used as a return type.

FUNCTION <function name> {: <return type>}
<variable segments>
...
<statements>
...
END_FUNCTION

A struct type is used to create a complex data type. This struct can be declared, and passed to FBs through VAR_IN_OUT.

STRUCT <struct name>
<variable name> : <type> {:= <value>};
...
END_STRUCT

An enum type is used to create constant variables. As opposed to VAR_CONSTANT accessing an enum variable must also include the enum name (<enum name>.<variable name>).

ENUM <enum name>: <type>
<variable name> := <value>;
...
END_ENUM

Call a FUNCTION or FUNCTION_BLOCK.

<function name>();
<function name>(<argument>, ...)

Assign a value to a variable.

<variable> := <expression>;
<variable> := <call>;

Conditionally executes code.

IF <expression> THEN
<statements> ...
END_IF
IF <expression> THEN
<statements> ...
ELSIF <expression> THEN
<statements> ...
END_IF
IF <expression> THEN
<statements> ...
ELSE
<statements> ...
END_IF

Executes statements while an expression returns a non-nullish value.

WHILE <expression> DO
<statements> ...
END_WHILE

Executes statements while an expression returns a non-nullish value.

REPEAT
<statements> ...
UNTIL <expression> END_REPEAT

Executes statements with a number of repetitions.

FOR <variable> := <number> TO <number> DO
<statements> ...
END_FOR
FOR <variable> := <number> TO <number> BY <number> DO
<statements> ...
END_FOR

Exit a WHILE, REPEAT or FOR loop immediately.

EXIT;

Continue to the start of a WHILE, REPEAT or FOR loop immediately.

CONTINUE;

Return from a FUNCTION, FUNCTION_BLOCK or TASK immediately.

RETURN;

Halts a complete TASK until the expression returns a nullish value.

WAIT_UNTIL(<expression>);

Exits a TASK immediately, TASK will resume at the next line after all other tasks have been called.

CONTEXT_SWITCH;

Logs a message and optional value when program hits the trace. The message can be read in the debug window.

TRACE(<string> <variable> <string>);
TRACE(<string>);
TRACE(<string> <variable>);

At a high level, an expression is a valid unit of code that resolves to a value.

<value>
<value><operator><value>
<value><operator><value><operator><value>

Examples

(28 * someVar) / 25
aFunc(someVar) + (0xff << otherVar) / TO_WORD(3.14 * 28)

All complex expressions are joined by operators, such as = and +. Margee has access to the following:

TypenameCan be performed on REAL
==Equal✅ Results in an unsigned small integer (0 or 1)
<>Not equal✅ Results in an unsigned small integer (0 or 1)
<=Less or equal✅ Results in an unsigned small integer (0 or 1)
<Less✅ Results in an unsigned small integer (0 or 1)
>=Greater or equal✅ Results in an unsigned small integer (0 or 1)
>Greater✅ Results in an unsigned small integer (0 or 1)
*Multiply✅ Yes
/Divide✅ Yes
%Modulo❌ No
+Add✅ Yes
-Sub✅ Yes
&And❌ No
****Or
<<Shift left❌ No
>>Shift right❌ No

The basic expression is a value. A value can be a CONSANT, READ or CALL.

  • CALL - A call can only be used if the called function returns a value.
  • READ - A variable that is a simple type.
  • CONSTANT - 1234, 16#ABCD, 2#10010001, 3.14 and more…

Converts an expression to a REAL type.

Actual code is generated when:

  • expression is not of type REAL
TO_REAL(<expression>)

Converts an expression to a UDINT type.

Actual code is generated when:

  • expression is of type REAL
TO_UDINT(<expression>)

Converts an expression to a DWORD type.

Actual code is generated when:

  • expression is of type REAL
TO_DWORD(<expression>)

Converts an expression to a UINT type.

Actual code is generated when:

  • expression is of type REAL or
  • expression is of type UDINT or
  • expression is of type DINT or
TO_UINT(<expression>)

Converts an expression to a WORD type.

Actual code is generated when:

  • expression is of type REAL or
  • expression is of type UDINT or
  • expression is of type DINT or
TO_WORD(<expression>)

Converts an expression to a USINT type.

Actual code is generated when:

  • expression is of type REAL or
  • expression is of type UDINT or
  • expression is of type UINT or
  • expression is of type DINT or
  • expression is of type INT or
TO_USINT(<expression>)

Converts an expression to a BYTE type.

Actual code is generated when:

  • expression is of type REAL or
  • expression is of type UDINT or
  • expression is of type UINT or
  • expression is of type DINT or
  • expression is of type INT or
TO_BYTE(<expression>)

Converts an expression to a DINT type.

Actual code is generated when:

  • expression is of type REAL
TO_DINT(<expression>)

Converts an expression to a INT type.

Actual code is generated when:

  • expression is of type REAL or
  • expression is of type UDINT or
  • expression is of type DINT or
TO_INT(<expression>)

Converts an expression to a SINT type.

Actual code is generated when:

  • expression is of type REAL or
  • expression is of type UDINT or
  • expression is of type UINT or
  • expression is of type DINT or
  • expression is of type INT or
TO_SINT(<expression>)

If an expression is an integer you can extract specific bits from this expression.

<expression>.<least significant bit>{..<bit length>}
(2#00111100).2..4 //result in: 2#0b1111
(2#00001000).3 //result in: 2#0b1