os: graduate O_*, SEEK_* defs to flag and whence enums

Mirrors Hare's `fs::flag` and `io::whence`:

    export type flag = enum i32 {
            RDONLY  = 0,
            WRONLY  = 1,
            RDWR    = 2,
            CREATE  = 64,    // 0o100
            TRUNC   = 512,   // 0o1000
    };

    export type whence = enum i32 { SET = 0, CUR = 1, END = 2 };

open/tryopen/lseek signatures take the enum types (`flags: flag`,
`w: whence`) so callers get type-checked: `os.open(p, os.flag.RDONLY,
0)` is the correct shape, and `os.flag.WRONLY | os.flag.CREATE |
os.flag.TRUNC` typechecks as a `flag` via the same-named-type rule.

Callers in selfhost/cmd/{ww,w6c,w6a,w6l,wwdump} updated from
`os.O_RDONLY` etc. to `os.flag.RDONLY`. SYS_* syscall numbers kept
as `def` for now (internal-only, ABI surface, no Hare analogue in
this scope).

selfhost/test/smoke.ww keeps its standalone-compile property by
using a numeric literal (`0`, RDONLY's value) for the open flags
arg — probe 6 in 990_selfhost compiles smoke.ww with no `use`
expansion, so cross-module type refs like `os.flag.RDONLY` can't
resolve there. Untyped 0 → flag via type_isnum.
This commit is contained in:
2026-05-12 04:41:50 +09:00
parent 5149d10618
commit b9443b1f33
16 changed files with 202 additions and 154 deletions

View File

@@ -155,8 +155,11 @@ export fn main() i32 = {
// Use raw os.open here (returns i32 with -errno) for the same
// reason as os.read below: probe 6 in 990_selfhost compiles
// smoke.ww standalone (no `use` expansion), so cross-module type
// references like `os.oserror` don't resolve at that step.
let fd: i32 = os.open(path.ptr, os.O_RDONLY, 0i32);
// references like `os.oserror` and `os.flag` don't resolve at
// that step. RDONLY is 0; passing the literal keeps the call
// site standalone-compilable to byte-identical asm on both
// compilers.
let fd: i32 = os.open(path.ptr, 0, 0i32);
if (fd < 0) { return 21; };
let rbuf: [128]u8;
// Use raw os.read here (single syscall, plain i64) instead of