summary_fwdvars-resultsfx.md 3.6 KB

Session summary — 2026-10-01 (c): forward variables, result suffixes

Suite 175/175; self-hosting fixpoint OK (image 2,899,706 bytes). Tag v3-fwdvars-resultsfx.

This session implemented forward module-level variables and expression result suffixes, added several gm2/ISO library modules, and fixed two bugs the new code exposed.

Steps, tags and headline commits

Step Tag What
forward vars + suffixes v3-fwdvars-resultsfx this commit

(Previous tag v3-showcase21 remains the last committed feature step.)

1. Forward module-level variables

A procedure body may reference a module-level variable (scalar, array, …) declared further down the module — gm2 tolerates this, declaration-before-use does not.

  • SymTab records each distinct name (FwdVarRef), resolves it at module end (FwdVarResolve), and exposes IsFwdVar so type checks are lenient while the type is unknown.
  • The designator is emitted with a placeholder symbol ($fwdN) and the load/store is emitted at the default class; at module end QbeGen.FwdPatchAll rewrites the symbol and re-classes the load/store (FixLoadClass/FixStoreClass) over the buffered image.
  • Lenient checks added to ArithCheck, UnaryCheck, OrdCheck, EqCheck, Assignable, and the pointer-compare branch in Expr (which treats an unresolved forward var as a scalar).
  • t_fwdvar.mod exercises counters, booleans and an array declared after their users; exit 42.

2. Expression result suffixes

F()^, F()[i], F().field — components applied to a function-call result, via a new ResultComp production reached only when a call has just parsed (so it stays LL(1)-clean). A final scalar is loaded with ElemLoad; aggregates stay as their descriptor address.

3. Library

Added: LongIO, LongWholeIO, DynamicStrings (core subset), SysStorage, TERMINATION, and (earlier in the day) ConvTypes, IOConsts, SIOResult, StrIO, InOut, StdIO, WholeStr, RealStr, LongStr, LongMath, STextIO, SWholeIO, SRealIO. FileIO gained Exists. The shim gained m2readline, m2writeintwidth, m2realconv, the m2ds* dynamic-string core, and ln/arctan now wrap log/atan.

4. Bugs fixed

  • Procedure values / LONGINT are 8-byte in array load/store and the parameter prologue (were 32-bit) — needed by DynamicStrings and the StdIO procedure stacks.
  • The M2 driver's session file table was capped at 32 sources; raised to 128.
  • Two self-hosting-order violations in QbeGen.mod (procedures used before declaration) and an array-element actual passed to a VAR array formal.
  • ClassOf treats an unresolved alias as pointer-like, which is correct for opaque String but wrong for forward variables; the forward-variable path gives its placeholders scalar semantics and patches the real class at module end.

5. Not done (see docs/language-report.md)

  • Statement-context result suffixes (F()[i] := x) — attempted twice; each restructuring of AssOrCall broke bare parameterless calls under self-hosting. Reverted; the expression form is shipped.
  • Remaining library holes: ChanConsts, GenDevIF, DeviceTablePtr, StdChans, StreamFile, FIO, wrapclock/wraptime/wrapc, TimeString.

Resume

cd .../m2compiler-V3
./bootstrap/fixpoint.sh                       # FIXPOINT OK
cd compiler && ./build.sh && ./run_tests.sh   # 175/175

Files

compiler/src/{M2.atg,SymTab.def,SymTab.mod,QbeGen.def,QbeGen.mod, FileIO.def,FileIO.mod}, compiler/tests/{t_fwdvar.mod}, stdlib/*, runtime/syslib/shim.c, docs/language-report.md, this doc.