Verified: Language reference
Each claim the Language reference page makes, with the tests that
prove it in the last green CI run: 152 of 160 verified.
The claims live in docs/claims/functions.yaml.
Last green CI run 16 Oct 2026, 14:48 UTC on c7618d3 · all runtime claims
FN-001 verified
Statements and rungs evaluate top to bottom within a scan: a value written by one is visible to the ones below it in the same scan and to everything on the next scan (the seal-in idiom works).
- pass
TestLadderPrograminruntime - pass
TestSealInLatchinlang/fbd - pass
TestConformance/ld-scan-orderinlang/conformance(2 of 2 passed)
FN-002 verified
A diagnostic raised anywhere in the .ld/.fbd to ST chain lands on the user's own source line (the rung, the FBD statement), because every hop preserves a line map.
- pass
TestLineMapinlang/ld - pass
TestTranspileLineMapinlang/fbd - pass
TestAnalyzeLDHopErrorLandsOnRungininternal/lsp - pass
TestAnalyzeLDFunctionBlocksininternal/lsp - pass
TestAnalyzeFBDParseErrorininternal/lsp - pass
TestAnalyzeFBDMapsDiagnosticsToSourceininternal/lsp
FN-003 partly verified
Logic that does not type-check is a compile diagnostic on the offending line or rung, never a silent coercion (for example a REAL assigned to a BOOL).
FN-004 verified
FBD execution order is network order: network 1 runs completely, then network 2. A read of a later network's FB output sees the value from the previous scan.
FN-005 verified
Statements before the first NETWORK line form an untitled first network, and a body with no NETWORK line is a single network, exactly the program it always was.
FN-006 verified
NETWORK stands alone on its line; a tag that happens to be called Network still works (Network := x is a coil), and a statement on the NETWORK line is refused.
- pass
TestNetworkParseEdgesinlang/fbd
FN-007 verified
A read that crosses a network boundary (an FB output or a wire from another network) draws as a variable box in the reading network, never as a line across bands.
FN-008 verified
Series ladder elements AND together, parallel branch legs OR (legs are series and nest freely), a plain contact passes power when its tag is TRUE and an NC contact (/Tag) when it is FALSE.
- pass
TestRungShapesinlang/ld - pass
TestTranspileRungsinlang/ld - pass
TestConformance/ld-coils/nested branch, bare leg passes at onceinlang/conformance - pass
TestConformance/ld-coils/nested branch, FB leg is Q false at PT-1ms, true at PT, drop resetsinlang/conformance
FN-009 verified
A rising-edge contact (+Tag) passes power for exactly one scan on the tag's 0 to 1 transition and a falling-edge contact (-Tag) for one scan on 1 to 0; holding the input steady fires neither again.
- pass
TestEdgeContactOneShotinlang/ld - pass
TestConformance/ld-coils/+ contact passes one scan on the rise, - contact one scan on the fallinlang/conformance
FN-010 verified
A plain coil sets its tag to the rung condition every scan; a set coil latches (Tag := Tag OR condition) and a reset coil unlatches (Tag := Tag AND NOT condition).
- pass
TestConformance/ld-coils/S coil latches, R coil unlatches, R wins a same-scan tieinlang/conformance - pass
TestConformance/ld-coils/+ contact passes one scan on the rise, - contact one scan on the fallinlang/conformance
FN-011 verified
A P coil is TRUE for exactly one scan when the rung condition rises and an N coil for one scan when it falls.
- pass
TestConformance/ld-coils/P coil is TRUE for exactly one scan on the rising edgeinlang/conformance - pass
TestConformance/ld-coils/N coil is TRUE for exactly one scan on the falling edgeinlang/conformance
FN-012 verified
Edge instances get a stable derived name (from rung name, reference and position among repeats), so the R_TRIG's retained state survives an unrelated edit; two edge contacts on the same tag in one rung are independent instances.
FN-013 verified
A function contact FN(args) passes power when the call yields TRUE, and /FN(args) negates it; the negation applies to any BOOL-yielding contact term (a plain ref, an accessor chain such as /t1.Q, a call such as /GT(a, b)).
- pass
TestNegatedFunctionContactinlang/ld - pass
TestFunctionContactExpressionArgsinlang/ld - pass
TestTranspileRungsinlang/ld - pass
TestConformance/ld-coils/negated function contact passes power when the call returns FALSEinlang/conformance
FN-014 verified
A rung with only a coil is driven by the rail (TRUE), and multiple coils on one rung share the same condition.
FN-015 verified
A rung's only output may be a function block instance, with no trailing coil: its own output (inst.Q, inst.DN) is read elsewhere.
- pass
TestFBOnlyRunginlang/ld - pass
TestConformance/ld-coils/FB-only rung (no coil) still runs, its outputs read elsewhereinlang/conformance
FN-016 verified
A rung's trailing output zone (coils or a rung-final function block) must be contiguous at the rung's right end; a coil ahead of later elements is the compile error "coils must sit at the rung's right end".
FN-017 verified
The BOOL rule: anything that gates ladder power must yield BOOL. Comparisons (GT, GE, LT, LE, EQ, NE) are valid contacts; a numeric function such as ADD(TempC, 0.0) used as a contact is a compile error, not a pass-through.
FN-018 verified
An assignment element { Tag := expr } is made only when the rung has power at that point and passes power through unchanged; several may be chained with ";".
- pass
TestAssignmentElementinlang/ld - pass
TestConformance/ld-assigninlang/conformance(5 of 5 passed)
FN-019 verified
An assignment element's value is evaluated every scan like any block (compiled as a SEL), so an array index in it must stay valid while the rung is false.
- pass
TestLadderAssignmentIndexEvaluatedWhileRungFalseinlang/conformance(4 of 4 passed) - pass
TestAssignmentElementinlang/ld
FN-020 verified
The standard's output binding (inst:TON(PT := T#5S, ET => Elapsed)) stores an FB output into a variable at the call site, in ladder, FBD and ST.
- pass
TestConformance/ld-coils/FB-only rung (no coil) still runs, its outputs read elsewhereinlang/conformance - pass
TestUserFB_OutputBindinginlang/st - pass
TestOutputBindinginlang/fbd - pass
TestLadderOutputBindinginlang/ld
FN-021 verified
An instance output is addressable as inst.Pin anywhere in the program that declares the instance, a non-BOOL pin as a contact's argument included. Another task's program cannot name the instance (t1.Q, or through its program's or task's name): that is an undeclared identifier whose error names the owning program and says to go through a tag. Published to a tag in the owner, the output reaches the other task as of the owner's last committed scan — at once for a reader that scans after the owner, on its next scan for one that scans before.
- pass
TestConformance/ld-coils/FB-only rung (no coil) still runs, its outputs read elsewhereinlang/conformance - pass
TestCrossTaskPublishedInstanceOutputinlang/conformance - pass
TestCrossTaskInstanceIsDiagnosedinlang/conformance(6 of 6 passed) - pass
TestUndeclaredIdentifierWithoutPeerKeepsItsMessageinlang/conformance - pass
TestCheckGoldenCrossTaskInstanceincmd/naut - pass
TestCrossTaskInstanceDiagnosticininternal/lsp
FN-022 verified
The untimed action qualifiers behave as specified: N active while the step is active, S / R set / reset once on the activation scan, P1 / P one scan on activation and P0 one scan on deactivation.
- pass
TestConformance/sfc-qualifiersinlang/conformance(8 of 8 passed) - pass
TestSetActsOnceThenActionMayClearinlang/sfc - pass
TestResetActsOnceThenActionMaySetinlang/sfc
FN-023 verified
The timed qualifiers L, D, SD, DS and SL behave as specified: L active from activation for the duration, D once active the duration, SD / DS / SL stored past leaving the step, SL for the duration even after leaving.
- pass
TestConformance/sfc-timed-qualifiersinlang/conformance(13 of 13 passed)
FN-024 verified
An R acts on its step's activation scan and clears the S, SD, DS and SL latches on its target; a timed SL that has run out stays latched until an R.
- pass
TestConformance/sfc-timed-qualifiers/R resets the stored qualifiersinlang/conformance - pass
TestConformance/sfc-timed-qualifiers/R before PT cuts SL short and stops SD from ever coming oninlang/conformance - pass
TestConformance/sfc-timed-qualifiers/re-entry restarts L and D; a timed-out SL stays off until an Rinlang/conformance - pass
TestConformance/sfc-timed-qualifiers/after an R, SL arms again on the next activationinlang/conformance - pass
TestConformance/sfc-timed-qualifiers/R acts once on its step's activation, not on every scan the step is activeinlang/conformance - pass
TestConformance/sfc-timed-qualifiers/R clears an S latch - the stored body runs on after the step is left until the Rinlang/conformance
FN-025 verified
Both association spellings compile and mean the same: "Q Target;" / "Q Target(T#3S);" and the standard's textual "Target(Q);" / "Target(Q, T#3S);". The duration of a timed qualifier is a TIME literal or a TIME variable.
- pass
TestIECAssociationForminlang/sfc - pass
TestTimedQualifiersParseAndCheckCleaninlang/sfc - pass
TestConformance/sfc-assoc-formsinlang/conformance(3 of 3 passed)
FN-026 verified
Every timed association has its own timer, retained across an online edit.
FN-027 verified
A step's MAXTIME makes Step.ERR TRUE once the step has been active longer than the limit (Step.ERR is legal in transition conditions and action bodies); it stays TRUE after the step is left and clears on the step's next activation.
- pass
TestConformance/sfc-step-maxtimeinlang/conformance(6 of 6 passed)
FN-028 verified
"ERROR :=" on a step mirrors Step.ERR into a BOOL variable (a manifest tag an alarm can watch).
- pass
TestConformance/sfc-step-maxtimeinlang/conformance(6 of 6 passed)
FN-029 verified
Identifiers are case-insensitive in every language: variables, tags, POUs, TYPEs, FB instances and pins, struct members, SFC steps/actions and their .X/.T flags, and FBD wires.
- pass
TestConformance/st-case-insensitiveinlang/conformance(3 of 3 passed) - pass
TestLowerCaseInsensitiveIdentifiersinlang/st - pass
TestCaseInsensitiveCallsKeepSpellinginlang/fbd - pass
TestCaseInsensitiveWiresAndInstancesinlang/fbd - pass
TestTagNamesAreCaseInsensitiveinruntime
FN-030 partly verified
The declaration's spelling is the name shown: the tag store, live values and the HTTP API answer with the declared spelling however a program spells it, and no second tag appears.
FN-031 verified
Two declarations that differ only in case in the same scope (variables, POUs, TYPEs, manifest tags, block pins) are a duplicate-declaration error naming both; the same name in different scopes is fine.
- pass
TestLowerCaseOnlyDuplicatesinlang/st(7 of 7 passed) - pass
TestLowerCaseDifferentScopesCoexistinlang/st - pass
TestTagFilesRejectDuplicates/differing only in caseininternal/project
FN-032 verified
The HTTP API accepts any casing for a tag or member path on writes, and forces and acceptance-test given:/expect: keys accept any casing too.
- pass
TestWriteTagAnyCasinginserver - pass
TestForceAPIAnyCasinginserver - pass
TestTagNamesAreCaseInsensitiveinruntime - pass
TestConformance/st-case-insensitiveinlang/conformance(3 of 3 passed)
FN-033 verified
Every tag the manifest declares is in scope in every PROGRAM (ST, ladder, FBD, SFC) without a declaration.
- pass
TestManifestTagsAreImplicitininternal/project - pass
TestImplicitTagsBindOnlyWhereUsedininternal/project - pass
TestImplicitGlobalsBindOnUseinlang/st - pass
TestConformance/tag-implicit-scopeinlang/conformance(2 of 2 passed)
FN-034 partly verified
A tag's type is its type: (any elementary type, a project TYPE or an ARRAY of either), else the type its init: implies; a tag with neither cannot be typed and naming it is an error that says to give it a type:.
- pass
TestElementaryTagTypesininternal/project - pass
TestImplicitStructTagBindsInOutininternal/project - pass
TestTagTypeFromInitininternal/project - pass
TestTagTypeArrayOfProjectTypeininternal/project - pass
TestUntypedTagErrorWordingininternal/project - pass
TestTagTypesAndUntypedTagsinlang/st
FN-035 partly verified
VAR_EXTERNAL stays legal and must agree with a stated type: (an error at the declaration otherwise); two programs binding one untyped tag with different types is an error naming both.
- pass
TestExplicitDeclarationMustAgreeWithTypedTagininternal/project - pass
TestProgramsDisagreeingOnAnUntypedTagininternal/project - pass
TestTagTypeDisagreementsNameTheirSourcesininternal/project
FN-036 verified
A program's own VAR with a tag's name shadows the tag (IEC scoping), and naut check and the editor warn.
- pass
TestLocalShadowsTagininternal/project - pass
TestCheckGoldenShadowWarningincmd/naut - pass
TestShadowWarningininternal/lsp
FN-037 verified
FUNCTION_BLOCK and FUNCTION bodies do not see tags implicitly; a block reaches a tag only through its own VAR_EXTERNAL.
- pass
TestFunctionBlocksDoNotSeeTagsImplicitlyininternal/project - pass
TestFunctionsDoNotSeeTagsImplicitlyininternal/project
FN-038 verified
A GVL file (a library .st holding a file-level VAR_GLOBAL block) declares globals for every program; one the manifest does not declare is a state tag starting at zero.
- pass
TestGVLComposesIntoEveryProgramininternal/project - pass
TestGVLRedeclarationMustAgreeininternal/project - pass
TestFileScopeVarGlobalAheadOfPrograminlang/st - pass
TestGVLGlobalIsAStateTagAtZeroininternal/project
FN-039 verified
Integer kinds share one 64-bit runtime representation, so arithmetic on INT, DINT, UINT or WORD never wraps at the declared width.
- pass
TestConformance/st-int-widthinlang/conformance(6 of 6 passed)
FN-040 verified
A diagnostic names the declared integer type (DINT, WORD), and partial access knows a DINT has 32 bits.
- pass
TestPartialAccessErrorsNameDeclaredTypeinlang/st
FN-041 verified
TIME counts milliseconds; literals T#500MS, T#5S, T#2M30S parse, and TIME values compare with the ordinary comparisons.
- pass
TestLowerTimeArithmeticinlang/st - pass
TestConformance/fn-conversions/TIME is milliseconds in both directionsinlang/conformance - pass
TestConformance/sfc-step-t/a Step.T condition fires one scan after T reaches PTinlang/conformance - pass
TestParseTimeLiteralsinlang/st
FN-042 verified
Mixed numeric arguments promote to REAL; comparing or combining a STRING with a number is a compile error, not a coercion.
FN-043 verified
A user TYPE is first-class: it can be a variable, a tag, a struct field, an array element, a FUNCTION argument or return and a FUNCTION_BLOCK pin, and structs nest.
FN-044 verified
Assigning a struct or an array copies it (b := a; b.F := 1 leaves a.F alone), and so does passing a struct to a VAR_INPUT pin; only VAR_IN_OUT writes back to the caller.
FN-045 verified
A field or element of a tag assigns directly (P101.Running := TRUE, Levels[2] := 41.0); the whole aggregate round-trips through the tag store.
- pass
TestExternalStructFieldAssignmentinlang/st - pass
TestVarInOutExternalStructFieldinlang/st - pass
TestArrayTagElementAssignsDirectlyininternal/project
FN-046 verified
An enumerated TYPE member without ":= n" takes the previous value plus one (the first, 0); names and values are unique within the type; the type's initial value is the one after the list, else the first member; a Codesys base type after the list is accepted.
- pass
TestEnumBasicsinlang/st - pass
TestEnumDeclarationErrorsinlang/st - pass
TestCodesysEnumTypeCompilesinlang/conformance - pass
TestEnumNumberingOrderingInitinlang/st
FN-047 verified
A member is named qualified (WashState#Fill), or bare where only one enumeration in scope has it or the context says which; otherwise the compiler asks for the qualified form.
- pass
TestEnumAmbiguousMemberResolvedByContextinlang/st - pass
TestEnumTypeErrorsinlang/st - pass
TestConformance/st-enum/CASE labels and comparisons on members, qualified and notinlang/conformance
FN-048 verified
Values of one enumeration compare (=, <>, and < / > by member value) and are CASE labels; assignment is between the same enumeration only, and an enumeration does not mix with an integer and has no arithmetic.
- pass
TestEnumBasicsinlang/st - pass
TestEnumTypeErrorsinlang/st - pass
TestConformance/st-enuminlang/conformance(3 of 3 passed) - pass
TestEnumNumberingOrderingInitinlang/st
FN-049 verified
Enumeration conversion is explicit: TO_INT(s) (or any TO_<type>) gives the member's integer and TO_WashState(n) gives the member with integer n; a number no member has keeps that number.
- pass
TestEnumConversionsinlang/st
FN-050 verified
A manifest tag may be typed with an enumeration, seeded by member name or number.
- pass
TestEnumTypedTagininternal/project - pass
TestConformance/st-enum/a tag of an enumerated type starts at the type's initial memberinlang/conformance - pass
TestEnumTagSeededByNumberininternal/project
FN-051 partly verified
Live values show the member name: /api/state, the live stream, the editors' inline values and acceptance expect: all show and take the member name, while a value underneath is its integer (what Sparkplug, Modbus and the retain store carry).
- pass
TestGivenEnumMemberByPathinacceptance - pass
TestGivenEnumNonMemberNamesMembersinacceptance - pass
TestEnumFromTagStoreinlang/st
FN-052 verified
VAR CONSTANT reads fold at compile time; assigning one (or a field, element or bit of one, or using it as a FOR variable) is a compile error.
- pass
TestConstantCannotBeWritteninlang/st - pass
TestConstantsAndMembersAreNotWritableinlang/conformance - pass
TestConstantFoldsAndPartsCannotBeWritteninlang/st(8 of 8 passed)
FN-053 verified
A constant's value, an initial value and an array bound may be a constant expression (literals, other constants and operators).
- pass
TestConstantInBoundsAndInitialValuesinlang/st - pass
TestConformance/st-global-constants/an INT constant from a constant expression sizes an array and bounds a loopinlang/conformance
FN-054 verified
VAR_GLOBAL CONSTANT in a library file declares project constants, visible to every POU in every language (ST, ladder, FBD, SFC) and folded the same way.
- pass
TestConformance/st-global-constantsinlang/conformance(4 of 4 passed) - pass
TestGlobalConstantsVisibleEverywhereinlang/st - pass
TestGlobalConstantsLibraryAloneinlang/st
FN-055 verified
A project constant is not a tag (no manifest entry, live value or API path), a POU's own declaration of the same name shadows it, and its type is elementary or an enumeration.
- pass
TestLocalShadowsGlobalConstantinlang/st - pass
TestGlobalConstantRulesinlang/st - pass
TestGlobalConstantsVisibleEverywhereinlang/st - pass
TestProjectConstantIsNotATagininternal/project
FN-056 verified
VAR_TEMP starts every scan of a PROGRAM, and every call of a FUNCTION_BLOCK or FUNCTION, at its declared initial value (or its type's zero), never at what the previous scan or call left.
- pass
TestConformance/st-var-tempinlang/conformance(3 of 3 passed) - pass
TestVarTempResetsEveryScaninlang/st - pass
TestVarTempResetsEveryFBCallinlang/st - pass
TestVarTempInFunctioninlang/st
FN-057 verified
A temp cannot be RETAIN and cannot be a function-block instance, and an online edit never carries a temp over.
FN-058 verified
REGION groups statements, nests, appears anywhere a statement can, and changes nothing about how they run: it opens no scope and declares nothing, and REGION is not a reserved word (a variable may be called Region).
- pass
TestConformance/st-regioninlang/conformance(3 of 3 passed) - pass
TestRegionIsANoOpGroupinginlang/st - pass
TestRegionOpensNoScopeinlang/st - pass
TestRegionInFBAndCaseinlang/st
FN-059 verified
A REGION must be closed inside the statement list it opened in (not across an END_IF).
- pass
TestRegionErrorsinlang/st
FN-060 verified
A CASE label is a constant: a literal, a named constant, an enumeration member or a range of them; each label ends the clause before it, named or not.
- pass
TestCaseNamedConstantLabelsinlang/st - pass
TestCaseConstantLabelFormsinlang/st - pass
TestConformance/st-case-constantsinlang/conformance(4 of 4 passed) - pass
TestGlobalConstantsVisibleEverywhereinlang/st - pass
TestConformance/st-enum/CASE labels and comparisons on members, qualified and notinlang/conformance
FN-061 verified
A variable is not a CASE label (compile error).
- pass
TestCaseLabelMustBeConstantinlang/st
FN-062 verified
Two CASE labels with the same value (two constants, a constant and a literal, a value inside a range) are a compile error naming both.
- pass
TestCaseDuplicateLabelValuesinlang/st - pass
TestCaseDuplicateConstantLabelDiagnosedinlang/conformance
FN-063 verified
The SCL "#name" local prefix is rejected wherever it appears with "the # prefix is Siemens SCL syntax; write the name without it", including on an assignment target.
- pass
TestHashPrefixRejectedEverywhereinlang/st - pass
TestHashPrefixDiagnosedinlang/conformance(3 of 3 passed)
FN-064 verified
AND, OR and XOR are logical on BOOL and bitwise on integers, over all 64 bits (-8 AND 6 = 0).
- pass
TestConformance/st-bitwiseinlang/conformance(6 of 6 passed) - pass
TestConformance/st-xorinlang/conformance(4 of 4 passed) - pass
TestConformance/fn-ops/AND, OR and XOR are logical on BOOL (the whole truth table), NOT negates a BOOLinlang/conformance - pass
TestConformance/fn-ops/AND, OR and XOR take a third input - the third one countsinlang/conformance
FN-065 verified
NOT is negation on BOOL and bitwise complement on an integer (NOT 0 = -1, NOT 12 = -13).
- pass
TestConformance/st-bitwiseinlang/conformance(6 of 6 passed) - pass
TestLowerNotOnIntinlang/st - pass
TestConformance/fn-ops/AND, OR and XOR are logical on BOOL (the whole truth table), NOT negates a BOOLinlang/conformance
FN-066 verified
ADD and MUL are n-ary, SUB is binary, and the result has the common type of the arguments: for integers, the narrowest type both widen to (DINT + DINT is DINT, a literal takes the other argument's type, the wider of two signed, unsigned or bit-string types, signed with unsigned the narrowest signed type holding both, a bit string with a number as its unsigned width); an integer with a REAL is a REAL. The type does not cut the value: TO_INT(d1 + d2) with both at 40000 is 14464.
- pass
TestLowerRealArithmeticinlang/st - pass
TestConformance/fn-ops/ADD and MUL are n-ary - the third input counts; SUB is the binary differenceinlang/conformance - pass
TestConformance/fn-ops/an INT combined with a REAL gives a REAL - the common type, nothing truncatedinlang/conformance - pass
TestConformance/fn-ops/DINT + DINT keeps its value past INT's range; a conversion of it wraps only to the targetinlang/conformance - pass
TestArithmeticTakesTheCommonWidthinlang/conformance(24 of 24 passed) - pass
TestArithmeticLiteralTakesTheOperandWidthinlang/conformance(7 of 7 passed) - pass
TestArithmeticBlocksTakeTheCommonWidthinlang/conformance(9 of 9 passed) - pass
TestCommonIntEveryPairinlang/ir - pass
TestB1OperatorArityAndTypesinlang/fbd
FN-067 verified
DIV gives the quotient and MOD the remainder of two integers.
- pass
TestConformance/st-div-zero/ordinary division truncates toward zero, MOD keeps the dividend's signinlang/conformance - pass
TestConformance/fn-ops/DIV of two integers is the quotient, MOD the remainderinlang/conformance
FN-068 verified
DIV by zero yields 0 for integer and REAL (never Inf or NaN), MOD by zero yields 0, and the scan keeps running.
- pass
TestConformance/st-div-zeroinlang/conformance(5 of 5 passed) - pass
TestDivideByZeroCountsAndKeepsScanninginruntime
FN-069 verified
Every divide-by-zero bumps the controller-wide divZero counter in the scan stats (/api/state scan.divZero), counted since start.
FN-070 verified
MOVE passes its single input through as an assignment (FBD wiring aid).
- pass
TestConformance/fn-ops/MOVE passes its single input through unchanged, whatever its typeinlang/conformance - pass
TestB1OperatorArityAndTypesinlang/fbd
FN-071 verified
GT, GE, LT, LE, EQ, NE take two comparable arguments (numeric or TIME) and return BOOL.
- pass
TestConformance/fn-ops/GT GE LT LE EQ NE on INT return BOOL - below, equal, aboveinlang/conformance - pass
TestConformance/fn-ops/GT GE LT LE EQ NE on REAL compare the fractions tooinlang/conformance - pass
TestConformance/fn-ops/GT GE LT LE EQ NE on TIME (milliseconds)inlang/conformance - pass
TestB1OperatorArityAndTypesinlang/fbd
FN-072 verified
A standard-function call is positional or formal (every input by its standard name: LIMIT(MN := 0.0, IN := x, MX := 100.0)); one call is one or the other, never a mix.
- pass
TestENOnFunctionAssigninlang/st - pass
TestENOOnlyAndPositionalinlang/st - pass
TestENErrorsinlang/st - pass
TestENOErrorsinlang/fbd - pass
TestConformance/fn-select-numeric/SEL gives IN0 when G is FALSE and IN1 when G is TRUE, positional or formalinlang/conformance - pass
TestConformance/fn-select-numeric/a formal MUX picks by K over IN0..IN2inlang/conformance - pass
TestConformance/fn-select-numeric/MIN and MAX of three or four inputs find the extreme wherever it sitsinlang/conformance - pass
TestConformance/fn-select-numeric/ABS is the absolute value of an INT, a DINT and a REAL, each in its own typeinlang/conformance
FN-073 verified
SEL(G, IN0, IN1) returns IN0 when G is FALSE and IN1 when G is TRUE.
- pass
TestBuiltinSelMuxinlang/st - pass
TestConformance/fn-select-numeric/SEL gives IN0 when G is FALSE and IN1 when G is TRUE, positional or formalinlang/conformance
FN-074 verified
MUX(K, IN0, ..., INn) picks the K-th input, 0-based.
- pass
TestConformance/st-mux-fault/K picks the K-th input, 0-basedinlang/conformance - pass
TestBuiltinSelMuxinlang/st
FN-075 verified
A MUX selector outside 0..n faults the scan; clamping K with LIMIT keeps it in range.
- pass
TestMuxOutOfRangeFaultsinlang/conformance(4 of 4 passed) - pass
TestConformance/st-mux-fault/LIMIT keeps a wandering selector in range, so the scan never faultsinlang/conformance - pass
TestBuiltinMuxOutOfRangeFaultsinlang/st
FN-076 partly verified
MIN and MAX are n-ary numeric and LIMIT(MN, IN, MX) clamps IN into [MN, MX].
- pass
TestBuiltinMinMaxLimitinlang/st - pass
TestConformance/st-mux-fault/LIMIT keeps a wandering selector in range, so the scan never faultsinlang/conformance - pass
TestConformance/fn-select-numeric/MIN and MAX of three or four inputs find the extreme wherever it sitsinlang/conformance - pass
TestMixedNumericArgsPromoteStringNumberRefusedinlang/st(8 of 8 passed) - pass
TestENOnFunctionAssigninlang/st
FN-077 verified
ABS returns the absolute value in the argument's own type.
- pass
TestBuiltinABSinlang/st - pass
TestConformance/fn-select-numeric/ABS is the absolute value of an INT, a DINT and a REAL, each in its own typeinlang/conformance - pass
TestB1ABSKeepsArgumentTypeinlang/st
FN-078 verified
SQRT, LN, LOG (base 10, not natural), EXP, EXPT and the trigonometric functions SIN/COS/TAN (radians), ASIN/ACOS/ATAN and the quadrant-correct ATAN2 return REAL with the stated meaning.
- pass
TestConformance/fn-trig-loginlang/conformance(9 of 9 passed) - pass
TestBuiltinNumericsinlang/st
FN-079 verified
TRUNC truncates toward zero for both signs, into the 64-bit integer an undeclared INT is; TRUNC_<int> does the same into the typed integer.
- pass
TestConformance/fn-conversions/TRUNC goes toward zero for both signsinlang/conformance - pass
TestConformance/st-conversions-matrix/REAL to integer rounds half to even; TRUNC goes toward zeroinlang/conformance - pass
TestConversionSemanticsinlang/ir - pass
TestBuiltinTruncStaysTruncationinlang/st - pass
TestConformance/fn-select-numeric/TRUNC goes toward zero into a 64-bit integer - a value beyond 32 bits survivesinlang/conformance
FN-080 verified
SHL and SHR shift left / right (SHR zero-fills) and ROL and ROR rotate; all operate over 64 bits, so a WORD you think of as 16 bits rotates as a 64-bit value.
- pass
TestConformance/st-int-width/shifts act on 64 bitsinlang/conformance - pass
TestConformance/st-int-width/ROL and ROR rotate over 64 bits, not the declared 16inlang/conformance - pass
TestBuiltinBitOpsinlang/st
FN-081 verified
Word.3 is bit 3 of an integer as a BOOL, readable anywhere a BOOL is (IF, a ladder contact, a compare argument) and assignable (a ladder coil too), numbered from 0 at the least significant end; the IEC Word.%X3 spelling works, and so do bits of array elements and structure members.
- pass
TestBitAccessinlang/st - pass
TestBitAccessInIfCompareArrayAndStructinlang/st - pass
TestConformance/st-partial-accessinlang/conformance(5 of 5 passed)
FN-082 verified
Partial access (w.%B1, w.%W0, w.%D1, w.%L0) reads as an unsigned integer of that width and writes back only its own bits; ladder contacts/coils and FBD wires take every form.
- pass
TestConformance/st-partial-accessinlang/conformance(5 of 5 passed) - pass
TestPartialAccessReadWriteinlang/st - pass
TestPartialAccessUnsignedAndLinlang/st
FN-083 verified
A partial access must fit the declared type: d.%X32 on a DINT or w.16 on a WORD is a compile error that names the type.
- pass
TestPartialAccessErrorsNameDeclaredTypeinlang/st
FN-084 verified
String functions use 1-based positions, and length and position arguments clamp to the string instead of faulting (LEFT, RIGHT, MID, INSERT, DELETE, REPLACE).
- pass
TestConformance/st-string-clampinlang/conformance(9 of 9 passed) - pass
TestBuiltinStringsinlang/st
FN-085 verified
FIND returns the 1-based position of IN2 in IN1, and 0 when absent or when IN2 is empty.
- pass
TestConformance/st-string-clamp/FIND is 1-based and gives 0 when absent or when the needle is emptyinlang/conformance
FN-086 verified
LEN returns the length, and CONCAT is n-ary.
- pass
TestBuiltinStringsinlang/st - pass
TestConformance/st-string-clamp/in-range arguments behave as the standard says (1-based)inlang/conformance
FN-087 verified
Every <A>_TO_<B> between the 18 elementary types exists (294 functions) except the marked cells, which are compile errors, as is the overloaded TO_<type> for the same cells; there are no implicit conversions across kinds.
FN-088 verified
Integer narrowing wraps: the result keeps the target's low bits, read signed or unsigned as the target is (DINT_TO_INT(70000) = 4464, INT_TO_USINT(-1) = 255, BYTE_TO_SINT(255) = -1, SINT_TO_WORD(-1) = 16#FFFF).
- pass
TestConformance/st-conversions-matrix/integer narrowing wraps at the target width (DINT to INT, UINT, BYTE)inlang/conformance - pass
TestConversionSemanticsinlang/ir
FN-089 verified
The argument of a conversion is read as its own declared type first, so UINT_TO_DINT(u) with u at -1 sees 65535.
- pass
TestConformance/st-conversions-matrix/sign - a signed source sign-extends, an unsigned one does notinlang/conformance - pass
TestConversionSemanticsinlang/ir
FN-090 verified
REAL to integer and REAL to TIME round to nearest, ties to even (2.5 to 2, 3.5 to 4, -2.5 to -2); TRUNC* go toward zero.
- pass
TestConformance/fn-conversions/REAL_TO_INT rounds half to even, not half away from zeroinlang/conformance - pass
TestConformance/fn-conversions/REAL_TO_TIME rounds milliseconds half to eveninlang/conformance - pass
TestConformance/st-conversions-matrix/REAL to integer rounds half to even; TRUNC goes toward zeroinlang/conformance - pass
TestBuiltinRealRoundingTiesToEveninlang/st
FN-091 verified
A REAL with no value in the target (beyond its range, NaN or infinite) faults the scan; LREAL_TO_SINT(127.5) faults while LREAL_TO_SINT(-128.5) rounds to the even -128 and does not.
- pass
TestConversionRangeFaultsinlang/conformance(9 of 9 passed) - pass
TestConversionFaultsinlang/ir - pass
TestConformance/st-conversions-matrix/REAL to integer rounds half to even; TRUNC goes toward zeroinlang/conformance
FN-092 verified
REAL and bit-string conversions are binary transfers of the IEEE 754 pattern, only at the same width (REAL_TO_DWORD(1.0) = 16#3F800000); a pattern that is NaN or infinite faults; REAL_TO_WORD is a compile error that says what to write instead.
- pass
TestConformance/st-conversions-matrix/REAL to DWORD and back is the IEEE 754 bit pattern (binary transfer)inlang/conformance - pass
TestConversionRangeFaults/NaN bit patterninlang/conformance - pass
TestConversionCompileErrorsinlang/st - pass
TestConversionSemanticsinlang/ir - pass
TestConversionInfinitePatternFaultsinlang/ir
FN-093 verified
Integers convert to REAL exactly up to 2^53 (REAL and LREAL are both float64 at run time), ULINT and LWORD convert unsigned, and REAL_TO_LREAL / LREAL_TO_REAL change only the type.
- pass
TestConformance/st-conversions-matrix/integers to REAL - REAL holds LREAL precision hereinlang/conformance - pass
TestConversionSemanticsinlang/ir - pass
TestConversionExactUnsignedAndRealLrealinlang/ir
FN-094 verified
BOOL converts to 0/1 of any numeric type (1 ms for TIME); any number converts to TRUE when it is nonzero in the source width (BYTE_TO_BOOL(256) is FALSE).
- pass
TestConformance/st-conversions-matrix/BOOL is 0 and 1; a number is TRUE when nonzero in the source widthinlang/conformance - pass
TestConformance/fn-conversions/BOOL to INT and REAL, INT and REAL to BOOLinlang/conformance - pass
TestConversionSemanticsinlang/ir
FN-095 verified
TIME and LTIME count milliseconds (LTIME is not nanoseconds), and TIME_TO_INT wraps like any integer narrowing.
- pass
TestConformance/st-conversions-matrix/TIME is milliseconds, and wraps like any integer when narrowedinlang/conformance - pass
TestConformance/fn-conversions/TIME is milliseconds in both directionsinlang/conformance - pass
TestConversionSemanticsinlang/ir
FN-096 verified
STRING_TO_x parses after trimming blanks: decimal or base-prefixed integers (16#FF, 2#1010, 8#17) with _ separators, decimal/exponent REALs, durations (T#1m30s, 90s, 500ms), and BOOL as TRUE/FALSE/1/0 in any case.
- pass
TestConformance/fn-conversions/parsing from STRINGinlang/conformance - pass
TestConformance/st-conversions-matrix/STRING formatting, parsing and round tripsinlang/conformance - pass
TestConversionSemanticsinlang/ir - pass
TestStringParsesEveryDocumentedForminlang/ir
FN-097 verified
Text that does not parse, or parses to a value the target cannot hold (STRING_TO_SINT('128'), STRING_TO_UINT('-1')), faults the scan.
- pass
TestStringParseFaultsinlang/conformance(5 of 5 passed) - pass
TestConversionRangeFaultsinlang/conformance(9 of 9 passed)
FN-098 verified
Formatting to STRING is decimal for integers (unsigned for U- and bit-string types), the shortest exact form for REAL, T#5000ms / LTIME#5000ms for durations, so STRING_TO_x(x_TO_STRING(v)) gives v back.
- pass
TestConformance/fn-conversions/formatting to STRINGinlang/conformance - pass
TestConversionSemanticsinlang/ir - pass
TestConversionStringRoundTripinlang/ir
FN-099 verified
TO_<type>(x) is the overloaded form (an expression's integer converts as LINT, an enumeration as its integer); TRUNC_<int>(x) and <real>_TRUNC_<int>(x) truncate toward zero; TO_<Enum>(n) gives the member.
FN-100 verified
DATE, TIME_OF_DAY and DATE_AND_TIME are not run-time types yet and have no conversions.
FN-101 verified
TON (on-delay): Q rises after IN has been TRUE for PT; ET is the elapsed time.
- pass
TestConformance/fb-toninlang/conformance(7 of 7 passed)
FN-102 verified
TOF (off-delay): Q stays TRUE for PT after IN drops.
- pass
TestConformance/fb-tofinlang/conformance(8 of 8 passed)
FN-103 verified
TP (pulse): rising IN produces a PT-wide TRUE pulse, a rising edge during the pulse is ignored, afterwards ET holds at PT while IN stays TRUE and returns to 0 the scan IN is FALSE.
- pass
TestConformance/fb-tpinlang/conformance(9 of 9 passed)
FN-104 verified
CTU counts rising CU edges, Q is TRUE when CV reaches PV, and R resets.
- pass
TestConformance/fb-ctuinlang/conformance(8 of 8 passed) - pass
TestFBCTUCountsAndResetsinlang/st
FN-105 verified
CTD counts down from PV (LD loads PV), and Q is TRUE when CV is at or below 0.
- pass
TestConformance/fb-ctdinlang/conformance(8 of 8 passed)
FN-106 verified
CTUD (inputs CU, CD, R, LD, PV; outputs QU, QD, CV) is an up/down counter.
- pass
TestConformance/fb-ctudinlang/conformance(9 of 9 passed)
FN-107 verified
R_TRIG's Q is TRUE for exactly one scan on CLK's rising edge.
- pass
TestConformance/fb-r-triginlang/conformance(6 of 6 passed) - pass
TestFBRTrigDetectsRisingEdgeinlang/st
FN-108 verified
F_TRIG's Q is a one-scan pulse on CLK's falling edge.
- pass
TestConformance/fb-f-triginlang/conformance(6 of 6 passed)
FN-109 verified
SR (S1, R → Q1) is a set-dominant latch.
- pass
TestConformance/fb-srinlang/conformance(8 of 8 passed)
FN-110 verified
RS (S, R1 → Q1) is a reset-dominant latch.
- pass
TestConformance/fb-rsinlang/conformance(8 of 8 passed)
FN-111 verified
Each function-block instance keeps its own state between scans, and its outputs read as inst.Pin from any language.
- pass
TestConformance/fb-instancesinlang/conformance(4 of 4 passed) - pass
TestConformance/fb-toninlang/conformance(7 of 7 passed)
FN-112 verified
With EN FALSE a function call does not execute: its result is not assigned and the variable it drives keeps its value.
- pass
TestConformance/fbd-en-eno/EN FALSE leaves the function's result unassignedinlang/conformance - pass
TestConformance/fbd-en-eno/EN FALSE from power-up never assigns (the tag keeps its init)inlang/conformance - pass
TestENOnFunctionAssigninlang/st
FN-113 verified
With EN FALSE a function-block body does not run: outputs, every => binding and internal state (a counter's edge memory, a timer's start) keep their values until it runs again.
- pass
TestConformance/fbd-en-eno/an FB with EN FALSE does not run — edges it misses are not countedinlang/conformance - pass
TestConformance/fbd-en-eno/the FB's edge memory is stale while disabled — a rise across it counts on returninlang/conformance - pass
TestENOnFBCallinlang/st
FN-114 verified
ENO = EN AND no error; a call that errors faults the scan, so a call that returns has ENO = EN, except FBD's DIV and MOD whose ENO is FALSE on a zero divisor (the result is still 0, counted in divZero).
- pass
TestConformance/fbd-en-eno/EN TRUE runs the call and ENO is TRUEinlang/conformance - pass
TestConformance/fbd-en-eno/DIV's ENO is FALSE on a zero divisor, TRUE otherwiseinlang/conformance - pass
TestConformance/fbd-en-eno/DIV with EN FALSE holds its result and reports ENO FALSEinlang/conformance - pass
TestConformance/fbd-en-eno/EN FALSE leaves the function's result unassignedinlang/conformance - pass
TestENOModByZeroinlang/fbd - pass
TestB1FBDDivModZeroENOAndDivZeroinruntime - pass
TestMuxOutOfRangeFaultsinlang/conformance(4 of 4 passed)
FN-115 verified
In ST, EN and ENO are formal arguments (t1(EN := Enable, ..., ENO => t1Ok); LIMIT(EN := ..., ENO => ok)).
FN-116 verified
A function's EN/ENO needs its call to be a statement of its own (the whole right-hand side of an assignment, or a user FUNCTION called as a statement); inside a larger expression it is a compile error.
FN-117 verified
In FBD, any block takes EN/ENO the same way; a block with EN/ENO must drive a variable (never another block's input), and ENO reads as a wire (t1.ENO, sp.ENO) that feeds a coil or the next block's EN.
- pass
TestENOModelAndTranspileinlang/fbd - pass
TestENOFunctionGatesItsCoilinlang/fbd - pass
TestENOErrorsinlang/fbd - pass
TestConformance/fbd-en-enoinlang/conformance(8 of 8 passed) - pass
TestB1ENOFeedsTheNextBlocksENinlang/fbd
FN-118 verified
A user block that declares its own EN input or ENO output keeps them as ordinary pins: its body decides what they mean.
- pass
TestENOnUserFunctionStatementAndOwnENinlang/st
FN-119 verified
In a rung, rung power drives a standard block's power-in pin (TON/TOF/TP IN, CTU CU, CTD CD, R_TRIG/F_TRIG CLK, SR S1, RS S) and continues from its power-out pin (Q, or Q1 for SR/RS).
- pass
TestConformance/fb-toninlang/conformance(7 of 7 passed) - pass
TestConformance/fb-tofinlang/conformance(8 of 8 passed) - pass
TestConformance/fb-tpinlang/conformance(9 of 9 passed) - pass
TestConformance/fb-ctuinlang/conformance(8 of 8 passed) - pass
TestConformance/fb-ctdinlang/conformance(8 of 8 passed) - pass
TestConformance/fb-r-triginlang/conformance(6 of 6 passed) - pass
TestConformance/fb-f-triginlang/conformance(6 of 6 passed) - pass
TestConformance/fb-srinlang/conformance(8 of 8 passed) - pass
TestConformance/fb-rsinlang/conformance(8 of 8 passed)
FN-120 verified
For a user FUNCTION_BLOCK, power drives EN else the first BOOL VAR_INPUT the call does not bind by name, and continues from ENO else the first BOOL VAR_OUTPUT.
FN-121 verified
Passing the power pin explicitly in the argument list (t1:TON(IN := x)) is a compile error: power owns it.
- pass
TestRungErrorsinlang/ld
FN-122 verified
A block with no power-in (every BOOL input bound by name, or none) is called unconditionally and may only sit on a rail-driven rung; with contacts ahead of it is the error "no free BOOL input for the rung's power".
FN-123 verified
A block with no BOOL output passes power through unchanged, so whatever conditioned the block still conditions the coils to its right.
- pass
TestLadderFunctionBlockPowerPinsinlang/ld
FN-124 verified
A user block's pins are resolved from the whole compile (this file's FUNCTION_BLOCKs plus every project library); a block whose type nothing in the compile declares falls back to IN/Q.
- pass
TestLadderFunctionBlockLowersinlang/ld - pass
TestLadderFunctionBlockNestedinlang/ld - pass
TestLadderLibraryProjectRunsininternal/project - pass
TestLadderUndeclaredBlockFallsBackToINQinlang/ld
FN-125 verified
PID output CV is clamped to [CV_MIN, CV_MAX], and leaving both unbound falls back to the IEC 0..100 range instead of pinning CV at zero.
FN-126 verified
DIRECT := FALSE is reverse acting (error = SP - PV, raise CV when PV is low, a heater) and DIRECT := TRUE direct acting (error = PV - SP, a cooling valve).
- pass
TestPIDDirectVsReverseinlang/st
FN-127 verified
Manual mode (AUTO = FALSE): CV tracks CV_MAN and the integral is back-solved every scan so returning to AUTO is bumpless, with no jump in CV.
FN-128 verified
Anti-windup is conditional integration: the integral does not accumulate when that would push the unclamped output further past a rail it has reached, CV comes off the rail as soon as the error reverses, and SAT_HI / SAT_LO report the clamp.
FN-129 partly verified
DT left at 0 (unbound) makes the block measure elapsed time itself from the scan clock; a bound DT is used as seconds since the last call.
FN-130 verified
PID is closed-loop control: around a process it drives PV to the setpoint and holds it there.
- pass
TestPIDStepResponseConvergesinlang/st
FN-131 verified
KP = 0 disables the whole controller, not just the P term; KI = 0 disables integral action and KD = 0 derivative action.
- pass
TestPIDZeroGainsDisableinlang/st(4 of 4 passed)
FN-132 verified
The derivative acts on PV, not on error (a setpoint step never kicks D_TERM), through a fixed first-order filter with time constant KD/10.
- pass
TestPIDDerivativeOnPVFilteredinlang/st(2 of 2 passed)
FN-133 verified
DB is a deadband on error: within +/-DB the P and I terms see zero error, while the D term still sees every PV move.
- pass
TestPIDDeadbandinlang/st
FN-134 verified
RESET = TRUE zeroes the integral this scan.
- pass
TestPIDResetZeroesIntegralinlang/st
FN-135 verified
The diagnostic outputs hold their stated values: ERR is the error before the deadband, and P_TERM, I_TERM, D_TERM are the three contributions to CV.
- pass
TestPIDDiagnosticTermsinlang/st
FN-136 verified
A function-block instance can be declared in an array (Timers : ARRAY[0..3] OF TON); each element is its own instance with its own retained state, callable by index in ST and in a rung, and the index may be a variable.
FN-137 verified
On a Logix target an array of instances is one TIMER[4] tag; an element called with a literal index carries its preset in the tag's data, one called with a computed index takes a MOVE to its .PRE ahead of the rung. Once an array is called with a computed index anywhere, its literal-index calls also re-assert their presets with a MOVE ahead of their rungs.
- pass
TestTimerInstanceArrayOnLogixinlogix/writer(3 of 3 passed) - pass
TestArraysOfBlocksinlogix/writer - pass
TestGolden/arraysinlogix/writer - pass
TestRoundTripArrayPresetsinlogix/importer
FN-138 verified
dialect: names are nautilus (the default, adds nothing), logix, and the reserved siemens and codesys.
- pass
TestLogixLibraryParsesAndIsDeclarationsOnlyininternal/dialect - pass
TestDialectNamesAndDefaultininternal/project
FN-139 verified
The logix dialect's TONR is a TON whose Reset clears the accumulated time and Q while TRUE; the free-running pulse is t:TONR(PT := T#1S, Reset := t.Q).
- pass
TestConformance/dialect-logix-tonrinlang/conformance(5 of 5 passed)
FN-140 verified
On a Logix controller a TONR in ladder is written as a TON with a RES(t) rung ahead of the timer's rung, and in ST as TONR(t) on an FBD_TIMER whose .Reset is TRUE while Reset is TRUE or IN is FALSE.
- pass
TestTONRinlogix/writer
FN-141 verified
A manifest tag's alias: is emitted by the Logix writer as an alias tag, and the L5X importer turns an export's alias tags, and rack points the logic named directly, into tags with alias:, and a rung that names an alias tag imports with the tag typed through its target.
- pass
TestAliasTagsinlogix/writer - pass
TestDialectAndAliasImportinlogix/importer - pass
TestAliasTagImportsWithAliasinlogix/importer - pass
TestAliasTagsInRungsImportAndRoundTripinlogix/importer - pass
TestAliasTagsTheExportCannotTypeAreRefusedByNameinlogix/importer
FN-142 verified
The nautilus runtime ignores a tag's alias: binding: the tag is a tag, so a simulation runs the same source.
- pass
TestConformance/tag-aliasinlang/conformance(2 of 2 passed)
FN-143 partly verified
A FUNCTION_BLOCK pin (VAR_INPUT / VAR_OUTPUT / VAR_IN_OUT / VAR) and a FUNCTION's inputs, locals and return type may be any type, including a user TYPE with nested structs, resolved against the whole compile; a pin naming an undeclared type is a compile error naming the type.
FN-144 verified
A call may leave any VAR_INPUT out: it keeps its value, the declared initial value until something writes it (as an unconnected FB input in TIA or CODESYS); EN, unbound, is TRUE.
FN-145 verified
A VAR_IN_OUT is bound to a variable, and what the block writes into it is visible to the caller when the call returns (scalar, struct local, VAR_EXTERNAL struct tag as one whole-struct write).
FN-146 verified
A VAR_IN_OUT argument must be assignable (a variable, a struct field, an array element or a VAR_EXTERNAL tag); an expression is a compile error.
FN-147 verified
The argument's type must match a VAR_IN_OUT pin exactly (an INT does not stand in for a REAL pin).
- pass
TestVarInOutTypeMustMatchinlang/st
FN-148 verified
Every VAR_IN_OUT must be bound at every call site (a compile error otherwise).
- pass
TestVarInOutMustBeBoundinlang/st
FN-149 verified
A VAR_IN_OUT pin's own type may not be a function block.
- pass
TestVarInOutRejectsFBPinTypeinlang/st
FN-150 verified
Two calls in one scan bound to different variables each see and update their own.
- pass
TestVarInOutTwoCallsSameScanEachOwnVariableinlang/st
FN-151 verified
FUNCTIONs have no VAR_IN_OUT or VAR_OUTPUT: an IEC function is a single return value, and the compiler says so.
- pass
TestFunctionRefusesInOutAndOutputinlang/st(3 of 3 passed)
FN-152 verified
A VAR_IN_OUT is bound with :=, like an input; the => form binds outputs, so it is not the way to bind an IN_OUT (a compile-time rule).
FN-153 verified
A .ld file may define FUNCTION_BLOCKs whose body is rungs, each instance with its own retained state (two pumps are two instances, each with its own seal-in and its own t1).
FN-154 verified
A ladder block's VAR_* sections are ordinary POU declarations, VAR_IN_OUT included, so a ladder block can take a UDT by reference.
- pass
TestLadderFunctionBlockInOutStructPininlang/ld
FN-155 verified
A ladder block is called from ladder with power on its power-in pin and => capturing outputs, and from ST or FBD like any other block.
- pass
TestLadderFunctionBlockRunsinlang/ld - pass
TestLadderFunctionBlockFromSTinlang/ld - pass
TestLadderAndFBDLibrariesCalledFromEveryLanguageininternal/project
FN-156 verified
An FB instance a rung declares inline needs no VAR entry, and a declaration in the POU's own header wins (the rung is a call on it, not a second declaration).
FN-157 verified
A .ld file with no PROGRAM is a project library whose blocks join the prelude ahead of every task, usable from any language; .fbd libraries work the same way.
- pass
TestLadderLibraryComposesininternal/project - pass
TestLadderLibraryProjectRunsininternal/project - pass
TestLadderAndFBDLibrariesCalledFromEveryLanguageininternal/project
FN-158 verified
A library may sit in the project root or under lib/; lib/ holds libraries only (a PROGRAM there is an error) and no other subdirectory composes.
- pass
TestLibDirComposesininternal/project - pass
TestLibDirRefusesAProgramininternal/project - pass
TestOtherSubdirsStayIgnoredininternal/project - pass
TestLadderLibraryProjectRunsininternal/project
FN-159 verified
Composition order is every .st library first, then every transpiled .ld / .fbd library, each group sorted by project-relative path; order never decides whether a call resolves (blocks may reference each other in either direction, across files), only which duplicate is reported.
- pass
TestLadderLibraryComposesininternal/project - pass
TestLibraryPathsRootAndLibininternal/stproject - pass
TestLibDirComposesininternal/project - pass
TestLibDirDuplicateAcrossRootAndLibininternal/project - pass
TestLibraryReferencesResolveInEitherDirectionininternal/project
FN-160 verified
Declaring the same FUNCTION_BLOCK twice in one .ld file is refused with the second declaration's line, before anything is transpiled.
- pass
TestLadderFunctionBlockErrorsinlang/ld