Pārlūkot izejas kodu

feat(compiler): rewrite EXPRESS group-3 section to Desc model

Replaces worker text using .wordN/RECORD10 forms with unified
curDesc.raw[N]/Desc/Words() forms; adds missing FORWARDs
(EmitDescriptor2, FoldLong*, EmitSetOrArrayAssign); fixes
ParseDesignatorBase call to 4-formal roles.
Eric Streit 1 nedēļu atpakaļ
vecāks
revīzija
c3459bd740
1 mainītis faili ar 221 papildinājumiem un 225 dzēšanām
  1. 221 225
      src/compiler/EXPRESS.MOD

+ 221 - 225
src/compiler/EXPRESS.MOD

@@ -104,6 +104,11 @@ PROCEDURE CentralError(ok: BOOLEAN; code: CARDINAL); FORWARD; (* proc1: proven (
 (*FIXME-NYC*) PROCEDURE CheckForwardRef; FORWARD;
 (*FIXME-NYC*) PROCEDURE CheckAssignable2(t: ADDRESS); FORWARD;
 (*FIXME-NYC*) PROCEDURE EmitOperand31(n: ADDRESS); FORWARD;
+(*FIXME-NYC*) PROCEDURE EmitDescriptor2(d: Desc); FORWARD; (* proc2 *)
+(*FIXME-NYC*) PROCEDURE FoldLongRelation(d: Desc); FORWARD; (* DOUBLES.qmul + proc47 *)
+(*FIXME-NYC*) PROCEDURE FoldLongDiv(d: Desc); FORWARD; (* DOUBLES.qdiv + proc47 *)
+(*FIXME-NYC*) PROCEDURE FoldLongAdd(d: Desc); FORWARD; (* DOUBLES.qadd + proc47 *)
+(*FIXME-NYC*) PROCEDURE EmitSetOrArrayAssign(d: Desc); FORWARD; (* proc11 pair *)
 (* Forward refs to group-defined procedures used before definition *)
 PROCEDURE ParseExpression; FORWARD;
 PROCEDURE ParseDesignatorTail; FORWARD;
@@ -881,6 +886,8 @@ END ParseSetOrCastTail;
    ParseExpression, const/type getters, assignment, init *)
 
 (* proc18 @0bd2 — ~LoadOperand *)
+(* EXPRESS group 3 — @0bd2..1516 *)
+
 PROCEDURE LoadOperand;
 VAR savedNode: ADDRESS;
 BEGIN
@@ -889,59 +896,56 @@ BEGIN
     RETURN;
   END;
   CodeGen.EmitSystemCall(20); (*{0bde}*)
-  savedNode := Scanner.curNode; (*{0be3}*)
+  savedNode := Scanner.curNode; (*{0be3} FIXME: ADDRESS := RecordPtr pun *)
   Scanner.GetSym; (*{0be6}*)
-  IF (curDesc.word2 # 0) OR (curDesc.word6 # 0) THEN (*{0be8-0bf0}*)
-    Scanner.TestSymbolRange40(8); (*{0bf2}*)
+  IF (curDesc.raw[2] # 0) OR (curDesc.raw[6] # 0) THEN (*{0be8-0bf0}*)
+    Scanner.TestSymbolRange40(8); (*{0bf2} FIXME: CARDINAL set pun *)
   END;
   IF Scanner.AcceptSymbol(43) THEN (*{0bf5} '(' *)
-    ParseTerm(savedNode, curDesc.word6, savedNode); (* proc37; FIXME: 3-arg call, signature TBD *)
+    ParseTerm(savedNode, curDesc.raw[6], savedNode); (* proc37; FIXME: 3 args vs (flag,t) *)
   END;
-  EmitOperand31(savedNode); (* proc31; FIXME: NYC — decompile *)
-  curDesc.word0 := savedNode; (*{0c03-0c06}*)
-  curDesc.word1 := 2; (*{0c07-0c09}*)
+  EmitOperand31(savedNode); (* proc31 FIXME *)
+  curDesc.raw[0] := savedNode; (*{0c03-0c06} FIXME pun *)
+  curDesc.raw[1] := 2; (*{0c07-0c09}*)
 END LoadOperand;
 
-(* proc19 @0c0c — ~StoreOperand *)
 PROCEDURE StoreOperand;
 VAR mark: ADDRESS; savedSp: CARDINAL; savedDesc: Desc; size: CARDINAL;
 BEGIN
   Scanner.GetStackMark(mark); (*{0c0e}*)
-  savedSp := spillTop; (*{0c11} global3 *)
+  savedSp := spillTop; (*{0c11} *)
   savedDesc := curDesc; (*{0c13-0c15}*)
-  IF 36 IN curDesc.word4 THEN (*{0c16-0c1b}*)
-    EmitDescriptor2(curDesc); (* proc2; FIXME: NYC *)
-    PushExprDesc(mark, Compiler.ProcType); (* proc4; FIXME *)
-    PopExprDesc(mark); (* proc3; FIXME *)
+  IF 36 IN curDesc.raw[4] THEN (*{0c16-0c1b} FIXME set TBD *)
+    EmitDescriptor2(curDesc); (* proc2 FIXME *)
+    PushExprDesc(mark, Compiler.ProcType); (* proc4 FIXME: (dst,src) roles TBD *)
+    PopExprDesc(mark); (* proc3 FIXME: ADDRESS arg *)
   ELSE
-    mark^ := curDesc; (*{0c28-0c2b} copy block 10 *)
+    mark^ := curDesc; (*{0c28-0c2b} FIXME: ADDRESS-deref block copy *)
   END;
   CodeGen.EmitSystemCall(20); (*{0c2c}*)
-  ParseTerm(savedDesc, savedDesc, savedDesc); (* proc37; FIXME arity *)
+  ParseTerm(savedDesc.raw[0], savedDesc.raw[0], savedDesc.raw[0]); (* proc37 FIXME arity/shape *)
   EmitDescriptor2(curDesc); (* proc2 *)
   CodeGen.EmitStandardOp(13); (*{0c39}*)
-  curDesc.word0 := savedDesc.word2; (*{0c3c-0c3f}*)
-  curDesc.word1 := 2; (*{0c40-0c42}*)
+  curDesc.raw[0] := savedDesc.raw[2]; (*{0c3c-0c3f} FIXME *)
+  curDesc.raw[1] := 2; (*{0c40-0c42}*)
   size := 0; (*{0c43-0c44}*)
-  IF savedDesc.word2 # 0 THEN (*{0c45-0c47}*)
-    size := savedDesc.word2 + savedDesc.word3; (*{0c4a-0c4d}*)
+  IF savedDesc.raw[2] # 0 THEN (*{0c45-0c47}*)
+    size := savedDesc.raw[2] + savedDesc.raw[3]; (*{0c4a-0c4d}*)
   END;
-  CodeGen.EmitExtCall3(19, savedDesc.word5, size); (*{0c4e-0c52}*)
+  CodeGen.EmitExtCall3(19, savedDesc.raw[5], size); (*{0c4e-0c52}*)
   size := (size + 1) DIV 2 * 2; (*{0c54-0c5a}*)
   CodeGen.EmitExtCall3(size DIV 256, 0, 0);
   spillTop := savedSp; (*{0c5d-0c5e}*)
 END StoreOperand;
 
-(* proc47 @0c61 — ~FoldRelation: spill LONGREAL operand to temp, return it *)
 PROCEDURE FoldRelation(): ADDRESS;
 VAR tmp: ADDRESS;
 BEGIN
   Scanner.Allocate(tmp, 8); (*{0c63-0c67}*)
-  tmp := curDesc.word2; (*{0c69} FIXME: LONGREAL pun, TBD *)
+  tmp := curDesc.raw[2]; (*{0c69} FIXME: LONGREAL pun *)
   RETURN tmp;
 END FoldRelation;
 
-(* proc51 @0c74 — ~CheckRelationTypes: set-constructor relation check *)
 PROCEDURE CheckRelationTypes(t1: ADDRESS);
 VAR buf: Desc;
     acc, acc2: BITSET;
@@ -954,28 +958,28 @@ BEGIN
   END;
   BoolCondHelper; (* proc12 *) (*{0c83}*)
   ConstToCard(t1, 0); (* proc7 *) (*{0c84-0c86}*)
-  PopExprDesc(t1); (* proc5 *) (*{0c88-0c8a}*)
+  PopExprDesc(t1); (* proc5 FIXME: ADDRESS arg *) (*{0c88-0c8a}*)
   IF ~ Scanner.AcceptSymbol(4) THEN (*{0c8b-0c8e} single element *)
-    anyConst := curDesc.word1 # 0; (*{0cc9-0ccc}*)
+    anyConst := curDesc.raw[1] # 0; (*{0cc9-0ccc}*)
     IF anyConst THEN CodeGen.EmitStandardOp(5); (*{0cd0}*)
     ELSE
       CodeGen.DiscardPending; (*{0cd5}*)
-      acc := acc + BITSET{Power2(curDesc.word2)}; (*{0cd7-0cdc} FIXME: Power2 NYC *)
+      acc := acc + BITSET{Power2(curDesc.raw[2])}; (*{0cd7-0cdc} FIXME *)
     END;
   ELSE
     buf := curDesc; (*{0c90-0c93}*)
     BoolCondHelper; (*{0c94}*)
     ConstToCard(t1, 0); (*{0c95-0c97}*)
-    PopExprDesc(t1); (*{0c99-0c9b}*)
-    bothConst := (curDesc.word1 # 0) OR (buf.mode # 0); (*{0c9c-0ca4}*)
+    PopExprDesc(t1); (*{0c99-0c9b} FIXME *)
+    bothConst := (curDesc.raw[1] # 0) OR (buf.raw[1] # 0); (*{0c9c-0ca4}*)
     IF bothConst THEN
       CodeGen.EmitStandardOp(26); (*{0ca8-0caa} set AND folded *)
     ELSE
       CodeGen.DiscardPending; (*{0cae}*)
       CodeGen.DiscardPending; (*{0cb0}*)
-      lo := buf.value; hi := curDesc.word2; (*{0cb2-0cb7}*)
+      lo := buf.raw[2]; hi := curDesc.raw[2]; (*{0cb2-0cb7}*)
       WHILE lo <= hi DO (*{0cb8-0cbb}*)
-        acc := acc + BITSET{Power2(lo)}; (*{0cbd-0cc1}*)
+        acc := acc + BITSET{Power2(lo)}; (*{0cbd-0cc1} FIXME *)
         INC(lo); (*{0cc2-0cc5}*)
       END;
     END;
@@ -987,81 +991,80 @@ BEGIN
       acc2 := {1}; (*{0ce9-0cea}*)
     END;
   END;
-  Scanner.TestSymbolInSet(130); (*{0ceb-0ced} relop set *)
+  Scanner.TestSymbolInSet(130); (*{0ceb-0ced} FIXME: CARDINAL set pun *)
   IF ~ Scanner.AcceptSymbol(1) THEN (*{0cef-0cf3} *)
     Scanner.GetSym; (*{0cf5}*)
   END;
   IF acc2 # {} THEN (*{0cf7-0cf8}*)
     IF acc # {} THEN (*{0cfa-0cfc}*)
-      CodeGen.QueueConst(acc); (*{0cff-0d00} FIXME: BITSET arg pun *)
+      CodeGen.QueueConst(CARDINAL(acc)); (*{0cff-0d00} FIXME pun *)
       CodeGen.EmitTypedOp(6, 4); (*{0d02-0d04}*)
     END;
-    curDesc.word1 := 2; (*{0d06-0d08}*)
+    curDesc.raw[1] := 2; (*{0d06-0d08}*)
   ELSE
-    CodeGen.QueueConst(acc); (*{0d0b-0d0d}*)
-    curDesc.word1 := 0; (*{0d0e-0d10} const set *)
-    curDesc.word2 := acc; (*{0d11-0d13} FIXME: BITSET pun *)
+    CodeGen.QueueConst(CARDINAL(acc)); (*{0d0b-0d0d} FIXME *)
+    curDesc.raw[1] := 0; (*{0d0e-0d10} const set *)
+    curDesc.raw[2] := CARDINAL(acc); (*{0d11-0d13} FIXME *)
   END;
-  curDesc.word0 := t1; (*{0d14-0d16} result type *)
+  curDesc.raw[0] := t1; (*{0d14-0d16} FIXME pun *)
 END CheckRelationTypes;
 
-(* proc50 @0d1a — ~EmitCompare: factor-level dispatch (NOT/paren/const/call/var) *)
 PROCEDURE EmitCompare;
 VAR t: ADDRESS;
 BEGIN
   IF Scanner.curSymbol = 66 THEN (* NOT *) (*{0d1c-0d21}*)
     Scanner.GetSym; (*{0d23}*)
     EmitCompare; (* with_frame proc50 *) (*{0d25}*)
-    ConstToCard(Compiler.BooleanType, 66); (* proc7; FIXME: group wrote word14 *)
-    IF curDesc.word1 = 0 THEN (*{0d2d-0d30}*)
+    ConstToCard(Compiler.BooleanType, 66); (* proc7 *) (*{0d28-0d2c}*)
+    IF curDesc.raw[1] = 0 THEN (*{0d2d-0d30}*)
       CodeGen.DiscardPending; (*{0d32}*)
-      curDesc.word2 := NOT curDesc.word2; (*{0d34-0d39} FIXME: CARDINAL NOT pun *)
-      EmitDescriptor2(curDesc); (* proc2 *)
+      curDesc.raw[2] := NOT curDesc.raw[2]; (*{0d34-0d39} FIXME pun *)
+      EmitDescriptor2(curDesc); (* proc2 *) (*{0d3a-0d3d}*)
     ELSE
       CodeGen.EmitStandardOp(3); (*{0d3d-0d3f}*)
     END;
     RETURN;
   END;
-  IF Scanner.curSymbol IN BITSET{43..47} THEN (*{0d43-0d49}*)
+  IF Scanner.curSymbol IN BITSET{43..47} THEN (*{0d43-0d49} FIXME set TBD *)
     IF Scanner.AcceptSymbol(43) THEN (* '(' expr ')' *) (*{0d4b-0d4f}*)
       BoolCondHelper; (* proc12 *) (*{0d51}*)
       Scanner.ExpectSymbol(5); (*{0d52-0d53} ')' *)
     ELSE
       Scanner.GetSym; (*{0d57}*)
-      CheckRelationTypes(Compiler.BitsetType); (* proc51; FIXME: group wrote word15 *)
+      CheckRelationTypes(Compiler.BitsetType); (* proc51 *) (*{0d59-0d5b}*)
     END;
     RETURN;
   END;
   Scanner.PushWithScope; (*{0d5f}*)
-  t := Scanner.literalType; (*{0d61-0d63}*)
-  curDesc.word0 := t; (*{0d64-0d66}*)
+  t := Scanner.literalType; (*{0d61-0d63} FIXME: ADDRESS := RecordPtr pun *)
+  curDesc.raw[0] := t; (*{0d64-0d66} FIXME *)
   IF ~ Scanner.isLiteral THEN (*{0d67-0d69}*)
-    curDesc.word1 := 0; (*{0d6b-0d6d}*)
-    IF t = Compiler.charArrayDesc THEN (* FIXME: group wrote word12=CHAR const? *)
-      Scanner.CopyStringToHeap(curDesc, Scanner.tokenBuffer); (*{0d74-0d7b} FIXME: arg order *)
-      curDesc.word3 := 0; (*{0d7e-0d80}*)
-    ELSIF t^.word4 IN BITSET{384} THEN (*{0d83-0d89} REAL/LONGREAL class *)
-      IF t^.word3 = 8 THEN (*{0d8b-0d8f} LONGREAL *)
-        FoldRelation(); (* proc47; FIXME: group passed longrealValue, dropped *)
+    curDesc.raw[1] := 0; (*{0d6b-0d6d}*)
+    IF t = Compiler.charArrayDesc THEN (*{0d6e-0d72} FIXME: group hedged CHAR/str *)
+      Scanner.CopyStringToHeap(curDesc, Scanner.tokenBuffer); (*{0d74-0d7b} FIXME: (dest,src) vs DEF order *)
+      curDesc.raw[3] := 0; (*{0d7e-0d80}*)
+    ELSIF Words(t)^[4] IN BITSET{384} THEN (*{0d83-0d89} FIXME set TBD *)
+      IF Words(t)^[3] = 8 THEN (*{0d8b-0d8f} LONGREAL *)
+        FoldRelation(); (* proc47; result dropped FIXME *)
       ELSE
-        curDesc.word2 := Scanner.cardValue; (*{0d99-0d9d}*)
+        curDesc.raw[2] := Scanner.cardValue; (*{0d99-0d9d}*)
       END;
     ELSE
-      curDesc.word2 := Scanner.cardValue; (*{0da1-0da4}*)
+      curDesc.raw[2] := Scanner.cardValue; (*{0da1-0da4}*)
     END;
     EmitDescriptor2(curDesc); (* proc2 *) (*{0da5}*)
     Scanner.GetSym; (*{0da7}*)
     RETURN;
   END;
-  CASE Scanner.identKind OF (*{0dab-0daf} word9 *)
+  CASE Scanner.identKind OF (*{0dab-0daf} *)
   | 1: (* const *) (*{0daf}*)
-      curDesc.word1 := 0; (*{0db0-0db2}*)
-      curDesc.word2 := curDesc.word2; (*{0db3-0db7} FIXME: const value copy TBD *)
+      curDesc.raw[1] := 0; (*{0db0-0db2}*)
+      curDesc.raw[2] := curDesc.raw[2]; (*{0db3-0db7} FIXME: const value copy TBD *)
       EmitDescriptor2(curDesc); (* proc2 *) (*{0db9-0dba}*)
       Scanner.GetSym; (*{0dbb}*)
   | 3: (* parenthesised / builtin *) (*{0dbe}*)
       Scanner.GetSym; (*{0dbe}*)
-      Scanner.TestSymbolRange40(40); (*{0dc0-0dc2}*)
+      Scanner.TestSymbolRange40(40); (*{0dc0-0dc2} FIXME arity *)
       IF Scanner.AcceptSymbol(45) THEN (*{0dc4-0dc8}*)
         MatchOpClass(16, 45); (* proc9 *) (*{0dca-0dce}*)
         CheckRelationTypes(t); (* nested proc51 *) (*{0dcf-0dd0}*)
@@ -1069,12 +1072,12 @@ BEGIN
         MatchOpClass(511, 43); (* proc9 *) (*{0dd4-0dd9}*)
         Scanner.GetSym; (*{0dda}*)
         BoolCondHelper; (* proc12 *) (*{0ddc}*)
-        MatchOpClass(511, 0); (* proc9 *) (*{0ddd-0de1}*)
-        IF (t^.word3 + 1) DIV 2 # (curDesc.word0^.word3 + 1) DIV 2 THEN
-          Errors.ReportError(66); (*{0de2-0e00}*)
+        MatchOpClass(511, 0); (* proc9 *) (*{0ddd-0de1} FIXME errCode 0 *)
+        IF (Words(t)^[3] + 1) DIV 2 # (Words(curDesc.raw[0])^[3] + 1) DIV 2 THEN
+          Errors.ReportError(66); (*{0de2-0e00} FIXME pun *)
         END;
-        curDesc.word0 := t; (*{0df1-0df4}*)
-        curDesc.word1 := 2; (*{0df5-0df7}*)
+        curDesc.raw[0] := t; (*{0df1-0df4} FIXME *)
+        curDesc.raw[1] := 2; (*{0df5-0df7}*)
         Scanner.ExpectSymbol(5); (*{0df8} ')' *)
       END;
   | 4: (* designator *) (*{0dfb}*)
@@ -1082,23 +1085,22 @@ BEGIN
       IF Scanner.curSymbol = 43 THEN (* '(' call *) (*{0dfc-0e01}*)
         Scanner.GetSym; (*{0e03}*)
         MatchOpClass(512, 43); (* proc9 *) (*{0e05-0e0a}*)
-        IF t^.word2 # 0 THEN Errors.ReportError(60) END; (*{0e0b-0e10}*)
+        IF Words(t)^[2] # 0 THEN Errors.ReportError(60) END; (*{0e0b-0e10} FIXME *)
         StoreOperand; (* proc19 *) (*{0e11}*)
       ELSE
         EmitDescriptor2(curDesc); (* proc2 *) (*{0e15-0e16}*)
       END;
   | 5: (* variable load path *) (*{0e18}*)
-      IF t # 0 THEN Errors.ReportError(60) END; (*{0e18-0e1c}*)
+      IF t # NIL THEN Errors.ReportError(60) END; (*{0e18-0e1c} FIXME *)
       LoadOperand; (* proc18 *) (*{0e1d}*)
   | 0: (* illegal *) (*{0e20}*)
-      Errors.ReportErrorWithText(128, Scanner.tokenBuffer); (*{0e20-0e25}*)
+      Errors.ReportErrorWithText(128, Scanner.tokenBuffer); (*{0e20-0e25} *)
   | 2:
-      Errors.ReportError(22); (*{0e3b-0e3d}*)
+      Errors.ReportError(22); (*{0e3b-0e3d} *)
   END;
-  CheckAndStore(); (* proc22; FIXME: group wrote proc22 CheckFollowSet *)
+  CheckAndStore(); (* proc22 FIXME arity *) (*{0e3f-0e40}*)
 END EmitCompare;
 
-(* proc49 @0e45 — ~EmitRangeCheck: AND-chains, mul/div/mod const-fold *)
 PROCEDURE EmitRangeCheck;
 VAR buf: Desc;
     op: CARDINAL;
@@ -1108,7 +1110,7 @@ VAR buf: Desc;
     isZero: BOOLEAN;
 BEGIN
   EmitCompare; (* nested proc50 *) (*{0e4a}*)
-  IF ~(Scanner.curSymbol IN BITSET{51..57}) THEN (*{0e4c-0e54}*)
+  IF ~(Scanner.curSymbol IN BITSET{51..57}) THEN (*{0e4c-0e54} FIXME set *)
     RETURN;
   END;
   EmitOp(); (* proc6 *) (*{0e57}*)
@@ -1116,77 +1118,77 @@ BEGIN
   IF op = 64 THEN (* AND *) (*{0e5b-0e5f}*)
     ConstToCard(Compiler.BooleanType, 64); (* proc7 *) (*{0e61-0e63}*)
     Scanner.GetSym; (*{0e65}*)
-    IF curDesc.word1 = 0 THEN (*{0e67-0e6a}*)
+    IF curDesc.raw[1] = 0 THEN (*{0e67-0e6a}*)
       CodeGen.DiscardPending; (*{0e6c}*)
-      savePend := CodeGen.pendMode; saveMode := curDesc.word2; (*{0e6e-0e84}*)
-      CodeGen.pendMode := savePend AND saveMode; (*{0e85-0e8c} FIXME: BITSET pun *)
+      savePend := CodeGen.pendMode; saveMode := curDesc.raw[2]; (*{0e6e-0e84} *)
+      CodeGen.pendMode := savePend AND saveMode; (*{0e85-0e8c} FIXME pun *)
       EmitCompare; (*{0e8a}*)
       ConstToCard(Compiler.BooleanType, 64); (*{0e8c-0e90}*)
       CodeGen.pendMode := savePend; (*{0e92-0e93}*)
       IF saveMode = 0 THEN (*{0e94-0e96}*)
-        curDesc.word1 := 0; curDesc.word2 := 0; (*{0e98-0e9d}*)
+        curDesc.raw[1] := 0; curDesc.raw[2] := 0; (*{0e98-0e9d}*)
         EmitDescriptor2(curDesc); (* proc2 *) (*{0e9e-0ea4}*)
       END;
     ELSE
       CodeGen.EmitStandardOp(11); (*{0e92}*)
-      CodeGen.OpenFixup(saveMode, TRUE); (* proc12 *) (*{0e95-0e99}*)
+      CodeGen.OpenFixup(saveMode, TRUE); (* proc12 *) (*{0e95-0e99} FIXME: CARDINAL VAR pun *)
       EmitCompare; (*{0e9a}*)
       ConstToCard(Compiler.BooleanType, 64); (*{0e9c-0ea0}*)
-      CodeGen.InsertFixup(saveMode, TRUE); (* proc14 *) (*{0ea1-0ea3}*)
+      CodeGen.InsertFixup(saveMode, TRUE); (* proc14 *) (*{0ea1-0ea3} FIXME *)
       Errors.ReportError(91); (*{0ea5-0ea7}*)
-      curDesc.word1 := 2; (*{0ea8-0eaa}*)
+      curDesc.raw[1] := 2; (*{0ea8-0eaa}*)
     END;
     RETURN;
   END;
   buf := curDesc; (*{0eae-0eb1}*)
-  IF op = 60 THEN rkind := 404; (* IN *) (*{0eb2-0eb6}*)
+  IF op = 60 THEN rkind := 404; (* IN *) (*{0eb2-0eb6} FIXME magic *)
   ELSIF op = 63 THEN rkind := 272;
-  ELSE rkind := 132; END; (*{0eca-0ecc}*)
+  ELSE rkind := 132; END; (*{0eca-0ecc} *)
   MatchOpClass(rkind, op); (* proc9 *) (*{0ecd-0ecf}*)
   Scanner.GetSym; (*{0ed0-0ed1}*)
   EmitCompare; (*{0ed2}*)
   EmitOp(); (* proc6 *) (*{0ed4}*)
   MatchOpClass(rkind, op); (* proc9 *) (*{0ed5-0ed7}*)
-  FoldConstOp(buf); (*FIXME: rkind result TBD*) (* proc35; FIXME: folded kind TBD *)
-  rkind := TypeKindOf(rkind); (* proc27; FIXME *)
+  FoldConstOp(buf); (* proc35 FIXME: kind result TBD *) (*{0ed8-0ed9}*)
+  rkind := TypeKindOf(); (* proc27 FIXME: 0-arg vs use *) (*{0edb}*)
   IF op = 63 THEN op := 61 END; (*{0ede-0ee2}*)
-  IF (curDesc.word1 = 0) AND (buf.mode = 0) THEN (*{0ee7-0eef} both const *)
+  IF (curDesc.raw[1] = 0) AND (buf.raw[1] = 0) THEN (*{0ee7-0eef} both const *)
     CodeGen.DiscardPending; (*{0ef2}*)
     CodeGen.DiscardPending; (*{0ef4}*)
     IF op = 60 THEN (* '*' *) (*{0ef6-0efa}*)
-      CASE buf.typ^.word4 OF (*{0efc-0efd}*)
-        0: curDesc.word2 := buf.value * curDesc.word2; (* umul_checked *) (*{0eff-0f06}*)
-      | 1: curDesc.word2 := buf.value * curDesc.word2; (* imul *) (*{0f07-0f0e}*)
-      | 2: curDesc.word2 := buf.value * curDesc.word2; (* dmul *) (*{0f0f-0f19} FIXME: double pun *)
-      | 3: curDesc.word2 := buf.value * curDesc.word2; (* real_mul *) (*{0f1a-0f23}*)
-      | 4: curDesc.word2 := buf.value AND curDesc.word2; (* and *) (*{0f25-0f2c} FIXME: CARDINAL AND pun *)
+      CASE buf.raw[0] OF (* FIXME: ADDRESS case-selector pun; kinds below TBD *)
+        0: curDesc.raw[2] := buf.raw[2] * curDesc.raw[2]; (* umul_checked *) (*{0eff-0f06} FIXME arith pun *)
+      | 1: curDesc.raw[2] := buf.raw[2] * curDesc.raw[2]; (* imul *) (*{0f07-0f0e} FIXME *)
+      | 2: curDesc.raw[2] := buf.raw[2] * curDesc.raw[2]; (* dmul FIXME *) (*{0f0f-0f19} *)
+      | 3: curDesc.raw[2] := buf.raw[2] * curDesc.raw[2]; (* real_mul FIXME *) (*{0f1a-0f23} *)
+      | 4: curDesc.raw[2] := buf.raw[2] AND curDesc.raw[2]; (* and FIXME *) (*{0f25-0f2c} *)
       END;
-      FoldLongRelation(buf); (* FIXME: Doubles.qmul + proc47 *)
+      FoldLongRelation(buf); (* FIXME: DOUBLES.qmul + proc47 *)
     ELSIF op = 61 THEN (* '/' zero check + div family *) (*{0f4e-0f52}*)
       IF rkind <= 1 THEN (*{0f54-0f57}*)
-        IF curDesc.word2 = 0 THEN isZero := curDesc.word2 = 0 END; (*{0f59-0f5d}*)
+        IF curDesc.raw[2] = 0 THEN isZero := curDesc.raw[2] = 0 END; (*{0f59-0f5d} FIXME *)
       ELSIF rkind <= 3 THEN
-        isZero := curDesc.word2 = 0; (* FIXME: real_compare *)
+        isZero := curDesc.raw[2] = 0; (* FIXME: real_compare *)
       ELSIF rkind = 5 THEN
         isZero := FALSE; (* FIXME: Doubles.qcp LONGREAL compare *)
       END;
       IF isZero THEN Errors.ReportError(76) END; (*{0f89-0f8e} div by zero *)
-      CASE buf.typ^.word4 OF (*{0f90-0f91}*)
-        0: curDesc.word2 := buf.value DIV curDesc.word2; (* udiv *) (*{0f93-0f9a}*)
-      | 1: curDesc.word2 := buf.value DIV curDesc.word2; (* idiv *) (*{0f9b-0fa2}*)
-      | 2: curDesc.word2 := buf.value DIV curDesc.word2; (* ddiv *) (*{0fa3-0fad} FIXME *)
-      | 3: curDesc.word2 := buf.value DIV curDesc.word2; (* real_div *) (*{0fae-0fb8} FIXME *)
-      | 4: curDesc.word2 := BITSET(buf.value) / curDesc.word2; (* xor *) (*{0fb9-0fc0} FIXME *)
+      CASE buf.raw[0] OF (*{0f90-0f91} FIXME pun *)
+        0: curDesc.raw[2] := buf.raw[2] DIV curDesc.raw[2]; (* udiv *) (*{0f93-0f9a} FIXME *)
+      | 1: curDesc.raw[2] := buf.raw[2] DIV curDesc.raw[2]; (* idiv *) (*{0f9b-0fa2} FIXME *)
+      | 2: curDesc.raw[2] := buf.raw[2] DIV curDesc.raw[2]; (* ddiv FIXME *) (*{0fa3-0fad} *)
+      | 3: curDesc.raw[2] := buf.raw[2] DIV curDesc.raw[2]; (* real_div FIXME *) (*{0fae-0fb8} *)
+      | 4: curDesc.raw[2] := BITSET(buf.raw[2]) / curDesc.raw[2]; (* xor FIXME *) (*{0fb9-0fc0} *)
       END;
       FoldLongDiv(buf); (* FIXME: Doubles.qdiv + proc47 *)
     ELSIF rkind = 2 THEN (*{0fe2-0fe5} LONGINT MOD *)
-      curDesc.word2 := buf.value MOD curDesc.word2; (*{0fe7-0fef} FIXME *)
+      curDesc.raw[2] := buf.raw[2] MOD curDesc.raw[2]; (*{0fe7-0fef} FIXME *)
     ELSE
-      curDesc.word2 := buf.value MOD curDesc.word2; (*{0ff3-0ff9} umod *)
+      curDesc.raw[2] := buf.raw[2] MOD curDesc.raw[2]; (*{0ff3-0ff9} umod *)
     END;
     EmitDescriptor2(curDesc); (* proc2 *) (*{0ffa-0ffb}*)
   ELSE
-    curDesc.word1 := 2; (*{0ffe-1000}*)
+    curDesc.raw[1] := 2; (*{0ffe-1000}*)
     IF (3 IN Scanner.scanOptions) AND (op = 60) AND (rkind = 0) THEN (*{1001-100e}*)
       CodeGen.EmitExtendedOp(op - 52, rkind); (* checked *) (*{1011-1015}*)
     ELSE
@@ -1195,30 +1197,30 @@ BEGIN
   END;
 END EmitRangeCheck;
 
-(* proc48 @1025 — ~ParseSimpleExpression *)
 PROCEDURE ParseSimpleExpression;
 VAR buf: Desc;
     op: CARDINAL;
     t: ADDRESS;
+    savePend, saveMode: CARDINAL;
 BEGIN
-  IF Scanner.curSymbol IN BITSET{58..60} THEN (* unary +/- *) (*{102a-1030}*)
+  IF Scanner.curSymbol IN BITSET{58..60} THEN (* unary +/- *) (*{102a-1030} FIXME *)
     IF Scanner.AcceptSymbol(59) THEN (* '-' *) (*{1032-1036}*)
       EmitRangeCheck; (* nested proc49 *) (*{1038}*)
       EmitOp(); (* proc6 *) (*{103a}*)
       MatchOpClass(388, 59); (* proc9 *) (*{103b-1040}*)
-      t := TypeKindOf(t) (*FIXME: type TBD*); (* proc27; FIXME: t uninitialized here, TBD *)
-      IF t = 0 THEN t := Compiler.CardType; ConstToCard(t, 59); END; (*{1044-104c} FIXME: group wrote word6=INTEGER? CARD fallback per text *)
-      IF curDesc.word1 = 0 THEN (* const negation *) (*{104d-1050}*)
+      t := TypeKindOf(); (* proc27 FIXME: 0-arg; t role TBD *) (*{1041-1043}*)
+      IF t = NIL THEN t := Compiler.CardType; ConstToCard(t, 59); END; (*{1044-104c} FIXME *)
+      IF curDesc.raw[1] = 0 THEN (* const negation *) (*{104d-1050}*)
         CodeGen.DiscardPending; (*{1052}*)
-        CASE t^.word4 OF (*{1054-1076}*)
-          2: curDesc.word2 := curDesc.word2; (* long_negate FIXME *)
-        | 3: curDesc.word2 := curDesc.word2; (* FIXME *)
-        | 5: curDesc.word2 := curDesc.word2; (* FIXME: Doubles.qneg *)
-        | 4: curDesc.word2 := curDesc.word2; (* complement+inc FIXME *)
+        CASE Words(t)^[4] OF (*{1054-1076} FIXME pun *)
+          2: curDesc.raw[2] := curDesc.raw[2]; (* long_negate FIXME *)
+        | 3: curDesc.raw[2] := curDesc.raw[2]; (* FIXME *)
+        | 5: curDesc.raw[2] := curDesc.raw[2]; (* FIXME: Doubles.qneg *)
+        | 4: curDesc.raw[2] := curDesc.raw[2]; (* complement+inc FIXME *)
         END;
-        curDesc.word0 := Compiler.CardType; (*{108b-108e} FIXME: group wrote word6 *)
+        curDesc.raw[0] := Compiler.CardType; (*{108b-108e} FIXME *)
       ELSE
-        CodeGen.EmitTypedOp(11, t^.word4); (* unary minus *) (*{1093-1095}*)
+        CodeGen.EmitTypedOp(11, Words(t)^[4]); (* unary minus *) (*{1093-1095} FIXME *)
       END;
     ELSE
       Scanner.GetSym; (*{1099} '+' skip *)
@@ -1229,29 +1231,31 @@ BEGIN
   ELSE
     EmitRangeCheck; (*{10a6}*)
   END;
-  WHILE Scanner.curSymbol IN BITSET{51..57} DO (* +,-,OR *) (*{10a8-10b0}*)
+  WHILE Scanner.curSymbol IN BITSET{51..57} DO (* +,-,OR *) (*{10a8-10b0} FIXME *)
     op := Scanner.curSymbol; (*{10b3-10b5}*)
     EmitOp(); (* proc6 *) (*{10b6}*)
-    IF op = 65 THEN (* OR *) (*{10b7-10bb} FIXME: 65 outside 51..57; loop-exit OR? TBD *)
+    IF op = 65 THEN (* OR *) (*{10b7-10bb} FIXME: 65 outside 51..57 loop? TBD *)
       ConstToCard(Compiler.BooleanType, 65); (* proc7 *) (*{10bd-10c1}*)
       Scanner.GetSym; (*{10c2}*)
-      IF curDesc.word1 = 0 THEN (*{10c4-10c7}*)
+      IF curDesc.raw[1] = 0 THEN (*{10c4-10c7}*)
         CodeGen.DiscardPending; (*{10c9}*)
-        savePend := saveMode; (* FIXME: undeclared in this scope; group24 cross-talk TBD *)
+        savePend := CodeGen.pendMode; saveMode := curDesc.raw[2]; (*{10cb-10d6} *)
+        CodeGen.pendMode := savePend OR (NOT saveMode); (*{10d1-10d6} FIXME pun *)
         EmitRangeCheck; (*{10d8}*)
         ConstToCard(Compiler.BooleanType, 65); (*{10da-10de}*)
+        CodeGen.pendMode := savePend; (*{10df-10e0}*)
         IF saveMode # 0 THEN (*{10e2-10e3}*)
-          curDesc.word1 := 0; curDesc.word2 := 1; (*{10e5-10eb}*)
+          curDesc.raw[1] := 0; curDesc.raw[2] := 1; (*{10e5-10eb}*)
           EmitDescriptor2(curDesc); (* proc2 *) (*{10ec}*)
         END;
       ELSE
         CodeGen.EmitStandardOp(12); (*{10ef-10f0}*)
-        CodeGen.OpenFixup(saveMode, TRUE); (* proc12 *) (*{10f2-10f5} FIXME: undeclared *)
+        CodeGen.OpenFixup(saveMode, TRUE); (* proc12 *) (*{10f2-10f5} FIXME pun *)
         EmitRangeCheck; (*{10f7}*)
         ConstToCard(Compiler.BooleanType, 65); (*{10f9-10fd}*)
-        CodeGen.InsertFixup(saveMode, TRUE); (* proc14 *) (*{10fe-1100}*)
+        CodeGen.InsertFixup(saveMode, TRUE); (* proc14 *) (*{10fe-1100} FIXME *)
         Errors.ReportError(91); (*{1102-1104}*)
-        curDesc.word1 := 2; (*{1105-1107}*)
+        curDesc.raw[1] := 2; (*{1105-1107}*)
       END;
     ELSE
       buf := curDesc; (*{110b-110e}*)
@@ -1260,51 +1264,50 @@ BEGIN
       EmitRangeCheck; (*{1116}*)
       EmitOp(); (* proc6 *) (*{1118}*)
       MatchOpClass(404, op); (* proc9 *) (*{1119-111e}*)
-      FoldConstOp(buf); (*FIXME: t result TBD*) (* proc35; FIXME: folded kind TBD *)
-      t := TypeKindOf(t) (*FIXME: type TBD*); (* proc27; FIXME *)
-      IF (curDesc.word1 = 0) AND (buf.mode = 0) THEN (*{1124-112c}*)
+      FoldConstOp(buf); (* proc35 FIXME: kind result TBD *) (*{111f}*)
+      t := TypeKindOf(); (* proc27 FIXME *) (*{1121}*)
+      IF (curDesc.raw[1] = 0) AND (buf.raw[1] = 0) THEN (*{1124-112c}*)
         CodeGen.DiscardPending; (*{112e}*)
         CodeGen.DiscardPending; (*{1130}*)
         IF op = 58 THEN (* '+' *) (*{1132-1136}*)
-          CASE t^.word4 OF (*{1138-1139}*)
-            0: curDesc.word2 := buf.value + curDesc.word2; (* uadd_checked *) (*{113b-1142}*)
-          | 1: curDesc.word2 := buf.value + curDesc.word2; (* iadd_checked *) (*{1143-114a}*)
-          | 2: curDesc.word2 := buf.value + curDesc.word2; (* dadd FIXME *) (*{114b-1155}*)
-          | 3: curDesc.word2 := buf.value + curDesc.word2; (* real_add FIXME *) (*{1156-1160}*)
-          | 4: curDesc.word2 := buf.value OR curDesc.word2; (* or; FIXME pun *) (*{1161-1168}*)
+          CASE Words(t)^[4] OF (*{1138-1139} FIXME pun *)
+            0: curDesc.raw[2] := buf.raw[2] + curDesc.raw[2]; (* uadd_checked *) (*{113b-1142} FIXME *)
+          | 1: curDesc.raw[2] := buf.raw[2] + curDesc.raw[2]; (* iadd_checked *) (*{1143-114a} FIXME *)
+          | 2: curDesc.raw[2] := buf.raw[2] + curDesc.raw[2]; (* dadd FIXME *) (*{114b-1155} *)
+          | 3: curDesc.raw[2] := buf.raw[2] + curDesc.raw[2]; (* real_add FIXME *) (*{1156-1160} *)
+          | 4: curDesc.raw[2] := buf.raw[2] OR curDesc.raw[2]; (* or; FIXME pun *) (*{1161-1168} *)
           END;
           FoldLongAdd(buf); (* FIXME: Doubles.qadd + proc47 *)
         ELSIF t = NIL THEN (* '-' family *) (*{118a-118b}*)
-          CASE buf.typ^.word4 OF
-            2: curDesc.word2 := buf.value - curDesc.word2; (* dsub FIXME *)
-          | 3: curDesc.word2 := buf.value - curDesc.word2; (* real_sub FIXME *)
-          | 4: curDesc.word2 := buf.value - curDesc.word2; (* diff FIXME *)
-          | 5: curDesc.word2 := buf.value - curDesc.word2; (* FIXME: Doubles.qsub *)
+          CASE buf.raw[0] OF (* FIXME pun *)
+            2: curDesc.raw[2] := buf.raw[2] - curDesc.raw[2]; (* dsub FIXME *)
+          | 3: curDesc.raw[2] := buf.raw[2] - curDesc.raw[2]; (* real_sub FIXME *)
+          | 4: curDesc.raw[2] := buf.raw[2] - curDesc.raw[2]; (* diff FIXME *)
+          | 5: curDesc.raw[2] := buf.raw[2] - curDesc.raw[2]; (* FIXME: Doubles.qsub *)
           END;
-        ELSIF (t = 0) OR ((buf.value >= 0) AND (curDesc.word2 > buf.value)) THEN
-          curDesc.word0 := Compiler.CardType; (* CARD result *) (*{11ca-11de}*)
+        ELSIF (t = NIL) OR ((buf.raw[2] >= 0) AND (curDesc.raw[2] > buf.raw[2])) THEN
+          curDesc.raw[0] := Compiler.CardType; (* CARD result *) (*{11ca-11de} FIXME: group wrote word6 *)
         END;
-        IF curDesc.word0 = Compiler.CardType THEN (*{11df-11e4}*)
-          IF buf.typ = Compiler.CardType THEN
-            curDesc.word2 := buf.value - curDesc.word2; (* isub_checked *) (*{11e6-11ec}*)
+        IF curDesc.raw[0] = Compiler.CardType THEN (*{11df-11e4}*)
+          IF buf.raw[0] = Compiler.CardType THEN
+            curDesc.raw[2] := buf.raw[2] - curDesc.raw[2]; (* isub_checked *) (*{11e6-11ec} FIXME *)
           ELSE
-            curDesc.word2 := buf.value - curDesc.word2; (* usub_checked *) (*{11ef-11f5}*)
+            curDesc.raw[2] := buf.raw[2] - curDesc.raw[2]; (* usub_checked *) (*{11ef-11f5} FIXME *)
           END;
         END;
         EmitDescriptor2(curDesc); (* proc2 *) (*{11f6}*)
       ELSE
-        curDesc.word1 := 2; (*{11fa-11fc}*)
-        IF (3 IN Scanner.scanOptions) AND (t^.word4 <= 1) THEN
-          CodeGen.EmitExtendedOp(op - 52, t^.word4); (* checked *) (*{1208-120c}*)
+        curDesc.raw[1] := 2; (*{11fa-11fc}*)
+        IF (3 IN Scanner.scanOptions) AND (Words(t)^[4] <= 1) THEN
+          CodeGen.EmitExtendedOp(op - 52, Words(t)^[4]); (* checked *) (*{1208-120c} FIXME *)
         ELSE
-          CodeGen.EmitTypedOp(op - 52, t^.word4); (* plain *) (*{1210-1214}*)
+          CodeGen.EmitTypedOp(op - 52, Words(t)^[4]); (* plain *) (*{1210-1214} FIXME *)
         END;
       END;
     END;
   END;
 END ParseSimpleExpression;
 
-(* EXPRES @1221 — ~ParseExpression *)
 PROCEDURE ParseExpression;
 VAR buf: Desc;
     op: CARDINAL;
@@ -1321,174 +1324,167 @@ BEGIN
   EmitOp(); (* proc6 *) (*{1239}*)
   buf := curDesc; (*{123a-123d}*)
   Scanner.AcceptSymbol(51); (* '=' consume *) (*{123d-1241}*)
-  IF Scanner.curSymbol = 0 THEN (*{1241} literal rhs fast path? FIXME *)
+  IF Scanner.curSymbol = 0 THEN (*{1241} FIXME: literal-rhs fast path? *)
     ParseSimpleExpression; (*{1243}*)
     MatchOpClass(16, 51); (* proc9 '=' *) (*{1245-124a}*)
-    FoldConstOp(buf); (* proc35 both sides *) (*{124c-1257}*)
-    IF (curDesc.word1 = 0) AND (buf.mode = 0) THEN (*{125a}*)
+    FoldConstOp(buf); (* proc35 both sides *) (*{124c-1257} FIXME kind TBD *)
+    IF (curDesc.raw[1] = 0) AND (buf.raw[1] = 0) THEN (*{125a}*)
       CodeGen.DiscardPending; (*{125c}*)
       CodeGen.DiscardPending; (*{125e}*)
-      curDesc.word2 := BITSET(buf.value) * curDesc.word2; (* IN-fold FIXME pun *) (*{1260-1266}*)
+      curDesc.raw[2] := buf.raw[2]; (* IN-fold FIXME pun *) (*{1260-1266}*)
       EmitDescriptor2(curDesc); (* proc2 *) (*{1267-1268}*)
     ELSE
-      curDesc.word1 := 2; (*{126b-126d}*)
+      curDesc.raw[1] := 2; (*{126b-126d}*)
       CodeGen.EmitStandardOp(4); (* '=' compare *) (*{126e-1270}*)
     END;
-  ELSIF IsOrdinalType(curDesc.word0) THEN (* proc26; FIXME: NYC *)
-    ExpectBoolOrSet(); (* proc25; FIXME: NYC, group passed (1) *)
+  ELSIF IsOrdinalType(curDesc.raw[0]) THEN (* proc26 FIXME NYC *)
+    ExpectBoolOrSet(); (* proc25 FIXME NYC *)
     Scanner.GetSym; (*{127d}*)
     ParseSimpleExpression; (*{127f}*)
-    CheckAssignable(buf); (* proc36 *) (*{1281-1283} FIXME: CheckAssignable() takes none *)
-    IF ~ IsOrdinalType(curDesc.word0) THEN (*{1284-1289}*)
+    CheckAssignable(buf); (* proc36 FIXME: 0-arg vs Desc arg *)
+    IF ~ IsOrdinalType(curDesc.raw[0]) THEN (*{1284-1289}*)
       FoldConstOp(buf); (* proc35 *) (*{128a-128c}*)
     END;
-    EmitSetMember(buf); (*FIXME: NYC*) (* proc11 pair; FIXME: NYC *)
+    buf := EmitSetMember(buf); (* proc11 pair FIXME NYC *)
     CodeGen.EmitStandardOp(7); (* IN test *) (*{1292-1294}*)
     CodeGen.EmitSystemCall(23); (*{1296-1298} bounds trap *)
     CodeGen.EmitTypedOp(op - 52, 0); (*{1299-1301}*)
-    curDesc.word1 := 2; (*{1302-1304}*)
+    curDesc.raw[1] := 2; (*{1302-1304}*)
   ELSE
-    IF op <= 53 THEN cls := 501; (* =,#,IN class *) (*{12a5-12ac}*)
-    ELSIF op <= 55 THEN cls := 389; (* <,<= class *) (*{12b1-12ba}*)
-    ELSE cls := 405; END; (* >,>= class *) (*{12bd-12c1}*)
+    IF op <= 53 THEN cls := 501; (* =,#,IN class *) (*{12a5-12ac} FIXME magic *)
+    ELSIF op <= 55 THEN cls := 389; (* <,<= class *) (*{12b1-12ba} FIXME *)
+    ELSE cls := 405; END; (* >,>= class *) (*{12bd-12c1} *)
     MatchOpClass(cls, op); (* proc9 *) (*{12c1-12c4}*)
     Scanner.GetSym; (*{12c5}*)
     ParseSimpleExpression; (*{12c6}*)
     EmitOp(); (* proc6 *) (*{12c8}*)
     MatchOpClass(cls, op); (* proc9 *) (*{12c9-12cb}*)
     FoldConstOp(buf); (* proc35 *) (*{12cc-12cd}*)
-    rkind := BaseTypeOf(buf); (* proc27; FIXME: BaseTypeOf takes 2 *)
-    IF (curDesc.word1 = 0) AND (buf.mode = 0) THEN (*{12d2-12da}*)
+    rkind := TypeKindOf(); (* proc27 FIXME *) (*{12cf-12d1}*)
+    IF (curDesc.raw[1] = 0) AND (buf.raw[1] = 0) THEN (*{12d2-12da}*)
       CodeGen.DiscardPending; (*{12dc}*)
       CodeGen.DiscardPending; (*{12de}*)
       cres := 0; (*{12e0-12e2}*)
-      CASE buf.typ^.word4 OF (*{12e2-12e3}*)
+      CASE Words(buf.raw[0])^[4] OF (*{12e2-12e3} FIXME pun *)
         0: (* CARDINAL unsigned *) (*{12e5}*)
-           IF buf.value > curDesc.word2 THEN cres := 2;
-           ELSIF buf.value < curDesc.word2 THEN cres := 1; END; (*{12e5-12f8}*)
+           IF buf.raw[2] > curDesc.raw[2] THEN cres := 2;
+           ELSIF buf.raw[2] < curDesc.raw[2] THEN cres := 1; END; (*{12e5-12f8} *)
       | 1: (* INTEGER signed *) (*{12fa}*)
-           IF buf.value > curDesc.word2 THEN cres := 2;
-           ELSIF buf.value < curDesc.word2 THEN cres := 1; END; (*{12fa-130d}*)
+           IF buf.raw[2] > curDesc.raw[2] THEN cres := 2;
+           ELSIF buf.raw[2] < curDesc.raw[2] THEN cres := 1; END; (*{12fa-130d} *)
       | 2: (* LONGINT *) (*{130f}*)
-           IF buf.value > curDesc.word2 THEN cres := 2;
-           ELSIF buf.value < curDesc.word2 THEN cres := 1; END; (* FIXME: dcompare *)
+           IF buf.raw[2] > curDesc.raw[2] THEN cres := 2;
+           ELSIF buf.raw[2] < curDesc.raw[2] THEN cres := 1; END; (* FIXME: dcompare *)
       | 3: (* REAL *) (*{132a}*)
-           IF buf.value > curDesc.word2 THEN cres := 2;
-           ELSIF buf.value < curDesc.word2 THEN cres := 1; END; (* FIXME: real_compare *)
+           IF buf.raw[2] > curDesc.raw[2] THEN cres := 2;
+           ELSIF buf.raw[2] < curDesc.raw[2] THEN cres := 1; END; (* FIXME: real_compare *)
       | 4: (* BITSET/WORD set equality limbs *) (*{1345}*)
-           IF buf.value # curDesc.word2 THEN
-             IF BITSET(buf.value) * BITSET(NOT curDesc.word2) = {} THEN cres := 2;
-             ELSIF BITSET(curDesc.word2) * BITSET(NOT buf.value) = {} THEN cres := 1; END;
+           IF buf.raw[2] # curDesc.raw[2] THEN
+             IF BITSET(buf.raw[2]) * BITSET(NOT curDesc.raw[2]) = {} THEN cres := 2;
+             ELSIF BITSET(curDesc.raw[2]) * BITSET(NOT buf.raw[2]) = {} THEN cres := 1; END;
            END; (*{1349-1366} FIXME: CARDINAL BITSET/NOT puns *)
       END;
-      CASE buf.typ^.word0 OF (* LONGREAL tail *) (*{1368} FIXME *)
+      CASE buf.raw[0] OF (* LONGREAL tail *) (*{1368} FIXME: ADDRESS case pun *)
         NIL: ;
       ELSE
         cres := cres; (* FIXME: Doubles.qcp LONGREAL compare *)
       END;
       CASE op OF (* map cres -> boolean *) (*{139d-13bc}*)
-        51: curDesc.word2 := ORD(cres = 0); (* '=' *) (*{13a0}*)
-      | 52: curDesc.word2 := ORD(cres # 0); (* '#' *) (*{13a5}*)
-      | 53: curDesc.word2 := ORD(cres = 1); (* '<' *) (*{13aa}*)
-      | 54: curDesc.word2 := ORD(cres = 2); (* '<=' *) (*{13b0} FIXME: inverted limbs? *)
-      | 55: curDesc.word2 := ORD(cres # 2); (* '>' *) (*{13b6}*)
-      ELSE  curDesc.word2 := ORD(cres # 1); (* '>=' / IN *) (*{13cd-13d1}*)
+        51: curDesc.raw[2] := ORD(cres = 0); (* '=' *) (*{13a0}*)
+      | 52: curDesc.raw[2] := ORD(cres # 0); (* '#' *) (*{13a5}*)
+      | 53: curDesc.raw[2] := ORD(cres = 1); (* '<' *) (*{13aa}*)
+      | 54: curDesc.raw[2] := ORD(cres = 2); (* '<=' *) (*{13b0} FIXME limbs *)
+      | 55: curDesc.raw[2] := ORD(cres # 2); (* '>' *) (*{13b6}*)
+      ELSE  curDesc.raw[2] := ORD(cres # 1); (* '>=' / IN *) (*{13cd-13d1}*)
       END;
       EmitDescriptor2(curDesc); (* proc2 *) (*{13d2-13d3}*)
     ELSE
-      curDesc.word1 := 2; (*{13d6-13d8}*)
-      CodeGen.EmitTypedOp(op - 52, rkind); (* general relop; FIXME: rkind pun *) (*{13d9-13dd}*)
+      curDesc.raw[1] := 2; (*{13d6-13d8}*)
+      CodeGen.EmitTypedOp(op - 52, rkind); (* general relop; FIXME pun *) (*{13d9-13dd}*)
     END;
   END;
-  curDesc.word0 := Compiler.BooleanType; (* BOOLEAN result *) (*{13df-13e2} FIXME: group wrote word14 *)
+  curDesc.raw[0] := Compiler.BooleanType; (* BOOLEAN result *) (*{13df-13e2} *)
 END ParseExpression;
 
-(* proc13 @13f3 — ~GetConstVal *)
 PROCEDURE GetConstVal;
 BEGIN
   BoolCondHelper; (* proc12 *) (*{13f5}*)
-  IF curDesc.word1 # 0 THEN Errors.ReportError(25) END; (*{13f6-13fb}*)
+  IF curDesc.raw[1] # 0 THEN Errors.ReportError(25) END; (*{13f6-13fb}*)
   CodeGen.DiscardPending; (*{13fc-13fe}*)
 END GetConstVal;
 
-(* proc14 @1400 — ~GetTypeDesc *)
 PROCEDURE GetTypeDesc(src: ADDRESS; dest: ADDRESS; mode: CARDINAL);
 BEGIN
   GetConstVal; (* proc13 *) (*{1402}*)
   EmitOp(); (* proc6 *) (*{1403}*)
-  ConstToCard(src, 0); (* proc7 *) (*{1404-1406}*)
-  PopExprDesc(src); (* proc5 *) (*{1407-1408} FIXME: PopExprDesc takes DescPtr *)
-  IF (curDesc.word0 # Compiler.CardType) OR (curDesc.word2 < 0) THEN
-    Errors.ReportError(80); (*{1409-1416} FIXME: group wrote word7=CARDINAL? kept *)
+  ConstToCard(src, 0); (* proc7 *) (*{1404-1406} FIXME: (c,errPos) vs call shape *)
+  PopExprDesc(src); (* proc5 FIXME: DescPtr vs ADDRESS *)
+  IF (curDesc.raw[0] # Compiler.CardType) OR (curDesc.raw[2] < 0) THEN
+    Errors.ReportError(80); (*{1409-1416} *)
   END;
-  dest^.word0 := curDesc.word2; (*{1417-141e} FIXME: ADDRESS deref TBD *)
+  Words(dest)^[0] := curDesc.raw[2]; (*{1417-141e} FIXME pun *)
   IF Scanner.AcceptSymbol(4) THEN (* ',' second bound *) (*{141f-1422}*)
     GetConstVal; (*{1424}*)
     EmitOp(); (*{1426}*)
-    ConstToCard(src, 0); (*{1427-0429}*)
-    PopExprDesc(src); (*{042a}*)
-    IF (curDesc.word0 # Compiler.CardType) OR (curDesc.word2 < 0) THEN
-      Errors.ReportError(80); (*{142b-1438}*)
+    ConstToCard(src, 0); (*{1427-0429} *)
+    PopExprDesc(src); (*{042a} *)
+    IF (curDesc.raw[0] # Compiler.CardType) OR (curDesc.raw[2] < 0) THEN
+      Errors.ReportError(80); (*{142b-1438} *)
     END;
-    IF curDesc.word2 < dest^.word0 THEN Errors.ReportError(46) END; (*{143a-1440} FIXME *)
-    dest^.word0 := curDesc.word2; (*{1441-1444} upper bound *)
+    IF curDesc.raw[2] < Words(dest)^[0] THEN Errors.ReportError(46) END; (*{143a-1440} FIXME *)
+    Words(dest)^[0] := curDesc.raw[2]; (*{1441-1444} upper bound *)
   END;
 END GetTypeDesc;
 
-(* ASSIGN check entry @144c *)
 PROCEDURE CheckAssignmentCompat(dst: ADDRESS);
 BEGIN
-  IF ~ BaseTypeOf(dst, curDesc.word0) THEN (* proc34; FIXME: BaseTypeOf takes 2 *)
-    Errors.ReportIncompatibleTypes(dst, curDesc.word0, " assignment"); (*{1456-1469} FIXME: T1 pun *)
+  IF ~ BaseTypeOf(dst, curDesc.raw[0]) THEN (* proc34 FIXME: 2-param vs use *)
+    Errors.ReportIncompatibleTypes(dst, curDesc.raw[0], " assignment"); (*{1456-1469} FIXME T1 pun *)
   END;
 END CheckAssignmentCompat;
 
-(* ASSIGN main entry @1471 *)
 PROCEDURE ParseAssignment;
 VAR saved: Desc;
 BEGIN
   assignActive := 1; (*{1473-1474} global8 *)
-  IF curDesc.word4 > 9 THEN (*{1475-1480} set-ctor rhs? *)
+  IF curDesc.raw[4] > 9 THEN (*{1475-1480} set-ctor rhs? *)
     EmitDescriptor2(curDesc); (* FIXME: proc2 via proc10? *)
-  ELSIF curDesc.word4 = 4 THEN (*{1480-1484} string/const rhs? *)
+  ELSIF curDesc.raw[4] = 4 THEN (*{1480-1484} string/const rhs? *)
     EmitDescriptor2(curDesc); (* FIXME: proc10 *)
   END;
-  curDesc.word4 := 2; curDesc.word3 := 0; (*{1488-1490}*)
+  curDesc.raw[4] := 2; curDesc.raw[3] := 0; (*{1488-1490}*)
   saved := curDesc; (*{148e-1491}*)
-  IF (Scanner.identKind = 5) AND (curDesc.word0^.word4 = 9) THEN (* func result? *) (*{1492-149d}*)
-    ParseDesignatorBase(saved.typ, saved.value, saved.low, saved.high); (* proc21; FIXME arity *)
-    CheckForwardRef(); (* proc29; FIXME: NYC *)
-    PopExprDesc(saved); (* proc3; FIXME *)
+  IF (Scanner.identKind = 5) AND (Words(curDesc.raw[0])^[4] = 9) THEN (* func result? *) (*{1492-149d} FIXME *)
+    ParseDesignatorBase(saved.raw[0], saved.raw[2], saved.raw[5], saved.raw[6]); (* proc21; FIXME: 4-formal roles TBD *)
+    CheckForwardRef(); (* proc29 FIXME NYC *)
+    PopExprDesc(saved); (* proc3 FIXME: Desc value vs DescPtr *)
     Scanner.GetSym; (*{14b1}*)
   ELSE
     BoolCondHelper; (* proc12 *) (*{14b7}*)
-    CheckAssignable2(saved.typ); (* proc26; FIXME: NYC *)
-    IF ~ CheckAssignable2(saved.typ) THEN (*{14bc}*)
-      CheckAssignable2(saved.typ); (* proc52 nested; FIXME: NYC *)
+    CheckAssignable2(saved.raw[0]); (* proc26 FIXME NYC *)
+    IF ~ CheckAssignable2(saved.raw[0]) THEN (*{14bc}*)
+      CheckAssignable2(saved.raw[0]); (* proc52 nested FIXME NYC *)
     END;
-    IF (curDesc.word0 # saved.typ) AND (curDesc.word1 # 0) THEN (*{14cb-14d5}*)
-      Errors.DerefAliasType(0); (*FIXME: arg*) (* proc25; FIXME: NYC *)
+    IF (curDesc.raw[0] # saved.raw[0]) AND (curDesc.raw[1] # 0) THEN (*{14cb-14d5}*)
+      Errors.DerefAliasType(0); (* proc25 FIXME NYC: arg TBD *)
     END;
-    IF (curDesc.word2 # 0) AND (saved.value # 0) THEN (*{14da-14e4}*)
-      IF saved.value - saved.low = curDesc.word2 - curDesc.word5 THEN (*{14e6-14f8}*)
-        PopExprDesc(saved); (* proc3; FIXME *)
+    IF (curDesc.raw[2] # 0) AND (saved.raw[2] # 0) THEN (*{14da-14e4}*)
+      IF saved.raw[2] - saved.raw[5] = curDesc.raw[2] - curDesc.raw[5] THEN (*{14e6-14f8}*)
+        PopExprDesc(saved); (* proc3 FIXME *)
       ELSE
-        EmitSetOrArrayAssign(saved); (* proc11 pair; FIXME: NYC *)
+        EmitSetOrArrayAssign(saved); (* proc11 pair FIXME NYC *)
         CodeGen.EmitStandardOp(18); (*{1503-1505}*)
       END;
     ELSE
-      CheckAssignable2(saved.typ); (*{1509-150b}*)
-      PopExprDesc(saved); (* proc5 *) (*{150d-150f} FIXME *)
-      PopExprDesc(saved); (* proc3 *) (*{1510-1511} FIXME *)
+      CheckAssignable2(saved.raw[0]); (*{1509-150b}*)
+      PopExprDesc(saved); (* proc5 *) (*{1510-1511} FIXME *)
+      PopExprDesc(saved); (* proc3 *) (*{1511} FIXME *)
     END;
   END;
   assignActive := 0; (*{1512-1513}*)
 END ParseAssignment;
 
-(* proc0 @1516 (module init) *)
-(* global9 -> global5 copy; global8 := 0 *)
-BEGIN
+BEGIN (* proc0 @1516 module init: global9 -> global5 copy; global8 := 0 *)
   exprPool := SymTab.stringPoolPtr; (* FIXME: which string pool? TBD *)
   assignActive := 0;
-END;
 END Express.