# Nested modules + full compiler source set compiles; self image links Tag `v3-selfcompile-image`. Main suite 111/111. ## Landed - **Nested modules (Wirth-style local `MODULE … EXPORT …`)** — the driver's `ListHandler` now lowers: declarations use the enclosing QBE module prefix, a `BEGIN` body becomes an init function that `main` calls, and the `EXPORT` list is hoisted into the enclosing scope via `SymTab.ExportUp` (called before `PopScope`). Test `t_nested` (exit 42) exercises export + init + exported var/proc use. - **`HALT` builtin** (`QbeGen.HaltQ`, `HaltStat`): `call $exit(w 1)` + `hlt`. - **`Strings.Delete` / `Strings.Append`** added (the driver needs them for file names). `Delete` is correct; `Append` works only while the descriptor count has not been shrunk (see string-model note). - **1-char string literal to a `VAR ARRAY OF CHAR`** formal (`Strings.Append(".", …)`): synthesizes a 1-char descriptor and passes its address. ## Bugs found and fixed on the way 1. **Nested anonymous arrays clobbered the shared bound buffer.** `ARRAY [0..3] OF ARRAY [0..7] OF CHAR` emitted the *inner* count for the outer level (8 instead of 4): the inner `ArrayType` reset the shared `blo/bhi/nBounds` before the outer `NestArray` ran. Fixed by snapshotting the bounds (new `BoundCount/BoundLo/BoundHi`) after `]`, before parsing the element type, then nesting from the snapshot. This also fixed QbeGen's own `nestBufs` (was 65536 entries). 2. **`sessBuf` too small / `FileIO.WriteString` misbehaves >~2 MB.** The compiler's own image text exceeds 1 MB. Enlarged `sessBuf` to 4 MiB and flush exactly `sessUsed` bytes with a manual byte loop (host `FileIO.WriteString` segfaults on multi-MB buffers). 3. **`strNams`/`strTexts` capacity** — the compiler image has >256 string literals; raised to 4096 (dropped literals previously left undefined `$str256` references). ## Milestone The **entire compiler source set now compiles under V3** (generated without `-m`, so `M2P` has real `FORWARD`s): ``` SymTab QbeGen M2S M2P M2 (driver) → gen_ssa/M2.ssa (1.31 MB, complete image) qbe gen_ssa/M2.ssa → ok cc …shim.c -lm → /tmp/M2self (7.9 MB) ``` `M2.ssa` is self-contained (461 exported functions: all modules inlined, as V3's model does for a program module). ## Next: self-compiled compiler crashes at startup `/tmp/M2self tests/t_constfold.mod` → SIGSEGV in `SymTab.Init`: ``` Assign_189 <- RawEnter <- Enter <- Predef <- Init <- SymTab_init ``` i.e. an early `ALLOCATE`/field-copy in symbol entry. Likely a V3 codegen/layout issue exposed by the compiler's own code (or the string model). This plus the `Strings.Append` model are the next tasks, then cross-stage `FileIO` + `bootstrap/fixpoint.sh`. ## Files `compiler/src/{M2.atg,SymTab.def,SymTab.mod,QbeGen.def,QbeGen.mod}`, `compiler/tests/t_nested.mod`, `compiler/run_tests.sh`, `stdlib/strings.def`, `stdlib/strings.mod`.