summary_step3.md 2.7 KB

Step 3 — Procedures (tag: step3)

Commit c0f1924 — "step3: procedures — nested, params, recursion, FORWARD, RETURN; 49/49 tests green" (91 files, +2730/−548).

Goal

Procedures (Phase 2 of the plan): declarations incl. nesting, value and VAR parameters, functions, RETURN, recursion, forward declarations; frames per spec §5.2; calls via ED/EC/EE.

What was built

  • SymTab: frame slots (SymSlot), proc depths (SymDepth/CurDepth), proc records numbered 1..64, forward + define signatures with VerifyProc, return-type stack (CurRet/InFunction), new kinds Proc/Param/VarPar.
  • MGen: N-entry proc table (print helper moved to last slot), ProcEntry/Leave, calls via ED (global), EC (directly nested), EE + display walk (11H); actuals evaluated left-to-right into temps, pushed reversed (nested-call-safe frame stack in ActBegin/Value/End, which also own arity/type/ VAR-actual checks); frame-aware loads/stores/addresses.
  • M2c.atg: ProcedureDecl (nested, FORWARD; form verified against gm2 — caret form rejected), Design split into Head+Tail with AssignOrCall, CallTail, ReturnStat, v/vn attributes threading "is plain variable" for VAR-actual checks.
  • Codes 231 (forward mismatch/missing body), 232 (bad RETURN), 233 (invalid call); proc END-name reuse 202 (text widened to "module/procedure name mismatch").

Tests — 49/49 (25 step-2 regressions + 24 new)

14 run: proper/value-params (incl. 6 params)/functions/factorial/ fib/VAR-swap/nested display/forward mutual recursion/early RETURN/ shadowing/nested calls/dropped results/VAR chains/empty bodies/ REAL functions. 10 rejections, each exactly one error: non-proc call, arity, actual type, proper-in-expression, 3× RETURN misuse, forward mismatch, missing body, undeclared callee.

Bugs found and fixed

  1. FORWARD; double-semicolon — the branch must not consume ; (it belongs to Declaration).
  2. Bare P; calls need no parens — empty-call branch in statements (expressions still require parens).
  3. 2EH pops an address off the stack — same-frame indirect access must go through 2CH+60H; deleted LoadStk.
  4. Dead callee value on expression calls (Double(10)+Double(11) → 22) — CallTail drops it on entry.

Research notes

  • Forward syntax confirmed empirically (PROCEDURE P(...); FORWARD; compiles under gm2; ^ and heading-alone do not).
  • Decoder-verified before use: 2E/3E unsigned (outer locals need the 41H/51H path), 11H np=0 valid, EC/EE/ED semantics.
  • Limits: 64 procedures, 64 actuals/call, 16 names per FP-section, 8-deep nested calls; truncating DIV/MOD and eager AND/OR carry over from step 2.