af8836cc8e26e5966a64c9a07f089809e92a907c
Closes the gaps that kept ww_ww from rebuilding the wwstage byte- for-byte. The pre-existing parser silently produced a broken AST on `a, b = fn();` (a no-op exprstmt + a single assign that lost the second tuple slot); the cgen leaned on a handful of cases that the surface type-walker didn't yet cover, so 6a/6l/ww built through wwstage drifted by a handful of bytes per file. Parser: - Multi-assign in parsestmt mirrors cmd/wwc/parse.c:1015-1031. If parseexpr is followed by `,`, switch into N_MASSIGN: collect the chained lvalues with parsebin(parseunary, 1) so they don't eat the trailing `=`, then absorb `= rhs;` and emit the node. Cgen: - N_MASSIGN handler stores AX into l0's slot, pops DX into l1's slot. Same shape as cmd/6c/cgen.c:2424-2440. Lvalues beyond two are dropped (C drops them too). - N_INDEX added to node_isunsigned: `p[i]` where p is *u8/[]u8/ [N]u8 now flags unsigned, so `p[i] >= 48u8` emits JAE instead of JGE. Bit 6a's parsenum. - node_isstr's N_DOT branch now handles chained dots via dot_inner_struct_ptr, so `p.to.asym` (Adr.asym is str) flags as str and push_args_rev pushes both halves. - index_base_esz returns 1 for str-typed struct fields. Was defaulting to 8, so `node.s[i]` scaled by 8 and used MOVQ instead of MOVZBQ. Bit ww/visit_seen. - N_LET with no initializer zero-inits the slot when the underlying type is an 8-byte primitive (pointer, fn-ptr, i64/u64, ...) — matches cmd/6c/cgen.c:2181. Structs, strings, slices, etc. are left for per-field writes, even when their slot rounds up to 8 in scan_locals. New helper type_is_8byte_primitive walks the type AST to make the same call C's checker would. Tests stay 17/17; new self-rebuild test (995) lands in the next commit and gates on these fixes.
Description
No description provided
Languages
C
89.4%
Python
7.2%
Makefile
2.3%
Shell
0.8%
Assembly
0.3%