Skip to content

feat(located): support ARRAY at a physical address - #229

Open
JulioSergioFS wants to merge 1 commit into
developmentfrom
feature/gh-565-located-arrays
Open

feat(located): support ARRAY at a physical address#229
JulioSergioFS wants to merge 1 commit into
developmentfrom
feature/gh-565-located-arrays

Conversation

@JulioSergioFS

Copy link
Copy Markdown

Resolves the compiler half of openplc-editor#565 ("Runtime compile error when using array type of Holding Registers").

  • Accept a located 1-D array of an elementary type. The issue was answered upstream with "MatIEC does not support located variables on non-base types" — true then, but that constraint left with MatIEC. Nothing here stands in the way: the descriptor table is flat, one {area, size, index, pointer} row per slot, so an array is N rows rather than a new mechanism. HR AT %MW60 : ARRAY [0..66] OF WORD now expands to 67 descriptors over %MW60..%MW126.
  • Detect address collisions by range overlap, not equality. An array occupies slotCount consecutive slots, so x AT %MW60 : ARRAY [0..66] OF WORD collides with a plain y AT %MW61 : WORD even though the two addresses differ. Comparing addresses for equality — all that was needed while every declaration took one slot — would have let the second variable silently share storage with an element of the first. Kept per size class: %MW0 and %MD0 index different runtime arrays and still do not collide.
  • Fix the pointer initialiser, which is a bug on its own. It located each descriptor with findIndex matching on variable name. With N descriptors sharing one name that resolves every element to slot 0 — element 0 bound N times, elements 1..N-1 left null. Now walks the array by position; the index is right there.

Rejections that stay, with their own message

Multi-dimensional, variable-length (ARRAY [*]), and non-constant bounds have no linear run of addresses to occupy. Each is refused with a sentence saying so, rather than falling through to the type-compatibility error — which is what leaked the internal __INLINE_ARRAY_WORD / __VLA_1D_WORD spelling at the user in the first place. A mismatched element type now reads Array element type 'BOOL' is not compatible with address size 'W', naming the half of the declaration that is actually wrong.

Verification

  • tests/semantic/located-variables.test.ts: 73 green, 15 of them new (element-type validation, named ARRAY TYPE, range collisions, the rejected shapes, bit arrays crossing a byte boundary, one descriptor per element with distinct pointers).
  • Full suite: 1349 passed, 0 failed (tests/semantic + tests/backend + tests/integration), tsc --noEmit clean, no new lint warnings (111 before and after).
  • End to end, compiling and running the generated C++ against the issue's own declaration:
    count=67 bound=67 distinct=67
    range=%MW60..%MW126
    elem3=0xBEEF elem4=0x0000
    
    distinct=67 is the line that pins the findIndex fix — before it, all 67 descriptors pointed at element 0.

Downstream

The editor accepts a located array in its variables table only once it bundles a release containing this. The paired editor PR carries that UI change already, so this needs to be released and the editor's binary-versions.json pin bumped before that PR merges — otherwise the editor accepts the declaration and the bundled v0.6.4 rejects it at compile time.

🤖 Generated with Claude Code

`HR_myData AT %MW60 : ARRAY [0..66] OF WORD` was rejected. The reason
given upstream was that MatIEC could not express a located non-elementary
type (openplc-editor#565) -- but that constraint left with MatIEC, and
nothing in this compiler stands in its way: the descriptor table is flat,
one {area, size, index, pointer} row per slot, so an array is N rows
rather than a new mechanism.

Analyzer: validate the ELEMENT type against the address size class, and
detect duplicates by slot-range overlap instead of address equality -- an
array occupies slotCount consecutive slots, so `x AT %MW60 : ARRAY[0..66]
OF WORD` collides with a plain `y AT %MW61 : WORD` even though the two
addresses differ. Reject the array shapes with no linear layout
(multi-dimensional, variable-length) with their own sentence, so none of
them falls through to the type-compatibility error and reports the
internal `__INLINE_ARRAY_<T>` spelling at the user.

Codegen: expand a located array into one descriptor per element, walking
the address forward by one slot each time (bit addresses continue across
the byte boundary).

Also fix the pointer initialiser, which located each descriptor by
variable NAME. With N descriptors sharing one name that resolved every
element to slot 0: element 0 bound N times, elements 1..N-1 left null.
Walk the array by position instead -- the index is right there.

Verified end to end: the issue's own declaration compiles to 67
descriptors over %MW60..%MW126, all 67 bound to distinct storage, and a
write through one descriptor lands in that element alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant