summary_step1.7.md 2.9 KB

V3 step 1.7 — declarations: scalar TYPEs, headings, bodies, FORWARD (done 2026-09-19)

Interactive grammar §3, landed syntax-now/backend-later like §2. Suite 15/15 (5 run + 10 reject), LL(1)-clean.

Grammar (compiler/src/M2.atg)

  • TypeBlock<isDef> replaces OpaqueBlock in both DefUnit (TRUE) and DeclSeq (FALSE). TypeItem = ident ("=" Type | /*opaque*/) — the branch happens after the ident so = vs ; keeps it LL(1). Opaque outside DEFINITION → new 231 (frame text added).
  • Scalar-phase Type = TypeIdent | Subrange | Enum. Composites (ARRAY/RECORD/SET/POINTER) are still syntax errors → step 3.
  • TypeIdent factored (named/predef/import-tolerant) and reused by VarDecl (which now also accepts imported type names as Invalid).
  • Subrange = "[" Expr ".." Expr "]": integer-family bounds folded via new SymTab.ConstInt (literals incl. 0x, folded unary minus); non-literal/non-int/inverted bounds → 230. Stored via new NewSubR(lo,hi); baseless FSub resolves to ClInt (ClassOf fix).
  • Enum = "(" idents ")": literals entered as KindConst of the new type. Use of non-INTEGER consts (enum/char/bool/real) is now 230 (Design KindConst branch tightened; NIL stays silent).
  • ProcHeading<pn> (OUT name): EnterProc/ReenterProc + optional formals + optional : TypeIdent result. DefUnit uses it + PopScope.
  • FormalParams: "(" [groups] ")", VAR per group, EnterParam
    • FixPending (params behave as typed variables in bodies).
  • ProcDecl = heading ";" ("FORWARD" | Block); Block parses decls + optional body with END-name check, one 230 (lowering = step 4). Wirth trailing-; convention (V1 parity): DeclSeq uses ProcDecl ";".

SymTab growth (additive, no interface breakage)

KindProc/KindParam; node fields rslt/plink/isVar/fwd; EnterProc (pushes scope), ReenterProc (fwd→body, fresh signature), EnterParam (pend-records + positional chain), SetProcRes/ProcRes/MarkFwd, NewSubR + tlo/thi, ConstInt. PrintTable shows PROC/PARAM.

Bugs found by the new tests (all fixed, suite proved each)

  1. ProcDecl ";" missing → FORWARD's trailing ; misparsed as 'END' expected (V1 had the same separator rule).
  2. [0..9] lexed wrong without Test2's CONTEXT("..") guard on the integer token (spaced [0 .. 9] worked, unspaced didn't).
  3. ReenterProc didn't reset plink → second param list chained onto a NIL tail: SIGABRT heap crash, bisected to fwd+params on both headings.
  4. EnterParam didn't pend-record → params stayed InvalidType and every use falsely 230'd (5 errors in t_proc instead of 1).

Tests

t_types run → 8 (subrange/alias/hex use); t_enumdecl, t_proc (value + VAR formals, result), t_forward (fwd/body pair) → single 230s; t_bad_opaque → 231. Deferred on record: unmatched FORWARD (no body) is silently accepted — step 4 makes it 231; fwd/body signature compare also step 4.