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

fix: allow ADDRESS/pointer equality

Eric Streit 4 дней назад
Родитель
Сommit
10174878b2

+ 3 - 3
README.md

@@ -87,13 +87,13 @@ docs/              STATUS.md, plan.md, plan-*.md, analysis_*.md, summary_*.md
 
 ## Status (2026-10-24)
 
-- Suite **305/305**; self-hosting **fixpoint OK** (byte-identical
-  stage2/stage3, 3,807,056 bytes); corpus **519/612 compile-OK,
+- Suite **306/306**; self-hosting **fixpoint OK** (byte-identical
+  stage2/stage3, 3,808,348 bytes); corpus **519/612 compile-OK,
   0 crashes** (`tools/v3-corpus`; the corpus is gm2's testsuite, so it
   mixes conforming Modula-2 with gm2 leniencies — see `docs/gaps/`).
   The remaining `except*`/`onebyte*`-style corpus files still hit V3's
   declaration-order policy.
-- Active branch **`master`**, feature state **`v3-generic-class-instances`**.
+- Active branch **`master`**, feature state **`v3-language-robustness`**.
   Recent milestones: `PACKEDSET`, ISO exceptions (`EXCEPT`/`RETRY`,
   `EXCEPTIONS`, `M2EXCEPTION`, catchable language traps including
   `functionException`, module `FINALLY`), self-referential pointer

+ 2 - 2
TUTORIAL.md

@@ -10,7 +10,7 @@ From the repository root:
 ```sh
 cd compiler
 ./build.sh          # M2.atg -> scanner/parser/driver -> ./M2
-./run_tests.sh      # 305/305
+./run_tests.sh      # 306/306
 ```
 
 `M2` reads Modula-2 sources and writes QBE IR to `gen_ssa/`.
@@ -149,7 +149,7 @@ TMP="$PWD/.scratch/fixpoint-separate" ./bootstrap/fixpoint-separate.sh
 tools/v3-corpus/corpus.sh
 ```
 
-Current gates: suite **305/305**, fixpoint **OK (3,807,056 bytes)**,
+Current gates: suite **306/306**, fixpoint **OK (3,808,348 bytes)**,
 corpus **519/612 compile-OK, 0 crashes**.
 
 ## 7. Current limits

+ 1 - 0
compiler/run_tests.sh

@@ -93,6 +93,7 @@ expect_run t_byte.mod 42
 expect_run t_word16.mod 42
 expect_run t_packedset.mod 42
 expect_run t_ptrchain.mod 42
+expect_run t_addreq.mod 42
 expect_run t_finally.mod 43
 expect_run t_finally_return.mod 43
 expect_run t_finally_except.mod 42

+ 8 - 0
compiler/src/SymTab.mod

@@ -3569,6 +3569,14 @@ PROCEDURE EqCheck (l, r: TypeIndex): BOOLEAN;
     IF ClassOf(r) = ClNil THEN
       RETURN (ClassOf(l) = ClNil) OR (ClassOf(l) = ClPtr)
     END;
+    (* ADDRESS is an untyped pointer: it compares with any pointer
+       value (the address in ADR(p) is the pointer value p itself). *)
+    IF (Resolve(l) = Resolve(dAddr)) AND (ClassOf(r) = ClPtr) THEN
+      RETURN TRUE
+    END;
+    IF (Resolve(r) = Resolve(dAddr)) AND (ClassOf(l) = ClPtr) THEN
+      RETURN TRUE
+    END;
     (* gm2 ext: any two set types compare =/# (word-wise equality);
        a set CASE selector uses this too. *)
     IF (ClassOf(l) = ClSet) AND (ClassOf(r) = ClSet) THEN RETURN TRUE END;

+ 11 - 0
compiler/tests/t_addreq.mod

@@ -0,0 +1,11 @@
+MODULE TAddrEq;
+(* ADDRESS/pointer equality: ADR(p^) is the pointer value p. *)
+TYPE P = POINTER TO INTEGER;
+VAR p : P;
+    a : ADDRESS;
+    ExitCode : INTEGER;
+BEGIN
+  NEW(p); p^ := 42;
+  a := ADR(p^);
+  IF a = p THEN ExitCode := 42 ELSE ExitCode := 1 END
+END TAddrEq.

+ 3 - 0
docs/INDEX.md

@@ -61,6 +61,9 @@ bisecting *why* a decision was made, not for reading end-to-end).
 
 ## Recent session summaries (newest first)
 
+- **`summary_session-2026-10-24-language-robustness.md`** — ADDRESS/
+  pointer equality and the language-robustness pass; tag
+  `v3-language-robustness`.
 - **`summary_session-2026-10-24-separate-compilation.md`** — core
   per-object compilation, stable symbols, init ordering, M2make
   `--separate`; tag `v3-separate-compilation`.

+ 3 - 3
docs/STATUS.md

@@ -4,9 +4,9 @@ This answers "where are we now?".
 
 ## Numbers
 
-- Suite **305/305** (`compiler/run_tests.sh`).
+- Suite **306/306** (`compiler/run_tests.sh`).
 - Self-hosting **FIXPOINT OK** — stage2 and stage3 images are
-  byte-identical (3,807,056 bytes).
+  byte-identical (3,808,348 bytes).
 - Corpus **519 / 612** sources compile with 0 errors, **0 crashes**
   (`tools/v3-corpus/corpus.sh` over the gm2 testsuite; the harness now
   resolves V3's own shipped libraries); the rest are genuine language
@@ -14,7 +14,7 @@ This answers "where are we now?".
   imports of gm2-only modules.  Open-array corpus cases `unbounded`,
   `unbounded2`, `unbounded3`, `unbounded4` and `array9` now compile;
   `unbounded`/`unbounded2`/`unbounded3`/`unbounded4` also run.
-- Branch **`master`**, feature state **`v3-generic-class-instances`**; tree
+- Branch **`master`**, feature state **`v3-language-robustness`**; tree
   clean.
 
 ## Architecture (current)

+ 2 - 1
docs/comparison-PIM4-gm2-V3.md

@@ -2,7 +2,7 @@
 
 **Date:** 2026-10-24 · **V3 state:** open arrays, dialect library
 folders and separate compilation with `M2 -I`/incremental objects
-(suite 305/305, self-hosting fixpoint OK 3,807,056 bytes, corpus
+(suite 306/306, self-hosting fixpoint OK 3,808,348 bytes, corpus
 519/612, 0 crashes).
 
 **Scope and sources.**
@@ -80,6 +80,7 @@ change individual cells.
 | Records | ✅ | ✅ | ✅ extensible | ✅ | ✅ (incl. self-referential pointer fields and flat multi-dimensional array fields) |
 | Variant records | ✅ | ✅ | ❌ removed (extensible records replace them) | ✅ | ✅ (plus empty arms/`ELSE`) |
 | Pointers, `NIL`, opaque types | ✅ | ✅ | ✅ (`OPAQUE` keyword) | ✅ | ✅ (incl. chained `p^.next^.value`) |
+| `ADDRESS` ↔ pointer equality | n/a | ✅ | n/a | ✅ | ✅ (`ADR(p^) = p`) |
 | Procedure types | ✅ (`PROCEDURE`) | ✅ (`PROCEDURE`, `PROC`) | ✅ (comma-separated formals) | ✅ | ✅ (`PROCEDURE`, `PROC`; comma/unnamed forms) |
 | Complex types (`COMPLEX`, `LONGCOMPLEX`) | ❌ | ✅ (ISO) | ❌ (not in the base R10 grammar) | ❌ | ❌ (`COMPLEX64` is a `REAL` placeholder) |
 | SYSTEM sized types (`WORD32`, `CARDINAL8`, `BITSET32`, …) | ❌ | ✅ | 🔄 `OCTET` (8-bit), `LONGCARD`, `LONGBITSET` | 🔄 `SHORTINT`/`LONGINT`/`SHORTCARD`/`LONGCARD` family | ✅ 8/16/32 names; `WORD`/`WORD32` 32-bit |

+ 2 - 2
docs/features.md

@@ -1,4 +1,4 @@
-# m2compiler-V3 — feature status (2026-10-24; suite 305/305 green)
+# m2compiler-V3 — feature status (2026-10-24; suite 306/306 green)
 
 Pipeline: Coco/R `M2.atg` (1748 lines, 73 productions) → `gm2`-built
 `M2` → QBE `.ssa` → `qbe` → `cc` → run. `SymTab.mod` 1623 lines,
@@ -148,7 +148,7 @@ Legend: ✅ done · 🔄 partial · ⏸ not started / deferred.
   literals (`"W" + "o"`), string `CONST`s and ordinal relations
   (`ORD(a > b)` in a `CONST`). UString `+`/`LEN` likewise.
 - ✅ `__FILE__`, `__LINE__`, `__FUNCTION__` predefined literals.
-- ✅ `NIL` comparisons/assignment.
+- ✅ `NIL` comparisons/assignment; `ADDRESS`↔pointer equality (`ADR(p^) = p`).
 - ✅ `VAL`/`ADR`/`TSIZE`/`SIZE`/`HIGH`/`LEN` and `FLOAT`/`LFLOAT`
   work.  Array
   `SIZE`/`TSIZE` use payload bytes (no descriptor header/term slot);

+ 1 - 1
docs/plan-separate-compilation.md

@@ -5,7 +5,7 @@
 one-shot mode remains the default for the suite/corpus; this document
 keeps the design record and the deferred phases.
 
-**Baseline now:** suite 305/305, fixpoint OK 3,807,056 bytes, corpus
+**Baseline now:** suite 306/306, fixpoint OK 3,808,348 bytes, corpus
 519/612, 0 crashes.
 
 ---

+ 29 - 0
docs/summary_session-2026-10-24-language-robustness.md

@@ -0,0 +1,29 @@
+# Session 2026-10-24 — language/robustness pass
+
+**Gates:** suite **306/306**, one-shot fixpoint **OK (3,808,348
+bytes)**, separate-object fixpoint **OK (11 objects)**, corpus
+**519/612 compile-OK, 0 crashes**.
+
+## Landed
+
+- **`ADDRESS` ↔ pointer equality** (`SymTab.EqCheck`): an `ADDRESS`
+  now compares with any pointer value, which is the standard way to
+  check `ADR(p^) = p`.  Regression `t_addreq`.
+- The corpus case `adraddress` remains a declaration-order reject; the
+  language operation itself is no longer a gap.
+- Updated the feature status, comparison table and corpus triage.
+
+## Still open (language/robustness)
+
+- Wide sets (`SET OF CARDINAL`, spans above 65536 bits) remain an
+  implementation limit.
+- `COMPLEX*`, true 16-bit `SHORTREAL`, absolute variables and inline ASM
+  remain outside the chosen PIM/ISO target.
+- ISO exception protection/coroutine follow-ups.
+- Parser error recovery and diagnostic polish.
+- The remaining corpus `LANG` cases are mostly deliberate
+  declaration-order policy or dialect choices.
+
+## Commit/tag
+
+- feature tag `v3-language-robustness`

+ 2 - 2
docs/summary_session-2026-10-24-separate-compilation.md

@@ -4,7 +4,7 @@ V3 now builds per-unit objects.  The one-shot mode remains the default
 for the suite/corpus.
 
 **Branch:** `master`.  **Feature state:** `v3-separate-compilation`.
-**Gates:** suite **305/305**, fixpoint **OK (3,807,056 bytes)**,
+**Gates:** suite **306/306**, fixpoint **OK (3,808,348 bytes)**,
 corpus **519/612 compile-OK, 0 crashes**.
 
 ---
@@ -88,7 +88,7 @@ Manual M2make cross-object class check: `CLib.def/.mod` + `CProg.mod`
   `gen_ssa/<Module>.o`, so definition-only data and class vtables link.
 - Added `CDefProg` (class-only `.def` vtable) and M2make checks for the
   ABI stamp and definition-only object.
-- Suite is now 305/305.
+- Suite is now 306/306.
 
 ## Generic-instance objects (2026-10-24)
 

+ 2 - 4
docs/triage-corpus-2026-10-24.md

@@ -89,10 +89,8 @@ No policy relaxation is recommended.
 
 ## Genuine gaps worth considering later
 
-- **ADDRESS ↔ pointer comparison**: `adraddress` exposes it, but the
-  file is also declaration-order.  A small `SymTab.EqCheck` extension
-  is safe (equality only), but it will not move the corpus count until
-  the file’s declaration order is fixed.
+- **ADDRESS ↔ pointer comparison**: fixed for equality (`t_addreq`);
+  `adraddress` remains a declaration-order corpus case.
 - **Absolute variables** and **inline ASM** remain unimplemented
   extensions; neither is part of the current PIM/ISO target.
 - **Wide sets** remain an explicit implementation limit; raising it is