Просмотр исходного кода

feat(express): verify proc10/11; LoadIndirect takes Head value, UNTIL-NOT shape

Eric Streit 2 недель назад
Родитель
Сommit
b297ab9c80
3 измененных файлов с 47 добавлено и 6 удалено
  1. 6 0
      SESSION.md
  2. 1 1
      src/compiler/EXPRESS.DEF
  3. 40 5
      src/compiler/EXPRESS.MOD

+ 6 - 0
SESSION.md

@@ -293,3 +293,9 @@ Next: GENZ80 media hunt; stage-2 pty-driven MCD diff per module.
   store is `d^.typ := NodePtr(d^.typ^.w2)` (5-push: d,d,typ,w2,store —
   direct unwrap, NO T1 call, zero-cost transfer). Scorer PREFIX(+n) with
   trailing gap-junk = SAME body (verify by byte list, not label).
+- Verified now 25: + proc10 NormalizeOperand (59/59), proc11 LoadIndirect
+  (53/53). proc11 takes Head VALUE (reserve_string entry copy; writers need
+  private copy); callers pass free ^ derefs (Q(p^) probed legal). UNTIL-NOT
+  emits `not+jpfalse-back` (matches proc20's UNTIL NOT). d.typ-unwrap same
+  5-push shape as CheckAndStore. ADR(d) on value param legal (alt for
+  EmitAddress(ADR(d)) kept HeadPtr signature, no call-site churn).

+ 1 - 1
src/compiler/EXPRESS.DEF

@@ -55,7 +55,7 @@ PROCEDURE PushExprDesc(dst: HeadPtr; src: DescPtr);
 PROCEDURE PopExprDesc(d: RecordPtr);
 PROCEDURE EmitOp(subOp, typeKind: CARDINAL);
 PROCEDURE NormalizeOperand(d: HeadPtr);
-PROCEDURE LoadIndirect(d: HeadPtr);
+PROCEDURE LoadIndirect(d: Head);
 PROCEDURE BoolCondHelper;
 PROCEDURE GetConstVal;
 PROCEDURE OpSetTest(allowed: BITSET; errCode: CARDINAL);

+ 40 - 5
src/compiler/EXPRESS.MOD

@@ -145,10 +145,45 @@ PROCEDURE Proc6;
 BEGIN
   IF curDesc^.typ^.w4 = 1 THEN curDesc^.typ := NodePtr(curDesc^.typ^.w2) END;
 END Proc6;
+(* proc10 @0127 — ~NormalizeOperand: fold descriptor to pending-op form. *)
 PROCEDURE NormalizeOperand(d: HeadPtr);
-BEGIN HALT; END NormalizeOperand;
-PROCEDURE LoadIndirect(d: HeadPtr);
-BEGIN HALT; END LoadIndirect;
+VAR v, k: CARDINAL; (* local-2, local-3 *)
+BEGIN
+  v := CARDINAL(d^.value); k := d^.kind;
+  IF k = 5 THEN
+    LoadIndirect(d^);
+    CodeGen.EmitTypedOp(8, 0);
+    CodeGen.EmitTypedOp(6, 0);
+  ELSIF (Proc24(d^.typ) OR (d^.typ^.w4 > 9)) AND (k <> 2) THEN
+    CodeGen.SetPendingOp(1, k, v, d^.extra);
+  ELSE
+    IF k <= 1 THEN v := (CARDINAL(d^.typ^.w3) + 1) DIV 2 * 2 END;
+    CodeGen.SetPendingOp(8, k, v, d^.extra);
+  END;
+END NormalizeOperand;
+(* proc11 @00e1 — ~LoadIndirect: normalize scratch copy, emit address code.
+   d is a VALUE param (entry copies 10 bytes via reserve_string so field
+   writes don't touch the caller); callers pass free ^ derefs. *)
+PROCEDURE LoadIndirect(d: Head);
+VAR flag: BOOLEAN; (* local-2 *)
+BEGIN
+  IF LookupField(RecordPtr(d.typ)) THEN
+    flag := FALSE;
+    REPEAT
+      EmitAddress(ADR(d));
+      CodeGen.QueueConst(1);
+      CodeGen.EmitTypedOp(6, 0);
+      IF flag THEN CodeGen.EmitTypedOp(8, 0) END;
+      d.typ := NodePtr(d.typ^.w5);
+      DEC(d.extra, 2);
+      flag := TRUE;
+    UNTIL NOT LookupField(RecordPtr(d.typ));
+    CodeGen.QueueConst(CARDINAL(d.typ^.w3));
+    CodeGen.EmitTypedOp(8, 0);
+  ELSE
+    CodeGen.QueueConst(CARDINAL(d.typ^.w3));
+  END;
+END LoadIndirect;
 PROCEDURE BoolCondHelper;
 BEGIN HALT; END BoolCondHelper;
 PROCEDURE OpSetTest(allowed: BITSET; errCode: CARDINAL);
@@ -444,7 +479,7 @@ BEGIN
     IF LookupField(RecordPtr(t)) THEN
       flags := CARDINAL(t^.w5^.word3);
       IF LookupField(t^.w5) OR ODD(flags) THEN
-        LoadIndirect(curDesc);
+        LoadIndirect(curDesc^);
         CodeGen.QueueConst(1);
         CodeGen.EmitTypedOp(7, 0);
         CodeGen.QueueConst(2);
@@ -878,7 +913,7 @@ BEGIN
             ELSE (*{0b27} address-builtin path *)
               save5 := CodeGen.emitEnabled; CodeGen.emitEnabled := 0; (*{0b27-0b2b}*)
               ParseDesignatorTail; CodeGen.emitEnabled := 1; (*{0b2d-0b2f}*)
-              LoadIndirect(curDesc); (*FIXME-ARG*) (*{0b31} local proc11 *)
+              LoadIndirect(curDesc^); (*FIXME-ARG*) (*{0b31} local proc11 *)
             END;
         | 103..105:
             Scanner.PushWith; Scanner.ExpectKd(3); (*{0b34-0b37}*)