wcc,lib/ww/syntax: resolve qualified struct-literal pkg.Type{...} (#76)
The parser folded a qualified type pkg.Type into two different node shapes by position: declaration position collapsed it into one N_TNAME (resolved via the strrchr-leaf path), but literal position left an N_DOT chain that the struct-literal typeref handoff had no resolver arm for, so pkg.Type{...} rejected with "expected type expression".
Normalize the literal-position N_DOT chain into the same source-order N_TNAME the declaration path emits, reusing the existing resolver; no new checker arm. cstage flattens at parseprimary struct-lit handoff; wwstage (no token peek) folds dots in parsepostfix and normalizes there, guarding numeric tuple components and staying in the postfix loop so trailing ops still chain. Both stages emit identical N_STRUCTLIT(N_TNAME). Prereq for qualifying wcc syntax refs (#75).
This commit is contained in:
@@ -427,6 +427,28 @@ parsearglist(Parser *p, Tkind close)
|
||||
return head;
|
||||
}
|
||||
|
||||
/* #76: a qualified path `pkg.Type` reaches a struct-literal handoff as an
|
||||
* N_DOT chain (parseprimary's dotted fold). Flatten it into one N_TNAME
|
||||
* whose str joins the chain in SOURCE order — byte-identical to parsetype's
|
||||
* dotted collapse (parse.c: aprintf("%s.%s", ...)) — so resolve_type's
|
||||
* existing N_TNAME arm resolves it with no new checker arm. */
|
||||
static const char *
|
||||
flattendotstr(Parser *p, Node *n)
|
||||
{
|
||||
if (n->kind == N_IDENT)
|
||||
return n->str;
|
||||
return aprintf(p->a, "%s.%s", flattendotstr(p, n->lhs), n->str);
|
||||
}
|
||||
|
||||
static Node *
|
||||
flattendot(Parser *p, Node *n)
|
||||
{
|
||||
Node *t = newnode(p->a, N_TNAME, n->pos);
|
||||
t->str = flattendotstr(p, n);
|
||||
t->strlen = strlen(t->str);
|
||||
return t;
|
||||
}
|
||||
|
||||
static Node *
|
||||
parsestructlit(Parser *p, Node *typeref)
|
||||
{
|
||||
@@ -636,8 +658,13 @@ parseprimary(Parser *p)
|
||||
n = mr;
|
||||
}
|
||||
/* struct literal: ident '{' ... '}' (only if ident-shaped) */
|
||||
if (p->cur.kind == TK_LBRACE)
|
||||
if (p->cur.kind == TK_LBRACE) {
|
||||
/* #76: bare `Foo{}` keeps the N_IDENT fast-path; a
|
||||
* qualified `pkg.Type{}` (N_DOT chain) flattens first. */
|
||||
if (n->kind == N_DOT)
|
||||
n = flattendot(p, n);
|
||||
return parsestructlit(p, n);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user