← board

Multidimensional fixed arrays

Done (commits 48401d9 2-D, 121c913 N-D)

2-D fixed arrays in var sections landed via the flatten-to-1-D design below: both m[i,j] and m[i][j] fold into one linear AN_INDEX at parse time (dims in parallel arrays SymArr2*), so the 1-D path handles codegen unchanged. test_cross_multidim byte-identical on all 4 targets, matches FPC. The single chokepoint was ParseLValueAST (both reads and writes of identifier indexing route through it), so the "~6 sites" worry was overstated.

Follow-ups landed same day:

ALL landed (2026-06-16): param arrays (const+var, commit), N-D to arbitrary rank (121c913), dynamic-array type aliases (separate commit). The "## Gap / ## Scope / ## Recommended design" sections below are the original plan, kept for history — fully delivered.

Gap

Neither multidim fixed-array syntax parses:

var m: array[0..2, 0..2] of Integer;   { Expected: ] }
var m: array[0..2] of array[0..2] of Integer;   { Expected: begin }

and the corresponding m[i, j] / m[i][j] indexing. FPC accepts both and they are common in user code. Single-dimension fixed arrays and nested dynamic arrays both work today; only nested fixed arrays are missing.

Scope

Storage and indexing both reduce to the existing 1D array path, so no backend work is needed (works on all four targets for free):

  1. Type parse (ParseVarSection / typed-const / type-decl array branches): parse array[lo1..hi1, lo2..hi2] of T and array[lo1..hi1] of array[lo2..hi2] of T. Allocate a 1D array via AllocArray(name, T, 0, span1*span2 - 1) where spanK = hiK-loK+1. Record the dims in parallel arrays keyed by sym (do NOT add TSymbol fields — MAX_UFIELD landmine; mirror SymDynDepth): SymArr2[sym]:Boolean, SymArr2Lo1/Span1/Lo2/Span2[sym]:Integer.
  2. Index m[i,j] and m[i][j]: build the flattened 1D index expression (i - lo1) * span2 + (j - lo2) and a single AN_INDEX(m, flatExpr). Both forms collapse to the same thing (FPC treats them identically).

Index-parse sites to touch (the spread-out risk — must be consistent)

All build AN_INDEX and currently parse exactly one [expr]; each needs to accept a comma ([i, j]) and, when the base sym has SymArr2, emit the flattened index. Centralise the flatten in one helper BuildArr2Index(baseNode, sym) called from each:

For m[i][j] (nested AN_INDEX), detect a 2-level index on a SymArr2 base and fold the two into one flattened AN_INDEX at parse time (the inner m[i] row value is not separately representable under flattening — error if used alone).

Build a test_cross_multidim (read+write, both syntaxes, non-zero los, Int64 elems) and wire into all four suites. Because flattening keeps it on the 1D path, expect byte-identical across targets immediately.

Notes