summary_variant-records.md 2.5 KB

Step: variant records

Tag v3-variant-records. Suite 132/132; fixpoint OK (image 2,135,590 bytes).

Grammar

RECORD
  id : INTEGER;                 (* plain fields *)
; CASE k : Kind OF              (* the variant part *)
    circle : radius : INTEGER;
  | square : side : INTEGER;
  | rect   : w, h : INTEGER;
  END
END
  • RecordType = RECORD [ RecItem { ";" [ RecItem ] } ] END, where RecItem is a plain RecField or a CaseField. Because a variant part starts with the CASE keyword it is unambiguously distinguishable from a field (which starts with an identifier), so the grammar stays LL(1).
  • CaseField = CASE tag : Type OF RecFieldList { "|" RecFieldList } END. Each RecFieldList is VarLabel [ ".." VarLabel ] ":" RecField …; labels are parsed but not interpreted (the layout overlays regardless).
  • The tag must be an ordinal type (else error 224).

Layout (SymTab)

  • Fields are registered per record as before; the tag field is recorded via SetVariantTag, and the record is flagged with MarkVariant.
  • ComputeOffsets: fields declared before the tag pack normally; the tag gets the next slot; every branch field overlays in the region after the tag. (Ranks are reverse-declaration, so "before the tag" is ord < tag^.ord.)
  • TypeSizeD: plainSize + tagSize + max(branch field sizes).

Example (Kind, then Shape): id@0, k@4, radius/side/w,h all @8; size 12. Branch fields share storage, so assigning w then h leaves h, and switching k reuses the slot — exactly the variant-record contract.

ResetFields clears a record's pending-field buffer and layout at each | so later branches re-register; field names stay visible for WITH/.field access.

Notes

  • Whole-record equality/assignment for a variant record is not offered (overlapping storage makes a field-by-field copy wrong); the existing array/record strictness gives 213 for such comparisons.
  • WITH over a variant's fields works (verified).

Tests

t_variant.mod (exit 31): plain field + tag + three branches, overlay (w/h share), branch switch (square reuses the slot).

Files

compiler/src/M2.atg (RecItem/CaseField/VarLabel, RecFieldList), compiler/src/SymTab.def/.mod (IsOrdinal, SetVariantTag, MarkVariant, IsVariant, ResetFields, ComputeOffsets, TypeSizeD), compiler/src/compiler.frm (message 236 bad variant record), compiler/tests/t_variant.mod, compiler/run_tests.sh, docs/features.md.