# Session save — 2026-09-22 (m2compiler-V3, step 5 complete) ## Where we are HEAD: `d260e48` — milestone tag `v3-step5` (alongside `v3-step5.1` … `v3-step5.4`). Suite **94/94** (51 run — incl. 4 trap-aborts, 5 sessions, 2 session-output, 2 session-input, 1 unit — + 43 reject). Build warning-free. Tree clean; `git.txt` untracked (now in `.gitignore`). No remote. ## Step 5 in four landings (all green at each tag) - `v3-step5.1` (88/88) — **foreign functions**: `PROCEDURE P(...); EXTERNAL;`, C link-name mangling, no static link for C callees; `runtime/syslib/shim.c` (knows the descriptor layout); `SysIO` (`Write`/`WriteLn`/`WriteInt`/`WriteChar`); first real output. - `v3-step5.2` (90/90) — **`HIGH`/`LEN`** (static for fixed arrays, header-read for open formals); `stdlib/strings` (Length/Assign/Concat/Compare/Copy, logical-length via `m2setlen`); `stdlib/textio`. - `v3-step5.3` (93/93) — **`Math`** (libm `sqrt`/`exp`/`ln`/`sin`/ `cos`/`arctan`/`abs`, `Pi`/`E`); **input** (`m2readchar`/ `m2readint`, `SysIO.ReadChar`/`ReadInt`, harness stdin variant); `stdlib/wholeio`. - `v3-step5.4` (94/94) — **`Files`** (stdio `OpenRead`/`OpenWrite`/ `Close`/`Read*`/`Write*`; opaque pointer handle). `stdlib/`: sysio, textio, strings, wholeio, math, files. ## Locked decisions from this session - Runtime is a C shim (`runtime/syslib/shim.c`) that encodes the compiler's memory model (a string = `[LONGCARD count, bytes]`); stdlib binds it with `EXTERNAL`. Traps are still `$abort`. - A string's descriptor header holds its **logical length**, updated by `m2setlen` on Assign/Concat (fixed arrays would otherwise always report their capacity). - **Host pointers must be pointer-class types.** `File = INTEGER` (`w`) truncated a C `FILE*`; `File = POINTER TO FileRec` (`l`) is required. Applies to any future handle type. ## Known limitations found (next work) 1. **Module-level globals are not module-qualified** — `DeclVar` emits `data $`, so two modules with the same global name collide at link time. Functions are safe (`_`, uid unique per session). 2. **Qualified access is flatten-on-import** — `L.x` clones `x` into the client scope; if the client already imported a same-named export from another module, the call resolves to the wrong signature (233). The tests avoid mixing same-named imports. Both are fixed by a **symbol-naming pass**: prefix module-level globals with their defining module and resolve `L.x`/`L.P` per-module instead of flattening. That also unblocks `Storage`/ `SYSTEM` (`ADDRESS`, generic pointers) and is a prerequisite for the step-7 syslib port and self-hosting. ## Deferred (carry forward) `Storage`/`SYSTEM` (`ALLOCATE`/`DEALLOCATE`, `ADDRESS`, generic pointers), `ReadString`, string escapes, explicit external link names (`EXTERNAL "c_name"`), and the step-6 Unicode work (`UCHAR`/`UString`, UTF-8 lexer). Traps still `$abort`; `runtime/syslib` `SYSTEM`/`Storage`/`Trap` land with step 7. ## Resume commands ```sh cd /home/eric/Projets/Projets-Modula2/MyWork/m2compiler-V3/compiler ./build.sh && ./run_tests.sh # expect 94/94, zero gm2 warnings ``` Recommended next: the symbol-naming / qualified-resolution pass.