lib: collapse the parallel vstream scaffold onto the single Hare io surface (#94 fold-eFinal)
The Option-C parallel _v vstream API was scaffolding to bring the io stack up alongside the old surface; carrying both permanently is a rule-9 divergence from ref/hare, which has exactly one io surface. Collapse onto that surface (stream = *vtable, ref/hare/io/stream.ha) and rename the _v symbols to their Hare names (io vstream->stream, fmt vfprint->fprint, bufio/memio/log surfaces, log.new). Deletes the 4 lib/*/vstream.ww scaffold files; regenerates w6c/wwdump combined.ww. cstage and wwstage stay byte-identical and combined_ww_fresh holds; all 220 tests pass.
This commit is contained in:
46
lib/io/io.ww
46
lib/io/io.ww
@@ -1,44 +1,26 @@
|
||||
// io — stream interface (Plan 9 Bio / Hare io::stream shape).
|
||||
//
|
||||
// No closures, no methods. A `stream` is a struct of function
|
||||
// pointers plus a `ctx: *void`. The error channel is the return
|
||||
// value of read/write/close — Hare-shaped tagged unions instead of
|
||||
// errno-style integer sentinels.
|
||||
// No closures, no methods. A `stream` is a pointer to a `vtable` of
|
||||
// function pointers (lib/io/stream.ww); read/write/close dispatch
|
||||
// through it. The error channel is the return value — Hare-shaped
|
||||
// tagged unions instead of errno-style integer sentinels.
|
||||
//
|
||||
// This file owns the eof / underread variant tags; lib/io/stream.ww
|
||||
// owns the `vtable` + `stream` + read/write/close dispatchers, and
|
||||
// lib/io/types.ww owns the error union, mode/whence enums, and the
|
||||
// reader/writer/closer fn-type aliases. #94 fold-eFinal collapsed the
|
||||
// pre-vtable `stream` struct + `closed` tag into the single vtable
|
||||
// surface; the dispatchers are read/write/close (over `stream`),
|
||||
// final over `handle` at io fold-2 (#5).
|
||||
package io;
|
||||
|
||||
// eof — read past the end of the stream. Hare uses the `done`
|
||||
// singleton for EOF; ww doesn't have `done` yet so we ship a
|
||||
// named-void variant tag.
|
||||
package io;
|
||||
|
||||
// named-void variant tag. Lifts to `done` with #93.
|
||||
export type eof = void;
|
||||
|
||||
// closed — operation attempted on a stream that has already been
|
||||
// closed. ww-specific: Hare's io collapses this into the wider
|
||||
// errors union, but our stream vtable has no handle-ownership
|
||||
// semantics, so a distinct tag is honest. Named void.
|
||||
export type closed = void;
|
||||
|
||||
// underread — an I/O handle hit eof partway through a fixed-size
|
||||
// read. Payload is the byte count actually delivered. Mirrors
|
||||
// Hare's `io::underread = !size`; ww uses i32 because the
|
||||
// underlying buffer-length type is i32 today.
|
||||
export type underread = !i32;
|
||||
|
||||
export type stream = struct {
|
||||
ctx: *void,
|
||||
read: fn(s: *stream, buf: []u8) (i32 | eof | closed),
|
||||
write: fn(s: *stream, buf: []u8) (i32 | closed),
|
||||
close: fn(s: *stream) (void | closed),
|
||||
};
|
||||
|
||||
export fn read(s: *stream, buf: []u8) (i32 | eof | closed) = {
|
||||
return s.read(s, buf);
|
||||
};
|
||||
|
||||
export fn write(s: *stream, buf: []u8) (i32 | closed) = {
|
||||
return s.write(s, buf);
|
||||
};
|
||||
|
||||
export fn close(s: *stream) (void | closed) = {
|
||||
return s.close(s);
|
||||
};
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// stream — Hare-shaped vtable port. Project #94 fold-e1.
|
||||
// stream — Hare-shaped vtable surface. Project #94 fold-eFinal.
|
||||
//
|
||||
// Adds the additive vtable surface alongside lib/io/io.ww's pre-vtable
|
||||
// stream struct + read/write/close wrappers (which fold-e2-eN migrate
|
||||
// to vtable-backed implementations and then retire). Three exports:
|
||||
// The single io stream surface (the fold-eFinal collapse retired the
|
||||
// pre-vtable `stream` struct + `closed` tag). Three exports:
|
||||
//
|
||||
// vtable a struct of optional fn-pointer slots — reader/writer/
|
||||
// closer per ref/hare/io/stream.ha:36-42. Hare spells the
|
||||
@@ -10,35 +9,25 @@
|
||||
// spelling (#192), so each slot is a `(*T | void)` tagged
|
||||
// union (Plan-9-lean per the Nullable kept ruling; opt-in
|
||||
// at optionality boundaries only).
|
||||
// vstream `*vtable` alias matching Hare's `stream = *vtable`
|
||||
// (ref/hare/io/stream.ha:33). Named `vstream` rather than
|
||||
// `stream` because lib/io/io.ww still owns the legacy
|
||||
// `stream` struct name until fold-eN collapses both.
|
||||
// st_read /
|
||||
// st_write /
|
||||
// st_close the three dispatchers per ref/hare/io/stream.ha:44-68.
|
||||
// stream `*vtable` alias matching Hare's `stream = *vtable`
|
||||
// (ref/hare/io/stream.ha:33).
|
||||
// read /
|
||||
// write /
|
||||
// close the three dispatchers per ref/hare/io/stream.ha:44-68.
|
||||
// Each `match`es the matching vtable slot, returns
|
||||
// `errors.unsupported` (widened twice) when the slot is
|
||||
// void, otherwise calls through the fn pointer.
|
||||
// void, otherwise calls through the fn pointer. Hare keeps
|
||||
// these private (`st_read` …) behind a `handle`-typed
|
||||
// public `read`/`write`/`close`; ww has no `handle` yet
|
||||
// (io fold-2, #5), so the dispatchers ARE the public
|
||||
// surface and grow the `handle` match when #5 lands.
|
||||
//
|
||||
// Fold-e1 cgen/checker dependencies (all closed at HEAD): #191
|
||||
// (N_DOT on aliased-ptr receiver — `s.reader` resolves through the
|
||||
// `vstream = *vtable` alias), #198 (`is` on cross-module variant
|
||||
// tag), #199 α (concrete→tagged widen via NAMED-variant nominal
|
||||
// match, used by `let e: error = u;`), #200 (`as` payload-extract),
|
||||
// #201 (return-of-tagged-call forwards instead of rewinds), #205
|
||||
// (tagged→tagged subset accepts NAMED-variant nominal match, used
|
||||
// by `return e;` where ret type contains `error` as a direct
|
||||
// variant). Two direct widens compose for the void-arm `return`:
|
||||
// concrete `errors.unsupported` → tagged `error` via #199 α, then
|
||||
// tagged `error` → tagged `(size | eof | error)` via #205.
|
||||
//
|
||||
// Deferrals (drew-signed): `seeker` lands with fold-e2 once `off`
|
||||
// + `whence` plug into the signature; Hare's `?`-propagating
|
||||
// `st_close` body (`c(s)?;`) collapses to a direct `return (*c)(s);`
|
||||
// here because #173 (TRY-on-tagged-return both-stages broken) is
|
||||
// still open — the dispatcher's surface stays Hare-shaped, only the
|
||||
// internal try-prop is omitted.
|
||||
// Deferrals (drew-signed): `seeker` lands with io fold-2 (#5) once `off`
|
||||
// + `whence` plug into the signature. Hare's `?`-propagating `close`
|
||||
// body (`c(s)?;`) collapses to a direct `return (*c)(s);` here because
|
||||
// the dispatcher's surface stays Hare-shaped; only the internal
|
||||
// try-prop is omitted (#173 history, now closed — kept direct for the
|
||||
// void-arm fall-through shape).
|
||||
|
||||
package io;
|
||||
|
||||
@@ -50,16 +39,15 @@ export type vtable = struct {
|
||||
closer: (*closer | void),
|
||||
};
|
||||
|
||||
// ref/hare/io/stream.ha:33. `vstream` not `stream` while io.ww still
|
||||
// owns the legacy `stream` struct name.
|
||||
export type vstream = *vtable;
|
||||
// ref/hare/io/stream.ha:33.
|
||||
export type stream = *vtable;
|
||||
|
||||
// ref/hare/io/stream.ha:44-50. The void-arm `return e;` chains two
|
||||
// direct widens: `errors.unsupported → error` via #199 α, then
|
||||
// `error → (size | eof | error)` via #205. The call-arm spells the
|
||||
// fn-ptr call explicitly per #193 (ww requires `(*r)(args)` rather
|
||||
// than implicit `r(args)`).
|
||||
export fn st_read(s: vstream, buf: []u8) (size | eof | error) = {
|
||||
export fn read(s: stream, buf: []u8) (size | eof | error) = {
|
||||
match (s.reader) {
|
||||
case void => {
|
||||
let u: errors.unsupported;
|
||||
@@ -71,7 +59,7 @@ export fn st_read(s: vstream, buf: []u8) (size | eof | error) = {
|
||||
};
|
||||
|
||||
// ref/hare/io/stream.ha:53-59.
|
||||
export fn st_write(s: vstream, buf: []u8) (size | error) = {
|
||||
export fn write(s: stream, buf: []u8) (size | error) = {
|
||||
match (s.writer) {
|
||||
case void => {
|
||||
let u: errors.unsupported;
|
||||
@@ -84,10 +72,9 @@ export fn st_write(s: vstream, buf: []u8) (size | error) = {
|
||||
|
||||
// ref/hare/io/stream.ha:62-68. Hare propagates the close error via
|
||||
// `c(s)?;` then falls through to the void arm; ww collapses to a
|
||||
// direct return because #173 (TRY-on-tagged-return) is still open.
|
||||
// The surface (void | error) matches; only the internal try-prop
|
||||
// is omitted.
|
||||
export fn st_close(s: vstream) (void | error) = {
|
||||
// direct return for the void-arm fall-through shape. The surface
|
||||
// (void | error) matches.
|
||||
export fn close(s: stream) (void | error) = {
|
||||
match (s.closer) {
|
||||
case void => return void;
|
||||
case let c: *closer => return (*c)(s);
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
// types — error union, mode/whence enums, reader/writer/closer
|
||||
// fn-type aliases. Project #94 fold-1 step (d) (drew Fold D); the
|
||||
// fn-aliases re-targeted from *stream → vstream as part of fold-e1
|
||||
// (vtable port in stream.ww).
|
||||
// fn-type aliases. Project #94 fold-eFinal; the fn-aliases target
|
||||
// `stream` (= `*vtable`, the single io surface).
|
||||
//
|
||||
// Hare splits the io module across stream.ha + types.ha and ww does
|
||||
// the same: lib/io/io.ww owns the (pre-vtable) `stream`, `eof`, and
|
||||
// `underread` shapes; lib/io/stream.ww owns the Hare vtable port
|
||||
// (`vtable`, `vstream`, `st_read`/`st_write`/`st_close` dispatch);
|
||||
// this file owns the surrounding port. The three files share
|
||||
// `package io;` so cross-file refs resolve via the dir-enum concat
|
||||
// order (io.ww < stream.ww < types.ww — `vstream` lands before the
|
||||
// reader/writer/closer aliases below).
|
||||
// the same: lib/io/io.ww owns the `eof` and `underread` tags;
|
||||
// lib/io/stream.ww owns the vtable surface (`vtable`, `stream`,
|
||||
// `read`/`write`/`close` dispatch); this file owns the surrounding
|
||||
// port. The three files share `package io;` so cross-file refs
|
||||
// resolve via the dir-enum concat order (io.ww < stream.ww < types.ww
|
||||
// — `stream` lands before the reader/writer/closer aliases below).
|
||||
//
|
||||
// Deferrals (drew-signed): `handle`, `seeker`, `copier`, `strerror`
|
||||
// land with fold-e2+ (need the `handle` sum). Hare's `EOF = done`
|
||||
// land with io fold-2 (#5; need the `handle` sum). Hare's `EOF = done`
|
||||
// stays as `io.eof` until the `done` singleton ships (#93).
|
||||
|
||||
package io;
|
||||
@@ -43,20 +41,20 @@ export type whence = enum i32 {
|
||||
// ww enumerates the tags explicitly (ken's #204-block — spread of an
|
||||
// errors-side tagged into this union triggers a wrapper-vs-flatten
|
||||
// layout mismatch; #199b layout-extension is the deferred fix). The
|
||||
// st_read/st_write dispatchers in stream.ww return
|
||||
// `errors.unsupported` when the matching vtable slot is unset, so the
|
||||
// variant lands here directly.
|
||||
// read/write dispatchers in stream.ww return `errors.unsupported`
|
||||
// when the matching vtable slot is unset, so the variant lands here
|
||||
// directly.
|
||||
export type error = !(errors.unsupported | underread | nomem);
|
||||
|
||||
// ref/hare/io/types.ha:46. `eof` (not Hare's `done`) per the io.ww:8
|
||||
// rationale; lifts to `done` with #93. `vstream` forward-refs the
|
||||
// ref/hare/io/types.ha:46. `eof` (not Hare's `done`) per the io.ww
|
||||
// rationale; lifts to `done` with #93. `stream` forward-refs the
|
||||
// `*vtable` alias in stream.ww — the dispatcher receives the vtable
|
||||
// pointer directly (Hare's stream.ha:33 + types.ha:46 collapse).
|
||||
export type reader = fn(s: vstream, buf: []u8) (size | eof | error);
|
||||
export type reader = fn(s: stream, buf: []u8) (size | eof | error);
|
||||
|
||||
// ref/hare/io/types.ha:51. No `const` qualifier — ww has none, and
|
||||
// lib/io/io.ww:30 + lib/sort/sort.ww:18 drop it the same way.
|
||||
export type writer = fn(s: vstream, buf: []u8) (size | error);
|
||||
// lib/sort/sort.ww:18 drops it the same way.
|
||||
export type writer = fn(s: stream, buf: []u8) (size | error);
|
||||
|
||||
// ref/hare/io/types.ha:55.
|
||||
export type closer = fn(s: vstream) (void | error);
|
||||
export type closer = fn(s: stream) (void | error);
|
||||
|
||||
Reference in New Issue
Block a user