wwstage: port struct embedding; graduate #59.13
The last frontend-gap pin: wwstage had no Hare struct embedding
(struct { hash.hash, ... }), rejecting lib/crypto/sha256 at parse.
- parse.ww: the three member forms (named / anonymous struct / bare
dotted-ident embed), consume-then-branch since this parser has no
peek; embeds carry f.str == "" and the type in f.lhs.
- check.ww N_TSTRUCT flatten: promote the inner struct's flattened
fields at base+src.offset (check.c:961-990); the embed is one
nested-struct unit in the slot ladder; the resolved inner AST is
planted on the TFIELD rhs for cgen.
- check.ww walkers: astoffset / exprtype N_DOT / #251 struct-lit
field lookups descend embeds through shared helpers; the collision
and non-struct-embed rejects live in validatestructfields (the
once-per-decl diagnostic site).
- cgenutil.ww registerstruct: regfieldrun walks the AST against the
flattened tfield cursor, descending embeds via the planted inner
AST so promoted fieldinfo entries keep the inner field's own name
and type node.
- wwi printers unchanged (both stages already emit nameless fields).
sha256_test compiles byte-identically end to end and its 6 tests
pass; 989_lib_byteid is now 44 id / 0 divergent / 0 wwreject.
Fixtures r5913_* (promoted rw, offset shift, anonymous embed,
two-level embed + promoted fn-ptr callee, three rejects); corpus pin
1485/2970.
This commit is contained in:
@@ -214,11 +214,37 @@ fn parsetype(p: *parser) *node = {
|
||||
let fpl = p.curline;
|
||||
let fpc = p.curcol;
|
||||
let f = newnode(nkind.N_TFIELD, fpf, fpl, fpc);
|
||||
let fid: str;
|
||||
expectident(p, &fid);
|
||||
f.str = fid;
|
||||
expecttok(p, tkind.TK_COLON, "expected ':' in field");
|
||||
f.lhs = parsetype(p);
|
||||
// Three member forms (cstage parse.c:230-244):
|
||||
// name: type — regular field
|
||||
// struct { ... } — anonymous embedded struct
|
||||
// Identifier — bare dotted-ident embedded type
|
||||
// Embeds carry f.str == "" and the type in f.lhs. The
|
||||
// cstage branches on peek≠':'; this parser has no peek,
|
||||
// so consume the leading ident first and branch on ':'.
|
||||
if (p.curkind == tkind.TK_STRUCT) {
|
||||
f.lhs = parsetype(p);
|
||||
} else {
|
||||
let fid: str;
|
||||
expectident(p, &fid);
|
||||
if (p.curkind == tkind.TK_COLON) {
|
||||
advance(p);
|
||||
f.str = fid;
|
||||
f.lhs = parsetype(p);
|
||||
} else {
|
||||
// Rebuild the dotted TNAME the consumed ident
|
||||
// began (parsetype's TK_IDENT collapse, L280-285).
|
||||
let tn = newnode(nkind.N_TNAME, fpf, fpl, fpc);
|
||||
let acc = fid;
|
||||
for (p.curkind == tkind.TK_DOT) {
|
||||
advance(p);
|
||||
if (p.curkind != tkind.TK_IDENT) { break; };
|
||||
acc = joindotted(acc, p.curtext);
|
||||
advance(p);
|
||||
};
|
||||
tn.str = acc;
|
||||
f.lhs = tn;
|
||||
};
|
||||
};
|
||||
if (fhead == nil) { fhead = f; ftail = f; }
|
||||
else { ftail.next = f; ftail = f; };
|
||||
if (!accepttok(p, tkind.TK_COMMA)) { break; };
|
||||
|
||||
Reference in New Issue
Block a user