Przeglądaj źródła

feat(compiler): signature audit fixes + proc32 WriteOutputFiles

8 SYMTAB swaps (accumulator-first), 9 EXPRESS swaps/drops,
ParseBeginBlock drops VAR rest, D1/D2 resolved, WriteOutputFiles
added. Audit tables in FRONTEND.md.
Eric Streit 1 tydzień temu
rodzic
commit
41e28dff84

+ 6 - 0
SESSION.md

@@ -20,6 +20,12 @@ export map incl. newly found EXPRESS internals; `docs/compiler/` analysis.
 * Drafts are unverified by design: MCD `unassemble.c` diff still pending for all.
 * Commit per step, tag per milestone (`*-v1`).
 
+## 2026-10-03: audit + proc32 applied (`audit-01`)
+proc32 WriteOutputFiles added; 8 SYMTAB + 9 EXPRESS signature swaps applied
+(def headers; bodies/calls positional-consistent by construction); STMT+PASS1
+all KEEP; D1/D2 resolved (map stands); CappedStrLen=StrLen alias noted.
+Next: GENZ80 recon + MCD-diff verification harness.
+
 ## Next steps (in order)
 
 1. DONE (`statemen-draft-v1`): `STATEMEN.MOD` 830 lines + frame-mechanics proof.

+ 23 - 23
src/compiler/EXPRESS.MOD

@@ -107,8 +107,8 @@ PROCEDURE CentralError(ok: BOOLEAN; code: CARDINAL); FORWARD; (* proc1: proven (
 (* Forward refs to group-defined procedures used before definition *)
 PROCEDURE ParseExpression; FORWARD;
 PROCEDURE ParseDesignatorTail; FORWARD;
-PROCEDURE ParseTerm(a, b: CARDINAL); FORWARD; (* FIXME arity: 3-arg call sites *)
-PROCEDURE ParseSetCons(s, flag: CARDINAL); FORWARD; (* FIXME: 1-arg call site *)
+PROCEDURE ParseTerm(flag, t: CARDINAL); FORWARD; (* audit SWAP; 3-arg call sites still FIXME *)
+PROCEDURE ParseSetCons(flag, s: CARDINAL); FORWARD; (* audit SWAP; 1-arg call site still FIXME *)
 PROCEDURE ParseTypeCast(kind: CARDINAL); FORWARD;
 PROCEDURE ParseFuncCall(idx: CARDINAL): CARDINAL; FORWARD;
 PROCEDURE ExpandStdProc43(code: CARDINAL); FORWARD; (* FIXME: 0-arg call site *)
@@ -117,9 +117,9 @@ PROCEDURE ExpandStdProc45(std: CARDINAL); FORWARD; (* FIXME: 0-arg call site *)
 PROCEDURE ExpandStdProc46; FORWARD;
 PROCEDURE GetConstVal; FORWARD;
 PROCEDURE PopExprDesc(d: DescPtr); FORWARD; (* FIXME: 0-arg call sites *)
-PROCEDURE PushExprDesc(src: DescPtr; dst: DescPtr); FORWARD; (* FIXME arities *)
-PROCEDURE ConstToCard(errPos: CARDINAL; c: DescPtr); FORWARD;
-PROCEDURE ConstToInt(errPos: CARDINAL; c: DescPtr); FORWARD;
+PROCEDURE PushExprDesc(dst: DescPtr; src: DescPtr); FORWARD; (* audit SWAP; arities still FIXME *)
+PROCEDURE ConstToCard(c: DescPtr; errPos: CARDINAL); FORWARD;
+PROCEDURE ConstToInt(c: DescPtr; errPos: CARDINAL); FORWARD;
 PROCEDURE MatchOpClass(allowed: BITSET; errCode: CARDINAL); FORWARD;
 PROCEDURE FoldConstOp(resTyp: DescPtr); FORWARD; (* FIXME: kind-result sites *)
 PROCEDURE EmitCompare; FORWARD;
@@ -127,25 +127,25 @@ PROCEDURE EmitRangeCheck; FORWARD;
 PROCEDURE ParseSimpleExpression; FORWARD;
 PROCEDURE LoadOperand; FORWARD;
 PROCEDURE StoreOperand; FORWARD;
-PROCEDURE CheckRelationTypes(t1: ADDRESS; op: CARDINAL); FORWARD; (* FIXME: 1-arg site *)
+PROCEDURE CheckRelationTypes(t1: ADDRESS); FORWARD; (* audit: op unused in body *)
 PROCEDURE FoldRelation(): ADDRESS; FORWARD;
-PROCEDURE ParseFactor(p1, p2, p3, p4, p5: CARDINAL); FORWARD;
+PROCEDURE ParseFactor(p1, p2, p3, p4, p5: CARDINAL); FORWARD; (* audit: name-to-slot mirrored pK->param(6-K); def+calls positionally consistent *)
 PROCEDURE EvalConstExpr; FORWARD;
 PROCEDURE ParseSetOrCastTail; FORWARD;
 PROCEDURE ParseAssignment; FORWARD;
 PROCEDURE IsOrdinal(t: Compiler.RecordPtr): BOOLEAN; FORWARD;
-PROCEDURE IsSet(t1, t2: Compiler.RecordPtr): BOOLEAN; FORWARD;
-PROCEDURE BaseTypeOf(t1, t2: Compiler.RecordPtr): BOOLEAN; FORWARD;
+PROCEDURE IsSet(t2, t1: Compiler.RecordPtr): BOOLEAN; FORWARD;
+PROCEDURE BaseTypeOf(t2, t1: Compiler.RecordPtr): BOOLEAN; FORWARD;
 PROCEDURE CheckAssignable; FORWARD;
-PROCEDURE ParseSelector(needVal: BOOLEAN; base: Compiler.RecordPtr; sel: Compiler.RecordPtr); FORWARD;
-PROCEDURE ParseDesignatorBase(VAR ok1, ok2: BOOLEAN; VAR id1, id2: CARDINAL; p1, p2: CARDINAL): BOOLEAN; FORWARD; (* FIXME: 3/4-arg sites *)
-PROCEDURE GetTypeDesc(dest: ADDRESS; mode: CARDINAL; src: ADDRESS); FORWARD;
+PROCEDURE ParseSelector(sel: Compiler.RecordPtr; needVal: BOOLEAN; base: Compiler.RecordPtr); FORWARD;
+PROCEDURE ParseDesignatorBase(VAR ok1, ok2: BOOLEAN; VAR id1, id2: CARDINAL; p1, p2: CARDINAL): BOOLEAN; FORWARD; (* FIXME 3/4-arg sites; audit: fct_leave 132 = 4 words, not 6 formals *)
+PROCEDURE GetTypeDesc(src: ADDRESS; dest: ADDRESS; mode: CARDINAL); FORWARD;
 PROCEDURE CheckAssignmentCompat(dst: ADDRESS); FORWARD;
 
 (* EXPRESS group 1 — descriptors, predicates, const-fold, designator base, selector *)
 
 (* proc4 @004a — ~PushExprDesc *)
-PROCEDURE PushExprDesc(src: DescPtr; dst: DescPtr);
+PROCEDURE PushExprDesc(dst: DescPtr; src: DescPtr);
 VAR aligned: CARDINAL; (* local word-2 *)
 BEGIN
   {/* 004a */} (* aligned := (src^.extra + 1) DIV 2 * 2 *)
@@ -260,12 +260,12 @@ BEGIN
 END PopExprDesc;
 
 (* proc33 @017d — ~IsSet *)
-PROCEDURE IsSet(t1, t2: RecordPtr): BOOLEAN;
+PROCEDURE IsSet(t2, t1: RecordPtr): BOOLEAN;
 BEGIN
   {/* 017d */} (* set-compatibility: identity, subrange unwrap, BITSET/CARD compat *)
   IF (t2 = t1) THEN RETURN TRUE END;
   IF (t2^.word4 = 1) AND IsSet(t2^.word2, t1) THEN RETURN TRUE END;
-  IF (t1^.word4 = 1) AND IsSet(t1, t2^.word2) THEN RETURN TRUE END;
+  IF (t1^.word4 = 1) AND IsSet(t2, t1^.word2) THEN RETURN TRUE END;
   IF (t2 = Compiler.BitsetType) AND (t1 = Compiler.CardType) THEN RETURN TRUE END;
   IF (t1^.word4 IN BITSET(96H)) OR (t2^.word4 IN BITSET(96H)) THEN
     RETURN TRUE;
@@ -278,7 +278,7 @@ BEGIN
 END IsSet;
 
 (* proc34 @01c5 — ~BaseTypeOf *)
-PROCEDURE BaseTypeOf(t1, t2: RecordPtr): BOOLEAN;
+PROCEDURE BaseTypeOf(t2, t1: RecordPtr): BOOLEAN;
 BEGIN
   {/* 01c5 */} (* base-type compatibility for assignment / param passing *)
   IF (t2 = t1) THEN RETURN TRUE END;
@@ -317,7 +317,7 @@ BEGIN
 END FoldConstOp;
 
 (* proc7 @0275 — ~ConstToCard *)
-PROCEDURE ConstToCard(errPos: CARDINAL; c: DescPtr);
+PROCEDURE ConstToCard(c: DescPtr; errPos: CARDINAL);
 BEGIN
   {/* 0275 */} (* CARDINAL context: reject INTEGER/alias mismatches, negatives *)
   IF (c^.typ <> Compiler.CardType) AND (c^.kind <> 1)
@@ -333,7 +333,7 @@ BEGIN
 END ConstToCard;
 
 (* proc8 @02ac — ~ConstToInt *)
-PROCEDURE ConstToInt(errPos: CARDINAL; c: DescPtr);
+PROCEDURE ConstToInt(c: DescPtr; errPos: CARDINAL);
 BEGIN
   {/* 02ac */} (* INTEGER context: base-type check only *)
   IF NOT BaseTypeOf(c^.typ, curDesc.typ) THEN
@@ -395,7 +395,7 @@ BEGIN
 END CheckAssignable;
 
 (* proc20 @0358 — ~ParseSelector *)
-PROCEDURE ParseSelector(needVal: BOOLEAN; base: RecordPtr; sel: RecordPtr);
+PROCEDURE ParseSelector(sel: RecordPtr; needVal: BOOLEAN; base: RecordPtr);
 VAR
   t: RecordPtr;      (* local-2 *)
   flags: CARDINAL;   (* local-3 *)
@@ -590,7 +590,7 @@ BEGIN
 END ParseFactor;
 
 (*{06a2} PROCEDURE ParseTerm(t, flag) — 2 params *)
-PROCEDURE ParseTerm(t, flag: CARDINAL);
+PROCEDURE ParseTerm(flag, t: CARDINAL);
 VAR a, b, c: CARDINAL;
 BEGIN
   IF Pass1.CondInsert(flag, a, b, c) THEN (*{06a4-06ab} PASS1.proc2 *)
@@ -600,7 +600,7 @@ BEGIN
 END ParseTerm;
 
 (*{0704} PROCEDURE ParseSetCons(s, flag) — 2 params; set constructor *)
-PROCEDURE ParseSetCons(s, flag: CARDINAL);
+PROCEDURE ParseSetCons(flag, s: CARDINAL);
 VAR lo, hi: Desc; mod, res: CARDINAL; first, bad: BOOLEAN; aux: Desc;
     op, k1, k2, m: CARDINAL;
 BEGIN
@@ -943,7 +943,7 @@ BEGIN
 END FoldRelation;
 
 (* proc51 @0c74 — ~CheckRelationTypes: set-constructor relation check *)
-PROCEDURE CheckRelationTypes(t1: ADDRESS; op: CARDINAL);
+PROCEDURE CheckRelationTypes(t1: ADDRESS);
 VAR buf: Desc;
     acc, acc2: BITSET;
     bothConst, anyConst: BOOLEAN;
@@ -1413,7 +1413,7 @@ BEGIN
 END GetConstVal;
 
 (* proc14 @1400 — ~GetTypeDesc *)
-PROCEDURE GetTypeDesc(dest: ADDRESS; mode: CARDINAL; src: ADDRESS);
+PROCEDURE GetTypeDesc(src: ADDRESS; dest: ADDRESS; mode: CARDINAL);
 BEGIN
   GetConstVal; (* proc13 *) (*{1402}*)
   EmitOp(); (* proc6 *) (*{1403}*)

+ 15 - 0
src/compiler/FRONTEND.md

@@ -174,3 +174,18 @@ Declared FORWARD in EXPRESS.MOD = remaining body work. AAAAAA heads = Z80 stubs.
 * PASS1 globals: word2 emitBase, word3 emitTop, word4 nestDepth.
 * ConstToCard/ConstToInt call shapes (type-first) vs EXPRESS.DEF order
   (errPos, c) disagree — signature-audit item (frame rule applied).
+
+## Signature audit 2026-10-03 (all four drafts; frame rule applied)
+Method per proc: body paramK roles vs frame arity vs call-site push shapes.
+STMT+PASS1: all KEEP (only change: ParseBeginBlock drops unused VAR rest;
+CappedStrLen = SCANNER F4FCT2 StrLen with explicit HIGH). D1/D2 swap REFUTED
+by arity (@0411 is 0-param) — map names stand.
+SYMTAB applied SWAPs (accumulator-first): NewString/GetName/PutAttr/GetAttr/
+AllocSym/EnterChained/EnterIdent/UnlinkScope; rest KEEP; DefineProgramModule
+UNKNOWN (now (setAddr, tag) + FIXME).
+EXPRESS applied: PushExprDesc/IsSet/BaseTypeOf/ConstToCard/ConstToInt/
+ParseTerm/ParseSetCons/GetTypeDesc/ParseSelector swaps (def headers; bodies
+and push-order call sites untouched by construction); CheckRelationTypes
+drops unused op; ParseDesignatorBase (6->4) + ParseFactor (mirror) recorded
+as FIXME (need frame re-read); FoldRelation LONGREAL-param noted.
+proc32 = WriteOutputFiles (refutes ~SkipToDeclStart); called from Pass1Main path.

+ 43 - 0
src/compiler/PASS1.MOD

@@ -978,4 +978,47 @@ PROCEDURE Pass1Main; FORWARD;
 (*{105b} 4NAZBA — module init: NO bytes. *)
 PROCEDURE InitPass1; FORWARD;
 
+
+(*{0db2} proc32 — WriteOutputFiles: file-output driver (.SYM via
+  SymTab.SaveSymbolFile vs .MCD via WriteMcdHeader+EmitTypeDesc).
+  0 params. Refutes FRONTEND.md ~SkipToDeclStart (only the head loop
+  skips input). Compiler.word3/word2 flag roles TBD (no DEF slots). *)
+PROCEDURE WriteOutputFiles;
+BEGIN
+  WHILE Scanner.curChar # CHR(255) DO (*{0db4-0db9} *)
+    Scanner.NextChar; (*{0dbb} *)
+    Express.CentralError((Scanner.curChar = CHR(255))
+      OR (Scanner.curChar <= CHR(32)), 32); (*{0dbd-0dcb} *)
+  END;
+  IF 0 IN Scanner.scanOptions THEN (*{0dcf-0dd3} *)
+    Texts.WriteLn(3); (*{0dd5-0dd6} FIXME channel roles TBD *)
+    Texts.WriteString(3, "End of source reached."); (*{0dd8-0df3} *)
+    Texts.WriteLn(3);
+  END;
+  Files.Close(Scanner.sourceFile); (*{0df8-0dfb} FIXME proc identity *)
+  Texts.WriteLn(3);
+  IF Compiler.scopeSpare3 THEN (*{0e00-0e02} FIXME: group read word3; TRUE = .SYM path *)
+    SymTab.SaveSymbolFile; (*{0e04} *)
+    Texts.WriteString(3, "Symbol"); (*{0e06-0e10} *)
+    Scanner.ChangeFileExtension(ComLine.outName, "SYM", TRUE); (*{0e12-0e1c} FIXME ComLine slot *)
+  ELSE
+    WriteMcdHeader; (*{0e21} *)
+    EmitTypeDesc; (*{0e23} *)
+    Scanner.ChangeFileExtension(ComLine.outName, "MCD", TRUE); (*{0e25-0e2f} *)
+    IF NOT Compiler.rangeCheckEnabled THEN (*{0e32-0e35} FIXME: group read word2; polarity TBD *)
+      Files.SetPos(Scanner.codeFile, LONG(CodeGen.windowBase)); (*{0e37-0e3d} FIXME proc/arg order *)
+      Files.WriteBytes(Scanner.codeFile, Scanner.codeBuffer,
+        CodeGen.nextEmitPos - CodeGen.windowBase); (*{0e40-0e4a} FIXME proc identity *)
+      Texts.WriteString(3, "M-code"); (*{0e4d-0e57} *)
+    END;
+  END;
+  IF Compiler.scopeSpare3 OR NOT Compiler.rangeCheckEnabled THEN (*{0e59-0e60} FIXME same flags *)
+    Texts.WriteString(3, " file "); (*{0e62-0e6b} *)
+    Texts.WriteString(3, ComLine.outName); (*{0e6e-0e73} FIXME slot *)
+    Texts.WriteString(3, " produced."); (*{0e75-0e83} *)
+    Files.Close(Scanner.sourceFile); (*{0e85-0e8c} FIXME: finalizer identity TBD *)
+    Texts.WriteLn(3);
+  END;
+END WriteOutputFiles;
+
 END Pass1.

+ 1 - 1
src/compiler/README.md

@@ -17,7 +17,7 @@ No `0x1A`/`0x00` padding, LF line endings.
 | `FRONTEND.md` | export map for `PASS1/STATEMEN/EXPRESS` (+ newly found EXPRESS internals) |
 | `EXPRESS.MOD` | **DRAFT v1, unverified** (CentralError 2-param + MatchOpClass order fixed 2026-10-03) |
 | `STATEMEN.MOD` | **DRAFT v1, unverified**: 830 lines; frame-mechanics proof in header |
-| `PASS1.MOD` | **DRAFT v1, unverified**: 981 lines — decl/type/formal/record machinery, module heads, `DCLS` driver, `MAINDE`, MCD writers; D1–D4 + proc9 disputes in header |
+| `PASS1.MOD` | **DRAFT v1, unverified** (+proc32 `WriteOutputFiles`, +audit swaps) |
 
 Full old->new tables: `RENAME-MAP.md` (module level; params/locals renamed
 per-procedure in the bodies — see the `VAR` blocks and headers inline).

+ 2 - 2
src/compiler/STATEMEN.MOD

@@ -87,7 +87,7 @@ PROCEDURE ParseCaseTail; FORWARD;
 PROCEDURE CloseBlockChain(VAR node: ADDRESS); FORWARD;
 PROCEDURE EmitNameHash(VAR name: ARRAY OF CHAR); FORWARD;
 PROCEDURE EmitComBytes; FORWARD;
-PROCEDURE ParseBeginBlock(tag: CARDINAL; VAR rest: CARDINAL); FORWARD;
+PROCEDURE ParseBeginBlock(tag: CARDINAL); FORWARD; (* audit: frame says 1 param; VAR rest dropped *)
 
 (* STATEMEN group 1 — procedures @0001-0566 *)
 
@@ -741,7 +741,7 @@ BEGIN
   RELEASE(saveHeap);
 END EmitComBytes;
 
-PROCEDURE ParseBeginBlock(tag: CARDINAL; VAR rest: CARDINAL); (* BODY @08a4 *)
+PROCEDURE ParseBeginBlock(tag: CARDINAL); (* BODY @08a4 *)
 VAR
   nonEmpty, wasVar: CARDINAL;
   fix: CARDINAL;

+ 43 - 43
src/compiler/SYMTAB.MOD

@@ -105,12 +105,12 @@ CONST symReadError = 790; (* RAISE code in LibRead {/*0497*/} *)
         UnlinkScope/EnterIdent recursion cycle (group B) ---- *)
 PROCEDURE SymbolAssert(cond: BOOLEAN; code: CARDINAL); FORWARD;
 PROCEDURE CheckNode(node: T1); FORWARD;
-PROCEDURE EnterChained(node: T1; scope: ADDRESS); FORWARD;
-PROCEDURE AllocSym(node: T1; scope: ADDRESS); FORWARD;
-PROCEDURE UnlinkScope(idx: CARDINAL; scope: ADDRESS); FORWARD;
-PROCEDURE EnterIdent(idx: CARDINAL; scope: ADDRESS); FORWARD;
-PROCEDURE PutAttr(src: T1; VAR slot: CARDINAL); FORWARD;
-PROCEDURE GetAttr(idx: CARDINAL; VAR node: T1); FORWARD;
+PROCEDURE EnterChained(scope: ADDRESS; node: T1); FORWARD;
+PROCEDURE AllocSym(scope: ADDRESS; node: T1); FORWARD;
+PROCEDURE UnlinkScope(scope: ADDRESS; idx: CARDINAL); FORWARD;
+PROCEDURE EnterIdent(scope: ADDRESS; idx: CARDINAL); FORWARD;
+PROCEDURE PutAttr(VAR slot: CARDINAL; src: T1); FORWARD;
+PROCEDURE GetAttr(VAR node: T1; idx: CARDINAL); FORWARD;
 PROCEDURE LookupChain(scopeNo: CARDINAL; key: CARDINAL): T1; FORWARD;
 PROCEDURE InitHeaps; FORWARD;
 PROCEDURE EnterStandards; FORWARD;
@@ -189,7 +189,7 @@ BEGIN
   END;
 END CheckNode;
 
-PROCEDURE NewString(src: ADDRESS; VAR off: CARDINAL);
+PROCEDURE NewString(VAR off: CARDINAL; src: ADDRESS);
 (* proc17 @00d4 — intern a string into the string pool; returns pool offset *)
 VAR len: CARDINAL;
 BEGIN
@@ -204,7 +204,7 @@ BEGIN
   END;
 END NewString;
 
-PROCEDURE GetName(off: CARDINAL; VAR name: ADDRESS);
+PROCEDURE GetName(VAR name: ADDRESS; off: CARDINAL);
 (* proc21 @0268 — inverse of NewString: heap copy of pooled string *)
 BEGIN
   IF off <> 0 THEN (*{/*026a*/}*)
@@ -214,7 +214,7 @@ BEGIN
   END;
 END GetName;
 
-PROCEDURE PutAttr(src: T1; VAR slot: CARDINAL);
+PROCEDURE PutAttr(VAR slot: CARDINAL; src: T1);
 (* proc18 @0106 — store a type/attr node into the scope-descriptor table *)
 VAR i: CARDINAL; e: Words; sw: Words;
 BEGIN
@@ -246,7 +246,7 @@ BEGIN
   e := Words(scopeHeapBase + 16 * scopeTop);
   sw := Words(src);
   e^[1] := 0; (*{/*016b*/}*)
-  PutAttr(T1(sw^[2]), e^[2]); (* copy link2 chain {/*016e*/} *)
+  PutAttr(e^[2], T1(sw^[2])); (* copy link2 chain {/*016e*/} *)
   e^[3] := sw^[3]; (*{/*0176*/}*)
   e^[4] := sw^[4]; (* kind {/*017a*/} *)
   CASE sw^[4] OF (* kind switch {/*01b3*/} *)
@@ -254,17 +254,17 @@ BEGIN
     e^[5] := sw^[5]; e^[6] := sw^[6]; (*{/*0182*/}*)
   | 99, 100:
     CheckNode(T1(sw^[5])); (*{/*0192*/}*)
-    EnterChained(T1(sw^[5]), ADR(e^[5])); (*{/*0197*/}*)
+    EnterChained(ADR(e^[5]), T1(sw^[5])); (*{/*0197*/}*)
   | 101:
-    PutAttr(T1(sw^[5]), e^[5]); (*{/*0189*/}*)
+    PutAttr(e^[5], T1(sw^[5])); (*{/*0189*/}*)
   | 102:
-    PutAttr(T1(sw^[5]), e^[5]); (*{/*019e*/}*)
-    PutAttr(T1(sw^[6]), e^[6]);
+    PutAttr(e^[5], T1(sw^[5])); (*{/*019e*/}*)
+    PutAttr(e^[6], T1(sw^[6]));
     e^[7] := sw^[7];
   ELSE (* 92..98: name/link/attr words suffice *)
   END;
 END PutAttr;
-PROCEDURE GetAttr(idx: CARDINAL; VAR node: T1);
+PROCEDURE GetAttr(VAR node: T1; idx: CARDINAL);
 (* proc22 @0281 — load a scope entry back into a heap node (inverse of PutAttr).
    Entry word1 = static node pointer or memoized node (returned as-is). *)
 VAR e: Words; new: T1; nw: Words;
@@ -280,18 +280,18 @@ BEGIN
   nw := Words(new);
   e^[1] := CARDINAL(new); (* memoize {/*029e*/} *)
   node := new; (*{/*02a1*/}*)
-  GetAttr(e^[2], new^.link2); (* subtype {/*02a4*/} *)
+  GetAttr(new^.link2, e^[2]); (* subtype {/*02a4*/} *)
   nw^[3] := e^[3]; (*{/*02ac*/}*)
   CASE e^[4] OF (* kind switch {/*02e1*/} *)
   | 90, 91:
     nw^[5] := e^[5]; nw^[6] := e^[6]; (*{/*02b4*/}*)
   | 99, 100:
-    UnlinkScope(e^[5], ADR(nw^[5])); (*{/*02c4*/}*)
+    UnlinkScope(ADR(nw^[5]), e^[5]); (*{/*02c4*/}*)
   | 101:
-    GetAttr(e^[5], nw^[5]); (*{/*02bb*/}*)
+    GetAttr(nw^[5], e^[5]); (*{/*02bb*/}*)
   | 102:
-    GetAttr(e^[5], nw^[5]); (*{/*02cc*/}*)
-    GetAttr(e^[6], nw^[6]);
+    GetAttr(nw^[5], e^[5]); (*{/*02cc*/}*)
+    GetAttr(nw^[6], e^[6]);
     nw^[7] := e^[7];
   ELSE (* 92..98: nothing beyond words 1..4 *)
   END;
@@ -300,7 +300,7 @@ END GetAttr;
 (* NOTE (group B): the brief asked for AllocSym(nodeKind): T1, but the MCode
    (proc14 @01d7, ProcLeave(2), uses param1+param2) is a 2-param PROCEDURE
    chaining a 14-byte entry onto scope and filling it from node. *)
-PROCEDURE AllocSym(node: T1; scope: ADDRESS);
+PROCEDURE AllocSym(scope: ADDRESS; node: T1);
 (* proc14 @01d7 — chain-allocate a 14-byte symbol-table entry from node *)
 VAR s: Words; n: T1; nw: Words; sw: Words;
 BEGIN
@@ -310,17 +310,17 @@ BEGIN
   n := T1(s); nw := s; sw := Words(node);
   s^[0] := Words(scope)^[0]; (*{/*01e9*/}*)
   Words(scope)^[0] := symTop; (*{/*01ed*/}*)
-  NewString(node^.link1, s^[1]); (*{/*01f0*/}*)
-  PutAttr(node^.link2, s^[2]); (*{/*01f7*/}*)
+  NewString(s^[1], node^.link1); (*{/*01f0*/}*)
+  PutAttr(s^[2], node^.link2); (*{/*01f7*/}*)
   n^.word3 := node^.word3; (*{/*01fe*/}*)
   nw^[5] := sw^[5]; nw^[6] := sw^[6]; (* dword {/*0202*/} *)
   n^.word4 := node^.word4; (* kind {/*0208*/} *)
   IF node^.link2 = Compiler.charArrayDesc THEN (* COMPILER.word12 {/*020c*/} *)
-    NewString(ADDRESS(sw^[5]), nw^[5]); (*{/*0213*/}*)
+    NewString(nw^[5], ADDRESS(sw^[5])); (*{/*0213*/}*)
   ELSIF nw^[4] >= 5 THEN (*{/*021c*/}*)
     CheckNode(T1(sw^[6])); (*{/*0222*/}*)
     nw^[6] := 0; (*{/*0226*/}*)
-    EnterChained(T1(sw^[6]), ADR(nw^[6])); (*{/*0229*/}*)
+    EnterChained(ADR(nw^[6]), T1(sw^[6])); (*{/*0229*/}*)
   ELSIF (nw^[4] = 1) AND (node^.link2 = Compiler.LongrealType) THEN
     (* COMPILER.word11: 8-byte real constant {/*0231*/} *)
     SymbolAssert(strTop + 8 <= strCap, 85); (*{/*023e*/}*)
@@ -329,16 +329,16 @@ BEGIN
   END;
 END AllocSym;
 
-PROCEDURE EnterChained(node: T1; scope: ADDRESS);
+PROCEDURE EnterChained(scope: ADDRESS; node: T1);
 (* proc13 @0259 — append a link0 node chain to scope (oldest first) *)
 BEGIN
   IF node <> NIL THEN (*{/*025b*/}*)
-    EnterChained(node^.link0, scope); (*{/*025f*/}*)
-    AllocSym(node, scope); (*{/*0263*/}*)
+    EnterChained(scope, node^.link0); (*{/*025f*/}*)
+    AllocSym(scope, node); (*{/*0263*/}*)
   END;
 END EnterChained;
 
-PROCEDURE EnterIdent(idx: CARDINAL; scope: ADDRESS);
+PROCEDURE EnterIdent(scope: ADDRESS; idx: CARDINAL);
 (* proc20 @0305 — declare symbol-table entry idx into scope (dup check + attrs) *)
 VAR sentry: Words;          (* symHeapBase + idx*14 *)
     new: T1; nw: Words;
@@ -351,7 +351,7 @@ BEGIN
   new := Scanner.NewNode(sentry^[4]); (* kind; always 14 bytes {/*030d*/} *)
   nw := Words(new);
   nw^[0] := Words(scope)^[0]; (* chain at head {/*0312*/} *)
-  GetName(sentry^[1], nm); (* heap copy of name {/*0316*/} *)
+  GetName(nm, sentry^[1]); (* heap copy of name {/*0316*/} *)
   nw^[1] := CARDINAL(nm);
   nmt := nm;
   existing := Scanner.FindIdent(Scanner.List(scope), nm, 9 IN Scanner.scanOptions);
@@ -362,7 +362,7 @@ BEGIN
     Errors.ReportErrorWithText(1, nmt^); (*{/*033a*/}*)
   END;
   Words(scope)^[0] := CARDINAL(new); (*{/*0341*/}*)
-  GetAttr(sentry^[2], new^.link2); (*{/*0344*/}*)
+  GetAttr(new^.link2, sentry^[2]); (*{/*0344*/}*)
   new^.word3 := BITSET(sentry^[3]); (*{/*034b*/}*)
   new^.word4 := sentry^[4]; (*{/*034f*/}*)
   IF sentry^[4] = 3 THEN (* constant: back-link value node {/*0353*/} *)
@@ -370,13 +370,13 @@ BEGIN
       Words(new^.link2)^[0] := CARDINAL(new); (*{/*035f*/}*)
     END;
   ELSIF new^.link2 = Compiler.charArrayDesc THEN (* COMPILER.word12 {/*0365*/} *)
-    GetName(sentry^[5], nm2); (*{/*0372*/}*)
+    GetName(nm2, sentry^[5]); (*{/*0372*/}*)
     nw^[5] := CARDINAL(nm2);
   ELSIF sentry^[4] >= 5 THEN (*{/*037b*/}*)
     IF existing = NIL THEN (*{/*0381*/}*)
       Scanner.GetStackMark(mark); (*{/*0385*/}*)
       nw^[6] := 0; (*{/*0389*/}*)
-      UnlinkScope(sentry^[6], ADR(nw^[6])); (*{/*038c*/}*)
+      UnlinkScope(ADR(nw^[6]), sentry^[6]); (*{/*038c*/}*)
       IF (sentry^[4] = 5) AND (stageFlag <> 0) THEN (*{/*0393*/} global25 *)
         Compiler.allocateSignature(new, mark); (* COMPILER.dword27 gate {/*039d*/} *)
       END;
@@ -390,14 +390,14 @@ BEGIN
   END;
 END EnterIdent;
 
-PROCEDURE UnlinkScope(idx: CARDINAL; scope: ADDRESS);
+PROCEDURE UnlinkScope(scope: ADDRESS; idx: CARDINAL);
 (* proc19 @03c9 — re-declare a link0 index chain into scope (oldest first) *)
 VAR e: Words;
 BEGIN
   IF idx <> 0 THEN (*{/*03cb*/}*)
     e := Words(symHeapBase + 14 * idx);
-    UnlinkScope(e^[0], scope); (*{/*03cf*/}*)
-    EnterIdent(idx, scope); (*{/*03d8*/}*)
+    UnlinkScope(scope, e^[0]); (*{/*03cf*/}*)
+    EnterIdent(scope, idx); (*{/*03d8*/}*)
   END;
 END UnlinkScope;
 
@@ -551,7 +551,7 @@ VAR
   END ListExports;
 
   PROCEDURE ImportOne(anchor: ADDRESS; symIdx: CARDINAL);
-  (* proc31 @05be, nested. NOTE arg order flipped to B's EnterIdent(idx, scope);
+  (* proc31 @05be, nested. EnterIdent(scope, idx) per audit (pushes (scope,idx));
      original call order was (anchor, symIdx) — MCD diff decides. *)
   VAR e: SymEntryPtr;
   BEGIN
@@ -559,7 +559,7 @@ VAR
       e := symHeapBase + symIdx * 14; (*{/*05c4*/}*)
       ImportOne(anchor, e^.link); (*{/*05ca*/}*)
       IF 0 IN e^.flags THEN (*{/*05d0*/}*)
-        EnterIdent(symIdx, anchor); (*{/*05d6*/}*)
+        EnterIdent(anchor, symIdx); (*{/*05d6*/}*)
       END;
     END;
   END ImportOne;
@@ -642,11 +642,11 @@ BEGIN
         WHILE sib # 0 DO
           e2 := symHeapBase + sib * 14;
           IF (e2^.ref # e^.ref) OR NOT (9 IN e2^.flags) THEN EXIT END; (*{/*072d*/}*)
-          EnterIdent(sib, ADR(currentScope^.link1)); (*{/*0747*/}*)
+          EnterIdent(ADR(currentScope^.link1), sib); (*{/*0747*/}*)
           sib := e2^.link;
         END;
       END;
-      EnterIdent(findIdx, ADR(currentScope^.link1)); (*{/*0756*/}*)
+      EnterIdent(ADR(currentScope^.link1), findIdx); (*{/*0756*/}*)
       Scanner.GetSym; (*{/*075c*/}*)
       Scanner.TestSymbolInSet(BITSET{1,9}); (*{/*075e*/}*)
     UNTIL NOT Scanner.AcceptSymbol(1); (* "," {/*0763*/} *)
@@ -745,7 +745,7 @@ BEGIN
      i.e. list/name swapped; order TBD from @088a. *)
 END BuildBitsetConst;
 
-PROCEDURE DefineProgramModule(fromSeen: CARDINAL);
+PROCEDURE DefineProgramModule(setAddr: ADDRESS; tag: CARDINAL); (*FIXME: audit UNKNOWN — body uses param2 as INCL target, never param1; fromSeen is local-3; 2nd formal role unknown*)
 (* proc3 @089a. FIXME: heavy FIXME — group D's reading of @089a-0914 tangles
    moduleTable^[16] (a Symbol slot) with T1 chain operations; treat as
    first-draft sketch, not ground truth. *)
@@ -800,7 +800,7 @@ BEGIN
   END;
   Scanner.GetStackMark(mark);
   Scanner.CheckStackMark(mark); (* FIXME: group passed symOptions; mark form kept *)
-  UnlinkScope(CARDINAL(modName), modName); (* FIXME: args TBD; proc19 *)
+  UnlinkScope(modName, CARDINAL(modName)); (* FIXME: arg roles TBD; proc19 *)
 END InitSymbolTables;
 
 PROCEDURE NoteImported;
@@ -889,7 +889,7 @@ BEGIN
     IF base^.word4 = 5 THEN INCL(base^.word3, 5) END;
     INC(i);
   END;
-  UnlinkScope(CARDINAL(currentScope^.link1), currentScope^.link1); (* FIXME args *)
+  UnlinkScope(currentScope^.link1, CARDINAL(currentScope^.link1)); (* FIXME arg roles TBD *)
   i := 15;
   WHILE i <= scopeTop DO (*{/*0ae8*/}*)
     base := T1(scopeHeapBase + i * 16);