Interactive grammar §2, landed as syntax-now/backend-later: everything parses and type-checks, but only program modules lower to QBE. Suite 9/9 (3 run + 6 reject), LL(1)-clean first try.
compiler/src/M2.atg)M2 = Unit ".", Unit = DefUnit | ImplUnit | ProgModule
(FIRSTs DEFINITION/IMPLEMENTATION/MODULE — no conflicts).DefUnit: DEFINITION MODULE + imports + CONST/TYPE(opaque)/
VAR, ends with one 230 (lowering = step 4). Procedure headings
arrive with the declarations section (§next).ImplUnit: full DeclSeq + optional BEGIN, ends with one 230.ProgModule: as before + optional Priority ("[" integer "]"
→ 230) + { Import }; only this path calls QbeGen.EndModule.DeclSeq = { ConstBlock | VarBlock | NestedModule ";" }.NestedModule: Wirth form — own scope via PushScope/PopScope,
imports, EXPORT [QUALIFIED] list ; (parse-only, wires in step 4),
optional Priority, decls, optional body without BeginBody
(no fake main in the outer file), one 230 at END.Import: both FROM A IMPORT x, y; and IMPORT A, B; (V2 parity);
names entered as KindImport, use-as-value already 230 via Design.OpaqueBlock: TYPE T; enters a targetless NewAlias() which
resolves to InvalidType until step 4 completes it — cascades
suppressed by the standard Invalid rules.QbeGen.CloseModule (def+mod): closes the .ssa with an honest
# no code remark instead of a bogus main."not supported in step 1 (integers only)" →
"not supported yet" (no tests referenced the old text).t_defunit (CONST+opaque+VAR definition → single 230, no cascades),
t_implunit (→ single 230), t_nested (inner y := 2 checks clean
in its scope, y after END Inner → 201 proves the pop, + 230).
Three units now; both IMPORT forms; classic opaque TYPE T;;
nesting kept (Wirth form + EXPORT); priority accepted-but-230.
Next: § declarations (TYPE syntax, CONST expressions, procedure
headings — including ProcHeading ";" for DefUnit).