Kaynağa Gözat

feat(express): verify proc43 exact (nested variants, LPtr heap temp)

Eric Streit 2 hafta önce
ebeveyn
işleme
7478569f72
2 değiştirilmiş dosya ile 56 ekleme ve 21 silme
  1. 5 0
      SESSION.md
  2. 51 21
      src/compiler/EXPRESS.MOD

+ 5 - 0
SESSION.md

@@ -323,3 +323,8 @@ Next: GENZ80 media hunt; stage-2 pty-driven MCD diff per module.
   the slot-reuse puzzle (w2/w5/w6: WalkPtr); free pointer transfers satisfy
   ConstToCard/typ (universal solvent); pre-test IF + REPEAT..UNTIL NOT;
   inner WHILE. Stale ExpandStdProc44 refs (2) await caller audits.
+- Verified now 35: + proc43 Proc43 (69/69 nested). Nested untagged variants
+  probed legal (BufRec 3 views); offset-0 field read explicit word0 (T8),
+  VAR-address elided (T7); tmp.a: LPtr heap LONGREAL temp; CARDINAL truthiness
+  banned in IF (unlike orjp) -> BOOLEAN param; -2147483647L-1L folds to MINLONG
+  imm (no delta). ResetFrame wipes tail junk (balance panic unfounded).

+ 51 - 21
src/compiler/EXPRESS.MOD

@@ -59,6 +59,30 @@ FROM SYSTEM IMPORT ADR, MOVE; (* ADDRESS/WORD/RecordPtr come via DEF imports (le
        typ: RecordPtr;
      END;
      (* N31Ptr/N31 live in EXPRESS.DEF. *)
+     LPtr = POINTER TO LRec; (* heap LONGREAL/LONGINT overlay (proc43 tmp) *)
+     LRec = RECORD
+       CASE : BOOLEAN OF
+       | TRUE: lr: LONGREAL;
+       | FALSE: li: LONGINT;
+       END;
+     END;
+     BufRecPtr = POINTER TO BufRec; (* (unused: bufs are locals) *)
+     BufRec = RECORD (* 8-byte const buffer: word + longreal + long-at-2 *)
+       CASE : BOOLEAN OF
+       | TRUE: w: ARRAY [0..3] OF WORD;
+       | FALSE: CASE : BOOLEAN OF
+                | TRUE: lr: LONGREAL;
+                | FALSE: p0, p1: WORD; li: LONGINT;
+                END;
+       END;
+     END;
+     TmpRec = RECORD (* 4-byte heap-temp carrier: ADDRESS arm for Allocate/
+       conversion addressing, LONGINT arm for queuing the address value *)
+       CASE : BOOLEAN OF
+       | TRUE: a: LPtr; b: CARDINAL;
+       | FALSE: lh: LONGINT;
+       END;
+     END;
      WalkPtr = POINTER TO Walk; (* self-closed walk view: every link field
        reassigns the cursor slot; w2 unwraps to RecordPtr via free transfer
        for ConstToCard; w7 exists (unlike 7-word records) *)
@@ -82,7 +106,7 @@ VAR
 PROCEDURE ParseDesignatorTail; FORWARD;
 PROCEDURE ParseTypeCast(kind: CARDINAL); FORWARD;
 PROCEDURE ParseFuncCall(idx: CARDINAL): ADDRESS; FORWARD;
-PROCEDURE ExpandStdProc43(code: CARDINAL); FORWARD; (* FIXME: 0-arg call site *)
+PROCEDURE Proc43(code: BOOLEAN); FORWARD;
 PROCEDURE Proc44(p1: WalkPtr); FORWARD;
 PROCEDURE ExpandStdProc45(std: CARDINAL); FORWARD; (* FIXME: 0-arg call site *)
 PROCEDURE ExpandStdProc46; FORWARD;
@@ -846,27 +870,33 @@ END ParseFuncCall;
 PROCEDURE ParseTypeCast(kind: CARDINAL);
 BEGIN HALT; END ParseTypeCast; (* TEMP-STUB: uplevel proc40 frame; audit later *)
 
-(*{087f} PROCEDURE ExpandStdProc43(code) — scalar transfer const builder *)
-PROCEDURE ExpandStdProc43(code: CARDINAL);
-VAR buf: ARRAY [0..3] OF WORD; tmp: ARRAY [0..1] OF WORD; k, i: CARDINAL;
+(* proc43 @0ad7 — LONGREAL/scalar const builder (NESTED in proc39:
+   ec-call only; move inside proc39 in nesting pass).
+   BufRec nests untagged variants (probed legal): word array + whole
+   LONGREAL + LONGINT-at-2 views, all 8 bytes. TmpRec carries the heap
+   LONGREAL temp (ADDRESS-first, T7-probe shape). *)
+PROCEDURE Proc43(code: BOOLEAN);
+VAR buf: BufRec; (* word-2, 8 bytes *) tmp: TmpRec; (* word-3, 4 bytes *)
+    i: CARDINAL; (* word-4 *) k: CARDINAL; (* word-5 *)
 BEGIN
-  k := TypeKindOf(); (*{0adf} local proc27 *)
-  k := TypeKindOf(); (*{0889-088a} local proc27 *)
-  IF k <= 1 THEN (*{088b-088d} short ordinal: bias into const *)
-    CodeGen.QueueConst(code-k*32768); RETURN; (*{088f-0896}*)
-  END;
-  i := 0; (*{089a-089c}*)
-  REPEAT buf[i] := 65535; INC(i); UNTIL i > 3; (*{089c-08a8} all-bits *)
-  IF code # 0 THEN buf.raw[3] := 32767; (*{08aa-08b3} max CARDINAL *)
-  ELSIF k = 2 THEN buf.raw[0] := 8000H; buf.raw[1] := 0; (*{08b5-08c0} MIN(LONGINT) *)
-  END;
-  IF k = 5 THEN (*{08c2-08c4} LONGREAL: convert via temp *)
-    tmp := buf; (* copy 8 {08c7-08c9} *)
-    tmp := LONGREAL(buf); (*{08cc-08d1} FIXME: conversion sketch *)
-    CodeGen.QueueLongConst(3, tmp); (*{08d2-08d7} kind 3 *)
-  ELSE CodeGen.QueueLongConst(2, buf); (*{08db-08df} kind 2 *)
-  END;
-END ExpandStdProc43;
+  k := TypeKindOf();
+  IF k <= 1 THEN
+    CodeGen.QueueConst(k * 32768 - ORD(code));
+  ELSE
+    i := 0;
+    REPEAT buf.w[i] := 65535; INC(i); UNTIL i > 3;
+    IF code THEN buf.w[3] := 32767;
+    ELSIF k = 2 THEN buf.li := -2147483647L - 1L; (* MINLONG: -2147483648L literal rejected (unary-minus overflow); this folds to the same dword-imm *)
+    END;
+    IF k = 5 THEN
+      Scanner.Allocate(tmp.a, 8);
+      tmp.a^.lr := buf.lr;
+      CodeGen.QueueLongConst(3, tmp.lh);
+    ELSE
+      CodeGen.QueueLongConst(2, buf.li);
+    END;
+  END;
+END Proc43;
 
 (* proc44 @0b3c — descriptor-walk const collector (NESTED in proc39:
    ec/ee calls only; move inside proc39 in nesting pass). *)