# V3 step 5.7 — SYSTEM facilities + Storage (done 2026-09-22) Unblocks the pointer/generic-memory layer needed by the syslib port. Suite 98/98. LL(1)-clean, zero gm2 warnings. ## SYSTEM facilities (built-in, no import) Following V3's "built-in over module" choice (like `NEW`/`DISPOSE`), the SYSTEM basics are predef rather than an importable module (a documented divergence from ISO): - **`ADDRESS`** — new predef type, pointer-sized (`l`), class `ClPtr`. Interchangeable with any `POINTER TO T` for assignment and `VAR` parameters (`Assignable`/`VarParamOk` rules), and `NIL`-assignable. - **`ADR(x)`** — address of an addressable designator (var, param, or any indexed/field/deref designator); result `ADDRESS`. 230 on non-addressable operands. - **`SIZE(x)` / `TSIZE(x)`** — full allocation footprint (`SymTab.ObjectSize`: arrays `8 + count*element`, else inline `TypeSize`); result INTEGER. ## Storage (`stdlib/storage`) `ALLOCATE(VAR p : ADDRESS; size)`, `DEALLOCATE(VAR p : ADDRESS; size)` (nils `p`), `REALLOCATE(VAR p : ADDRESS; oldSize, newSize)`, binding libc `malloc`/`free`/`realloc` directly. Because `ADDRESS` is interchangeable with typed pointers, the classic idiom works: ```modula-2 TYPE PP = POINTER TO P; ALLOCATE(p, SIZE(p^)); (* p : PP *) p^.x := 30; ... DEALLOCATE(p, SIZE(p^)) ``` ## Test `StorageProg` → 42: allocates a record through a typed pointer, writes two fields, checks `ADR(p^.x) # NIL`, frees. Image shows `call $malloc(w size)` / `call $free(l addr)`. ## Deferred `VAL`/`CAST` (type-operand casts), `BYTE`, and the `runtime/syslib` `SYSTEM`/`Trap` modules — these land with the step-7 syslib port, which this step now unblocks (FileIO can allocate its descriptors via `Storage`).