From 322eb1d034ab20bf53e2fc9842f848fbc62ed1b2 Mon Sep 17 00:00:00 2001 From: giles Date: Thu, 7 May 2026 09:29:14 +0000 Subject: [PATCH] =?UTF-8?q?plans:=20tick=20Phase=205=20channel=20I/O=20?= =?UTF-8?q?=E2=80=94=20349/349=20green?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- plans/tcl-sx-completion.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/plans/tcl-sx-completion.md b/plans/tcl-sx-completion.md index 9e3cb6d7..bb752719 100644 --- a/plans/tcl-sx-completion.md +++ b/plans/tcl-sx-completion.md @@ -132,6 +132,31 @@ architectural improvement worth doing when the moment is right. --- +## Phase 5 — Channel I/O (random access + non-blocking) ✓ + +Real Tcl channel commands replacing the previous stubs. SX gained 11 channel +primitives in `sx_primitives.ml` (using `Unix.openfile` + `Unix.read`/`write`/ +`lseek`/`set_nonblock`). Tcl `open`/`close`/`read`/`gets`/`puts`/`seek`/`tell`/ +`eof`/`flush`/`fconfigure` now wrap them. + +| Status | Work | Unlocks in Tcl | +|---|---|---| +| [x] | `channel-open`, `channel-close` | `open` returns "fileN", `close` actually closes | +| [x] | `channel-read`, `channel-read-line`, `channel-write` | `read`/`gets`/`puts` to/from real files | +| [x] | `channel-seek`, `channel-tell` | random access — `seek $c offset start\|current\|end`, `tell` | +| [x] | `channel-eof?`, `channel-flush` | proper EOF detection, no-op flush | +| [x] | `channel-blocking?`, `channel-set-blocking!` | `fconfigure $c -blocking 0\|1` | + +Modes supported: `r`, `w`, `a`, `r+`, `w+`, `a+`. Whence: `start`, `current`, `end`. + +`puts` now detects channel argument (string starting with "file") and dispatches +to `channel-write`; otherwise writes to `interp :output` as before. + +**Total: ~half day. 7 new idiom tests covering write+read, gets-loop, seek/tell, +eof-after-read, append mode, seek-to-end, fconfigure-blocking.** + +--- + ## Suggested order 1. **Phase 1** — immediate Tcl wins, zero risk, proves the approach @@ -148,6 +173,7 @@ becomes a lasting SX contribution used by every future hosted language. _Newest first._ +- 2026-05-07: Phase 5 channel I/O — 11 SX primitives (channel-open/close/read/read-line/write/flush/seek/tell/eof?/blocking?/set-blocking!) wrapping Unix.openfile/read/write/lseek/set_nonblock; tcl-cmd-open/close/read/gets-chan/seek/tell/flush rewritten + new tcl-cmd-fconfigure; tcl-cmd-puts dispatches on "fileN" arg; gets registration fixed; +7 idiom tests; 349/349 green - 2026-05-06: Phase 4 env-as-value — current-env (special form via Sx_ref.register_special_form), eval-in-env (primitive in setup_evaluator_bridge), env-lookup + env-extend (in setup_env_operations); 5 idiom tests; 342/342 green - 2026-05-06: Phase 3 OCaml primitives — file-read/write/append/exists?/glob + clock-seconds/milliseconds/format in sx_primitives.ml + unix dep; tcl-cmd-clock/file wired up; 337/337 green - 2026-05-06: Phase 2 coroutine rewrite — `tcl-cmd-coroutine` now creates a `make-fiber`; `tcl-cmd-yield` calls `:coro-yield-fn` (threaded through interp); true suspension; 337/337 green @@ -162,7 +188,7 @@ _Newest first._ ## What stays out of scope - `package require` of binary loadables -- Full `clock format` locale support +- Full `clock format` locale support - Tk / GUI - Threads (mapped to coroutines only, as planned) -- Full POSIX file I/O (seek/tell/async) — stubs are fine +- `chan event` / `fileevent` — event-driven I/O callbacks (Phase 5 covers blocking + non-blocking flag, but no event loop dispatch)