Verified: Structured Text
Each claim the Structured Text page makes, with the tests that
prove it in the last green CI run: 57 of 57 verified.
The claims live in docs/claims/structured-text.yaml.
Last green CI run 16 Oct 2026, 14:48 UTC on c7618d3 · all runtime claims
ST-001 verified
Statements evaluate top to bottom, so a value assigned on one line is what the next line reads in the same scan.
ST-002 verified
Program-local VAR keeps its value from scan to scan.
- pass
TestVarTempResetsEveryScaninlang/st - pass
TestConformance/st-var-tempinlang/conformance(3 of 3 passed)
ST-003 verified
In a manifest project every tag in nautilus.yaml is in scope in every program without a VAR_EXTERNAL declaration, typed by its type: (or its init:).
- pass
TestManifestTagsAreImplicitininternal/project - pass
TestLowerImplicitGlobalsinlang/st - pass
TestInitTypesAnImplicitTagininternal/project
ST-004 verified
A VAR_EXTERNAL that names a manifest tag must agree with the tag's type:. For a tag typed only by its init:, the declaration sets the type and the init: must be a value of it (init: TRUE against a REAL declaration is an error).
- pass
TestExplicitDeclarationMustAgreeWithTypedTagininternal/project - pass
TestDeclarationTypesAnInitOnlyTagininternal/project - pass
TestTagTypesAndUntypedTagsinlang/st
ST-005 verified
Naming a tag binds it in the tag store rather than creating it, and reading a tag nothing has ever written faults the scan with "undefined tag".
- pass
TestScanReadOfUnwrittenTagFaultsinruntime
ST-006 verified
A FUNCTION_BLOCK sees no tag it does not declare in its own VAR_EXTERNAL.
- pass
TestFunctionBlocksDoNotSeeTagsImplicitlyininternal/project - pass
TestTagTypesAndUntypedTagsinlang/st
ST-007 verified
The declaration sections VAR, VAR_INPUT, VAR_OUTPUT, VAR_IN_OUT, VAR_TEMP, VAR_GLOBAL and VAR_EXTERNAL parse, each closed by END_VAR, with RETAIN or CONSTANT allowed after the section keyword.
ST-008 verified
VAR_GLOBAL and VAR_EXTERNAL resolve identically: both name a tag in the store.
ST-009 verified
A declared initial value (Gain : REAL := 2.0;) is where the variable starts, in a PROGRAM, in every FUNCTION_BLOCK instance, and on every FUNCTION call.
ST-010 verified
An initial value (:=) on a VAR_GLOBAL or VAR_EXTERNAL is a compile error; the tag's init: in the manifest sets it instead.
- pass
TestExternalInitialValueRejectedinlang/st - pass
TestGlobalConstantRulesinlang/st - pass
TestManifestTagsAreImplicitininternal/project
ST-011 verified
VAR_TEMP starts every scan of a program, and every call of a function block or function, at its initial value (or zero), never at what the last execution left.
- pass
TestConformance/st-var-tempinlang/conformance(3 of 3 passed) - pass
TestVarTempResetsEveryScaninlang/st - pass
TestVarTempResetsEveryFBCallinlang/st - pass
TestVarTempInFunctioninlang/st
ST-012 verified
VAR CONSTANT is a named value folded at compile time; assigning one is a compile error.
ST-013 verified
VAR_GLOBAL CONSTANT in a library file declares project constants every POU sees; a constant is not a tag.
- pass
TestGlobalConstantsVisibleEverywhereinlang/st - pass
TestGlobalConstantsLibraryAloneinlang/st - pass
TestConformance/st-global-constantsinlang/conformance(4 of 4 passed)
ST-014 verified
A standalone VAR_GLOBAL block at the top of a library file (a Codesys gvl.st) declares globals for every program; one the manifest does not declare becomes a state tag starting at the zero of its type.
- pass
TestFileScopeVarGlobalAheadOfPrograminlang/st - pass
TestGVLComposesIntoEveryProgramininternal/project - pass
TestGVLUndeclaredGlobalBecomesAStateTagininternal/project
ST-015 verified
The elementary types BOOL, SINT..LINT/USINT..ULINT/BYTE..LWORD, REAL, LREAL, TIME, LTIME, STRING, WSTRING, CHAR and WCHAR are accepted.
ST-016 verified
All integer kinds share one 64-bit representation, so a declared width documents intent without narrowing (INT does not wrap at 16 bits, DINT not at 32).
- pass
TestConformance/st-int-widthinlang/conformance(6 of 6 passed) - pass
TestConformance/st-bitwise/bits above 32 survive - the width is 64 bitsinlang/conformance
ST-017 verified
TIME counts milliseconds.
- pass
TestConformance/fn-conversions/TIME is milliseconds in both directionsinlang/conformance - pass
TestConformance/st-conversions-matrix/TIME is milliseconds, and wraps like any integer when narrowedinlang/conformance - pass
TestParseDurationinlang/ir
ST-018 verified
ARRAY[lo..hi] OF T takes several comma-separated dimensions and any element type, including a UDT or a function block.
ST-019 verified
Array bounds are integer constants: a literal, a named constant, or arithmetic on them (ARRAY[1..N_TANKS]).
- pass
TestConstantInBoundsAndInitialValuesinlang/st - pass
TestConformance/st-global-constants/an INT constant from a constant expression sizes an array and bounds a loopinlang/conformance - pass
TestArrayBoundArithmeticInTheBoundinlang/st
ST-020 verified
TYPE ... END_TYPE declares a STRUCT, an alias for another type, or an enumeration; enumeration members are used as Mode#Run or plain Run and shown by name in live values.
ST-021 verified
A struct-typed VAR_EXTERNAL tag is written one field at a time (P101.Running := TRUE) or whole, and each field write reaches the tag store as a member write.
ST-022 verified
Literals cover decimals and exponents (1.5e3), based integers (16#FF, 2#1010, 8#777), typed forms (INT#42, BOOL#TRUE, STRING#'hi') and durations (T#5s, T#500ms, T#1h30m).
ST-023 verified
Block comments (* ... *) nest, and // comments to end of line.
ST-024 verified
RETAIN parses and changes nothing at runtime: every program VAR and function block instance already keeps its value scan to scan.
ST-025 verified
A warm swap carries program VAR and FB instance state across an online edit by name and type.
ST-026 verified
IF/ELSIF/ELSE, CASE, FOR ... BY, WHILE, REPEAT ... UNTIL, EXIT, CONTINUE and RETURN execute with their standard meaning.
- pass
TestLowerIfElsifinlang/st - pass
TestLowerCaseRangesinlang/st - pass
TestLowerForLoopSuminlang/st - pass
TestLowerWhileWithExitinlang/st - pass
TestLowerContinueSkipsEveninlang/st - pass
TestLowerRepeatUntilinlang/st - pass
TestReturnEarlyinlang/ir - pass
TestForByStepAndReturnFromSTinlang/st
ST-027 verified
A CASE label is a constant (literal, named constant or enumeration member), a comma list, or an inclusive lo..hi range; a value outside every label falls to ELSE.
- pass
TestLowerCaseMultipleValuesinlang/st - pass
TestLowerCaseRangesinlang/st - pass
TestCaseConstantLabelFormsinlang/st - pass
TestCaseNamedConstantLabelsinlang/st - pass
TestConformance/st-case-constantsinlang/conformance(4 of 4 passed) - pass
TestConformance/st-enum/CASE labels and comparisons on members, qualified and notinlang/conformance
ST-028 verified
Two CASE labels with the same value are a compile error.
- pass
TestCaseDuplicateLabelValuesinlang/st - pass
TestCaseDuplicateConstantLabelDiagnosedinlang/conformance
ST-029 verified
Assignment is :=, equality is =, and inequality is <>.
ST-030 verified
REGION name ... END_REGION only groups statements (for folding and the Outline); it opens no scope.
- pass
TestRegionIsANoOpGroupinginlang/st - pass
TestRegionInFBAndCaseinlang/st - pass
TestConformance/st-regioninlang/conformance(3 of 3 passed) - pass
TestRegionOpensNoScopeinlang/st
ST-031 verified
Operator precedence, tightest first: unary NOT and -; * / MOD; + -; the comparisons; AND; XOR; OR.
- pass
TestOperatorPrecedenceinlang/st(14 of 14 passed)
ST-032 verified
An INT widens to REAL where one is expected.
ST-033 verified
The other direction (REAL into an INT target) is a compile error; narrowing goes through a conversion.
ST-034 verified
REAL_TO_DINT (or TO_DINT) rounds to nearest with ties to even (2.5 becomes 2, 3.5 becomes 4); TRUNC_DINT truncates toward zero.
- pass
TestConformance/st-conversions-matrix/REAL to integer rounds half to even; TRUNC goes toward zeroinlang/conformance
ST-035 verified
Every IEC <A>_TO_<B> conversion between BOOL, the integer kinds, REAL, LREAL, TIME, LTIME and STRING exists; there are no WSTRING_TO_, CHAR_TO_ or WCHAR_TO_ functions.
- pass
TestConversionMatrixShapeinlang/ir - pass
TestConversionMatrixThroughSTinlang/st - pass
TestConformance/st-conversions-matrixinlang/conformance(9 of 9 passed) - pass
TestNoWideOrCharConversionFunctionsinlang/st(9 of 9 passed)
ST-036 verified
Integer narrowing wraps to the target width (DINT_TO_INT(70000) is 4464).
- pass
TestConformance/st-conversions-matrix/integer narrowing wraps at the target width (DINT to INT, UINT, BYTE)inlang/conformance - pass
TestConversionSemanticsinlang/ir
ST-037 verified
A REAL or a STRING with no value in the target type faults the scan.
- pass
TestConversionRangeFaultsinlang/conformance(9 of 9 passed) - pass
TestStringParseFaultsinlang/conformance(5 of 5 passed) - pass
TestConversionFaultsinlang/ir
ST-038 verified
A function block instance is declared like a variable (dwell : TON;) and invoked as its own statement with named arguments; => copies an output into a target at the call site and dwell.Q reads one anywhere.
ST-039 verified
Struct fields and array elements use .field and [i] on either side of an assignment.
ST-040 verified
An array index outside the declared bounds faults the scan.
- pass
TestScanArrayIndexOutOfBoundsFaultsinruntime(4 of 4 passed)
ST-041 verified
FUNCTION is stateless and returns one value assigned to the function's own name; FUNCTION_BLOCK is stateful and each instance owns its slots.
ST-042 verified
FUNCTION_BLOCK pins may be any type, a user TYPE included.
ST-043 verified
A VAR_IN_OUT pin is a reference: the caller binds a variable with := and the block's writes land in that variable when the call returns.
ST-044 verified
A VAR_EXTERNAL UDT bound to a VAR_IN_OUT pin round-trips through the tag store as one whole-struct write.
ST-045 verified
Every VAR_IN_OUT must be bound at every call, to an assignable of exactly the pin's type.
ST-046 verified
A .st file with no PROGRAM keyword is a library of TYPE, FUNCTION and FUNCTION_BLOCK declarations in scope for every program in the directory; blocks may also be written in .ld/.fbd libraries, composed after the ST libraries.
- pass
TestLibrariesUserFBFromFBDinruntime - pass
TestFBStructPinFromLibraryFileinlang/st - pass
TestLadderFunctionBlockFromSTinlang/ld - pass
TestGlobalConstantsLibraryAloneinlang/st - pass
TestLibrariesComposeSTFirstThenGraphicalininternal/stproject
ST-047 verified
naut check prints gcc-style file:line:col: message diagnostics and exits non-zero when it finds any.
ST-048 verified
Downloading a program warm-swaps it into a running controller with state carried across, and a failed compile leaves the running program untouched.
ST-049 verified
A program in a *_test.yaml runs on a virtual clock and tests assert on tags over virtual time.
- pass
TestConformance/fb-ton/Q false at PT-1ms, true at PT, ET clamps at PTinlang/conformance - pass
TestVirtualDtIsExactinacceptance
ST-050 verified
Pointers and references (REF_TO, dereference) are not supported.
ST-051 verified
VAR_ACCESS, CONFIGURATION, RESOURCE and TASK declarations are not supported; tasks come from nautilus.yaml or Go composition.
ST-052 verified
Subrange types are not supported; TYPE declares only a STRUCT, an enumeration, or an alias.
- pass
TestCheckRejects/subrangeincmd/naut
ST-053 verified
DATE, TOD, TIME_OF_DAY, DT and DATE_AND_TIME are rejected as unknown scalar types, and their literals do not evaluate.
- pass
TestCheckRejects/DATEincmd/naut - pass
TestCheckRejects/TODincmd/naut - pass
TestCheckRejects/TIME_OF_DAYincmd/naut - pass
TestCheckRejects/DTincmd/naut - pass
TestCheckRejects/DATE_AND_TIMEincmd/naut - pass
TestCheckRejects/DATE literalincmd/naut - pass
TestCheckRejects/D literalincmd/naut - pass
TestCheckRejects/D literal dateincmd/naut - pass
TestCheckRejects/DT literalincmd/naut - pass
TestCheckRejects/DATE_AND_TIME literalincmd/naut - pass
TestCheckRejects/TOD literalincmd/naut - pass
TestCheckRejects/TIME_OF_DAY literalincmd/naut
ST-054 verified
Exponentiation with ** is not supported; EXPT(base, exp) is used instead.
- pass
TestConformance/fn-trig-loginlang/conformance(9 of 9 passed) - pass
TestCheckRejects/**incmd/naut
ST-055 verified
Length-qualified strings (STRING[80]) are a parse error.
- pass
TestCheckRejects/STRING[80]incmd/naut
ST-056 verified
Aggregate initializers (:= [1, 2, 3]) in a declaration are a parse error.
- pass
TestCheckRejects/array initializerincmd/naut
ST-057 verified
SCL's # local prefix is rejected with a message saying to drop the #.
- pass
TestHashPrefixRejectedEverywhereinlang/st - pass
TestHashPrefixDiagnosedinlang/conformance(3 of 3 passed)