Commit Graph

1376 Commits

Author SHA1 Message Date
52f6d6f0d4 cmd: build local package graphs 2026-08-11 22:26:07 +09:00
db96422f74 compiler: load imports and enforce package exports 2026-08-11 22:25:59 +09:00
7bc96b4e03 protocol: freeze minimal WWAR v1 wire conformance 2026-08-11 19:37:30 +09:00
3157e1d688 docs: simplify WWAR phase boundaries 2026-08-11 19:36:58 +09:00
64f7a54be3 docs: type bootstrap record inputs 2026-08-10 23:34:04 +09:00
d7c57e97e8 docs: distinguish provider requirements from selections 2026-08-10 19:06:57 +09:00
9671cc2feb docs: close Phase 0 protocol gaps 2026-08-10 17:15:44 +09:00
90afbb1c2e docs: resolve WWAR protocol contradictions
Make the schema-1 transcription mechanically consistent before the protocol freeze: restore compiler-protocol identity, use the typed native-contract record identity, distinguish encoding and path classes, and close the package artifact kinds. These corrections must land together because one exhaustive IDL cannot encode the prior conflicting rules.
2026-08-10 15:48:54 +09:00
6880ebe543 docs: define WW Action Build architecture 2026-08-10 15:16:11 +09:00
ca2cadeb41 lib: refresh I/O architecture guidance 2026-08-09 18:19:53 +09:00
0aaba1a254 strings: drop stale runtime dependency 2026-08-09 18:19:06 +09:00
a04de3e02b bufio: make scanning bounded and incremental 2026-08-09 18:17:42 +09:00
09b6f22e85 bufio: preserve partial flush progress 2026-08-09 18:05:21 +09:00
cf8244c0ec memio: make cursor operations overlap-safe 2026-08-09 18:03:19 +09:00
d7d5b593c2 fmt: make formatting complete and rune-safe 2026-08-09 17:59:41 +09:00
976dc8a813 strconv: reject overflow before arithmetic 2026-08-09 17:50:47 +09:00
8e2e6ae162 strings: preserve UTF-8 and boundary invariants 2026-08-09 17:46:22 +09:00
2d947c469e bytes: make search linear and splits consistent 2026-08-09 17:43:31 +09:00
8620e64313 encoding/utf8: enforce scalar and buffer bounds 2026-08-09 17:39:41 +09:00
83101add2c gitignore: drop retired artifact paths 2026-08-09 12:07:57 +09:00
134f0ceef0 test: delete unconsumed legacy inputs 2026-08-09 12:07:13 +09:00
a2faa8b071 w6c: keep nested unwrap destinations distinct 2026-08-09 04:52:43 +09:00
7ab080fe2a docs: rule len and cap as an i32 stability carve-out 2026-08-09 04:40:40 +09:00
ac8ddee6c1 w6l: purge dead elf branches; pin rx extent 2026-08-09 04:37:33 +09:00
e720d4802f w6a: delete dead text state and redundant rex arm 2026-08-09 04:31:37 +09:00
80fc13c828 wcc: delete parser backtracking remnants 2026-08-09 04:25:36 +09:00
c9425a3b46 wcc: delete unused warning counters and ww err twin 2026-08-09 04:19:22 +09:00
2a03cfbfa4 w6c: delete unwired backend pass seams 2026-08-09 04:13:07 +09:00
a3d7f61792 wwpackage: validate cleanup directory after open 2026-08-09 04:06:45 +09:00
8f475affb3 wwfixture: stop before capture ordinals wrap 2026-08-09 04:04:34 +09:00
a85306e68f wwdump: fail ast mode on parser errors 2026-08-09 04:02:11 +09:00
00d0ed502d ww: resolve root argv0 and retire stale help paths 2026-08-09 03:56:37 +09:00
5f829399ea wcc: classify tuple destructure from the rhs type 2026-08-09 03:49:58 +09:00
edacb40bfe w6c: keep unwrap destination off the call stack 2026-08-09 03:44:12 +09:00
a030268c52 wcc: build generated labels at their exact size 2026-08-09 03:38:03 +09:00
0a16811ab1 w6c: preserve grouped and qualified types in wwi 2026-08-09 03:31:40 +09:00
53a9e94736 wcc: reject final-band integer overflow; restore rewind columns 2026-08-09 03:25:17 +09:00
cd11d6e573 ww: driver/coordinator robustness — dirent errors, EINTR, block comments
Three same-cluster robustness holes. enumeratedir treated a failed
getdents64 (r<0) as EOF: a mid-walk error silently truncated the
package source list, and a first-read error was misdiagnosed as
"directory contains no WW package sources" -- it now routes the
caller's "cannot read directory" arm. run_test_bin's waitpid had no
EINTR retry and its return was unchecked, so an interrupted wait
left status==0 and reported a false test PASS (the do_run twin
already retried). The coordinator's pkgskipspace now also skips
/* */ before the package clause like the driver's sep_skip_space --
a source opening with a block comment built under ww but failed
coordinator discovery.
2026-08-09 02:05:48 +09:00
999b110001 wcc: forrange bindings get a per-loop scope; dup binders reject
The TODO(#11) silent-accept of `for (let (a, a) .. xs)` rested on a
stale premise -- resolvewalk has per-block scopes since #53 and IS
the live w6c_ww checker pass. Bindings now install in a per-LOOP
scope (the N_MCASE pattern), so a duplicate name within one pattern
errs "redeclared in same scope" (cstage parity via stamptuplebinds'
scopedefine-nil check) while sequential same-name loops stay legal.
kwtab restores its stated alphabetical order (`import` before `is`,
both stages, kinds swapped in lockstep with names).
2026-08-09 01:59:33 +09:00
411515a83b wcc: checker-seam drain — spreads, tuple aliases, yield scoping
Four seams from one review cluster, all landing on the same checker
files; gates ran on the union (rule 11 body).

?-subset: the wwstage walk compared `...spread` ALIAS nodes on both
sides of the error-subset check, falsely rejecting a spread-carried
error return (`(i64 | ...errs)`, cs-accept/ww-reject) — both sides
now flatten like trycountvariants (cstage Tparams are pre-flattened
at type level).

Multi-let/multi-assign: the tuple gates keyed on the RAW rhs kind,
rejecting a NAMED tuple alias (`type pair = (i64,i64)`; cs clean-
reject, ww asserttyped stop) — both stages chase per #99 alias
transparency, wwstage rettupleof peels the alias so cgmassign keeps
the str element's len/cap stores, and the catA massign-alias error
pin re-rules to a run fixture. The N_MLET diagnostic also printed
its operands swapped (elem/declared reversed vs its wording).

Yield: match_yield_type didn't descend into N_SWITCH, so a yield
inside a switch arm typed the match void and dropped the value
(both stages); and a stray yield outside any match arm reached cgen
unchecked — both stages now gate on a match-arm counter (the
c->loops discipline).
2026-08-09 01:51:39 +09:00
503d1ab01e wcc: wwstage checks call arity at desugarcallargs
cstage rejects `add(1,2,3)` and `add(4)` (too many / not enough
arguments); wwstage ran no count check at this seam, so both built
-- a stray arg pushed silently, a missing one read garbage
(cs-reject/ww-accept build-verdict divergence). Surplus errs when
params exhaust with args left; missing errs on a leftover regular
param (a leftover TK_ELLIPSIS or FFI "..." is a legal zero-arg
variadic tail). fn-VALUE callees still bail at decl==nil -- their
whole typecheck, arity included, stays task #51.
2026-08-09 01:33:14 +09:00
cf9d83b209 wcc: enums compare nominally; folded members keep their enum stamp
Two composing defects made a two-enum union mis-tag in wwstage
(live cs!=ww: `let e: (color|shape) = shape.BALL` stored tag 0 —
the color arm — while cstage stored 1). type_eq/typeeq had no
TY_ENUM arm, so ANY two enums fell into the primitive default and
compared equal; enums are nominal (harec: an enum IS its alias
type) and now compare by node identity only. Underneath, the
wwstage post-order revisit re-stamped the constant-folded enum
member (an N_INTLIT) as untyped_int, clobbering the enum stamp the
N_DOT fold applied, so the widen matcher fell to its first-variant
fallback -- the #59.9 N_BIN guard now twins on N_INTLIT (cstage
cexpr is single-pass and never clobbered).
2026-08-09 01:26:31 +09:00
4a5f64fc3d w6a: bare negative constant parses honestly; name(reg) rejects
Two parse.c operand defects. A bare `-8` (no $) double-negated to
+8: a_parsenum lets strtoll consume the sign, and the caller's
`off * sign` re-applied it (the D_INDIR arm never multiplied, which
is why -8(BP) always worked); the wwstage twin was already correct,
so this was a latent cs!=ww on hand-written source. The name(REG)
non-SB arm faked a D_INDIR off an UNCHECKED reg_lookup and silently
discarded the parsed ident and +disp -- both stages; the shape has
no encoding and now rejects loud.
2026-08-09 01:12:41 +09:00
5006bf4fb9 w6l: link GNU long-name archive members; bad members fail the link
The archive walk skipped every member whose header name starts
with '/', which also dropped GNU long-name members (/N) -- any
member with a >15-char filename silently never linked. Only '/ '
(symbol index) and '//' (long-name table) are non-objects; /N
members index by content (names are never consulted). A member
that fails loadimage in the selective pull also stayed silently
unlinked with rc=0; it now reports and fails the link (rule 7).
wwstage w6l diagnostics ride the same .len idiom as the w6a sweep.
2026-08-09 01:07:19 +09:00
4fe2e25da4 w6a: branch labels stay out of the symtab (isglobal wired)
Every interned symbol -- including branch labels defined via
p.label -- was emitted STB_GLOBAL, so labels were collide-able
across objects and the header's "GLOBAL symbols only" contract was
enforced nowhere (asym.isglobal was set but never read). Labels
stay interned for fixup resolution; the symtab now carries only
exported definitions, undefined externs, and reloc-referenced syms
(a reloc pre-pass marks those). rt/ensure.o drops from 15 emitted
syms to 2. Bootstrap 991-995 hold byte-identical on the new format.
2026-08-09 01:07:19 +09:00
06c40a8bef w6a: MOVB REX for SI/DI/BP/SP; LEAQ/CALL shapes err; honest diag lengths
Three w6a defects, one component. MOVB with an SP/BP/SI/DI register
operand encoded AH/CH/DH/BH -- emit_rex suppressed the bare 0x40
that selects SPL/BPL/SIL/DIL (the comment claimed "we always emit
REX"; encode probe: `MOVB SI,(AX)` -> `88 30` = %dh). emit_rex8
forces the byte for low-byte codes 4-7; no current w6c output emits
those shapes, so all existing objects are unchanged. LEAQ and CALL
unsupported operand shapes fell through with zero bytes and no
errs++ (every MOV arm reports); both now err. Every hardcoded
os.write diagnostic length in the wwstage was one byte short
(truncating the newline/quote); all converted to the .len idiom so
the length cannot drift again.
2026-08-09 01:07:06 +09:00
f06c95e66b w6c: forrange bind cap loud; drain widen gates keyed on type-eq (#55)
Two silent seams in one sweep. The for-range destructure silently
dropped the 9th+ binding in both stages (bind arrays are sized 8);
the cap now hard-stops per the DEFER_MAX/LOOP_MAX discipline (the
shape is unreachable today -- every wide-tuple construction path
already loud-stops). argtaggedwidensz, the drain-side SSoT for
widened call args, still keyed "natural push" on slot-size equality
while pushargsrev flipped to type equality with #55 -- a same-slot
subset was classified widen by push, natural by drain (counts
coincide today; a classification reader desyncs, the #48 shape).
Both sides now share the wsame key; the widen-branch tag miss for a
concrete source joins the task-2 loud-stop family (tagged subset
sources keep t=0 -- their widentag is never read, the scratch store
remaps).

Lead 17 (enum fold-failure prev+1) DISPROVED: enumvalfold gates
every member init in the checker and its fold set is op-for-op
equal to cgen's enumevalmember, so the fallback only runs inside
already-failing compiles.
2026-08-09 00:52:27 +09:00
973dd964c9 wcc: structlit repeat-fill dim off the stamped tinfo (rule 13)
cgstructlitfill's `...` total read only an N_INTLIT dim node, so a
def-dimensioned [N]T struct field under-filled: elements 1..N-1 kept
the zero-fill, silently, wwstage only (cstage and the tn twin read
the stamped array length). Read tichase(fi.tnode.type_).alen first;
the surface node stays as the fallback for unstamped shapes.
2026-08-09 00:40:23 +09:00
f191e6e0e2 wcc: modulo is integer-only; compound ops carry their operand class
Hare's rule (harec check.c binarithm): % and the bitwise/shift five
are integer-only; + - * / need numeric operands. ww grouped % with
the numeric ops, and compound assigns never op-checked at all, so
`a % b` on floats compiled half-lowered (live cs!=ww divergence),
`a %= 2.0` plain-stored the rhs (op silently dropped, both stages),
and `s += "cd"` garbled str headers. Gate both at the checker, both
stages; the cgen float-compound fallbacks and the three unknown-
compound legacy defaults (deref/global/local) demote to rule-7 hard
stops. 34 compound-on-tagged/str/slice fixtures re-pin from the old
cgen "not wired" stops to the earlier checker diagnostics; 3 new
reject fixtures pin the closed shapes.
2026-08-09 00:32:41 +09:00
f0029227b5 wcc: cgdot/cgident dead-end paths are loud (rule 7)
cgdot's local-ident arm silently emitted nothing for a receiver
whose local record carries no type node (inference miss upstream),
leaving the consumer reading stale AX. cgident's tail silently
emitted nothing for any ident that resolved to no local/fn/def/let;
that silence is load-bearing ONLY for the #140 !void error-singleton
value (tag-only, the widen arm stamps the tag) -- keep exactly that
case, mirroring the cstage #140 guard, and hard-stop the rest.
2026-08-09 00:15:10 +09:00