Browse Source

feat(express): verify proc51 exact (set collector, T1 param)

Eric Streit 2 weeks ago
parent
commit
905fca6088
2 changed files with 61 additions and 0 deletions
  1. 4 0
      SESSION.md
  2. 57 0
      src/compiler/EXPRESS.MOD

+ 4 - 0
SESSION.md

@@ -332,3 +332,7 @@ Next: GENZ80 media hunt; stage-2 pty-driven MCD diff per module.
   syntax-banned even parenthesized; heapLR staging global appended at word10
   (no shifts). LONGREAL params: caller pushes quad, callee leave-132
   (drop-4+restore); ll=absolute frame-quad, ss=indirect (spec verified).
+- Verified now 36: + proc51 Proc51 (130/130). IF NOT X emits not+jpfalse
+  (not folded); T1 param for link2; BITSET accumulators with CARDINAL()
+  wraps; value-record buf (no mystery); proper-proc leave unaffected by
+  nesting (leave 1 top-level too).

+ 57 - 0
src/compiler/EXPRESS.MOD

@@ -318,6 +318,63 @@ BEGIN
   IF CARDINAL(p^.w2) <> 0 THEN count := CARDINAL(p^.w2^.word3) END;
   CodeGen.EmitExtCall3(19, Proc30(p^.w6), (count + 1) DIV 2 * 2);
 END Proc31;
+(* proc51 @0ecc — set-constructor collector (NESTED in proc50: move in
+   nesting pass). buf is a Head VALUE local (auto reserve-10; addresses are
+   addresses, so no-^ reads match HeadPtr shapes exactly). *)
+PROCEDURE Proc51(p1: SymTab.T1);
+VAR count: BITSET; (* word-2 *) latch: BOOLEAN; (* word-3 *)
+    flag: BOOLEAN; (* word-4 *) buf: Head; (* word-5, 10 bytes *)
+    lo, hi: CARDINAL; (* word-6, word-7 *)
+BEGIN
+  count := BITSET{}; latch := FALSE;
+  IF NOT Scanner.AcceptSy(7) THEN (* entry negated: body runs when no brace *)
+    REPEAT
+      BoolCondHelper;
+      ConstToCard(RecordPtr(p1^.link2), 0);
+      PopExprDesc(RecordPtr(p1^.link2));
+      IF Scanner.AcceptSy(4) THEN
+        buf := curDesc^;
+        BoolCondHelper;
+        ConstToCard(RecordPtr(p1^.link2), 0);
+        PopExprDesc(RecordPtr(p1^.link2));
+        flag := (curDesc^.mode <> 0) OR (buf.mode <> 0);
+        IF flag THEN CodeGen.EmitStandardOp(26);
+        ELSE
+          CodeGen.DiscardPending; CodeGen.DiscardPending;
+          lo := CARDINAL(buf.value); hi := CARDINAL(curDesc^.value);
+          WHILE lo <= hi DO
+            count := count + BITSET{lo};
+            INC(lo);
+          END;
+        END;
+      ELSE
+        flag := curDesc^.mode <> 0;
+        IF flag THEN CodeGen.EmitStandardOp(5);
+        ELSE
+          CodeGen.DiscardPending;
+          count := count + BITSET{CARDINAL(curDesc^.value)};
+        END;
+      END;
+      IF flag THEN
+        IF latch THEN CodeGen.EmitTypedOp(6, 4) ELSE latch := TRUE END;
+      END;
+      Scanner.TestSet(BITSET{1,7});
+    UNTIL NOT Scanner.AcceptSy(1);
+    Scanner.GetSym;
+  END;
+  IF latch THEN
+    IF count <> BITSET{} THEN
+      CodeGen.QueueConst(CARDINAL(count));
+      CodeGen.EmitTypedOp(6, 4);
+    END;
+    curDesc^.mode := 2;
+  ELSE
+    CodeGen.QueueConst(CARDINAL(count));
+    curDesc^.mode := 0;
+    curDesc^.value := ADDRESS(CARDINAL(count));
+  END;
+  curDesc^.typ := NodePtr(RecordPtr(p1));
+END Proc51;
 (* proc28 @009e — ~EmitAddress. *)
 PROCEDURE EmitAddress(d: HeadPtr);
 VAR k: CARDINAL; (* local-2 *)