summary_step5.4.md 2.0 KB

V3 step 5.4 — Files (done 2026-09-22)

Fourth stdlib landing; completes the plan-listed stdlib (Strings/TextIO/WholeIO/Math/Files). Suite 94/94 (51 run — incl. 4 trap-aborts, 5 sessions, 2 session-output, 2 session-input, 1 unit — + 43 reject). LL(1)-clean, zero gm2 warnings.

Files (stdlib/files)

Sequential files over libc stdio, bound via EXTERNAL: OpenRead/OpenWrite, Close, ReadChar/ReadInt, WriteChar/WriteInt/WriteString/WriteLn. A File is an opaque handle; NIL means the open failed.

Shim additions (runtime/syslib/shim.c)

m2fopenread/m2fopenwrite (convert the descriptor string to a NUL-terminated buffer, then fopen), m2fclose, m2fgetc, m2freadint, m2fputc, m2fwriteint, m2fputs, m2fwriteln. A shared m2cstr helper does the descriptor→C-string copy.

Tests

FilesProg → 42: writes 42 to gen_ssa/_files_tmp.txt, reopens it, reads the integer back into ExitCode.

Two findings (documented, affecting later work)

  1. Qualified access is flatten-on-import. Files.WriteInt materializes WriteInt into the client scope; if the client already imported a different module's WriteInt (e.g. from SysIO), Materialize returns the existing node and the call resolves to the wrong signature (233). The tests avoid mixing same-named imports; true per-module qualified resolution is deferred.
  2. Handles must be pointer-typed. File = INTEGER gave a w (32-bit) value and truncated the C FILE* on return, segfaulting on reuse. File = POINTER TO FileRec (opaque, l) matches the C pointer width. Rule: any value carrying a host pointer must be a pointer-class type, not INTEGER.

Deferred to 5.5+/step 7

Storage/SYSTEM (ALLOCATE/DEALLOCATE, ADDRESS, generic pointers — needs SYSTEM types), ReadString, string escapes, explicit external link names. Traps still $abort; runtime/syslib SYSTEM/Storage/Trap land with the step-7 syslib port.