Commit 14c63916 authored by Ken Thompson's avatar Ken Thompson

elided dots

R=r
OCL=17601
CL=17601
parent dbabeb1d
...@@ -471,7 +471,7 @@ loop: ...@@ -471,7 +471,7 @@ loop:
if(n->left != N && n->left->op == ONAME) { if(n->left != N && n->left->op == ONAME) {
f->nname = n->left; f->nname = n->left;
f->imbedded = n->imbedded; f->embedded = n->embedded;
} else { } else {
vargen++; vargen++;
snprint(buf, sizeof(buf), "_e%s_%.3ld", filename, vargen); snprint(buf, sizeof(buf), "_e%s_%.3ld", filename, vargen);
...@@ -1150,17 +1150,17 @@ resumecheckwidth(void) ...@@ -1150,17 +1150,17 @@ resumecheckwidth(void)
} }
Node* Node*
imbedded(Sym *s) embedded(Sym *s)
{ {
Node *n; Node *n;
n = newname(lookup(s->name)); n = newname(lookup(s->name));
n = nod(ODCLFIELD, n, N); n = nod(ODCLFIELD, n, N);
n->imbedded = 1; n->embedded = 1;
if(s == S) if(s == S)
return n; return n;
n->type = oldtype(s); n->type = oldtype(s);
if(isptr[n->type->etype]) if(isptr[n->type->etype])
yyerror("imbedded type cannot be a pointer"); yyerror("embedded type cannot be a pointer");
return n; return n;
} }
...@@ -124,7 +124,7 @@ struct Type ...@@ -124,7 +124,7 @@ struct Type
uchar trecur; // to detect loops uchar trecur; // to detect loops
uchar methptr; // 1=direct 2=pointer uchar methptr; // 1=direct 2=pointer
uchar printed; uchar printed;
uchar imbedded; // TFIELD imbedded type uchar embedded; // TFIELD embedded type
// TFUNCT // TFUNCT
uchar thistuple; uchar thistuple;
...@@ -163,7 +163,7 @@ struct Node ...@@ -163,7 +163,7 @@ struct Node
uchar class; // PPARAM, PAUTO, PEXTERN, PSTATIC uchar class; // PPARAM, PAUTO, PEXTERN, PSTATIC
uchar method; // OCALLMETH name uchar method; // OCALLMETH name
uchar iota; // OLITERAL made from iota uchar iota; // OLITERAL made from iota
uchar imbedded; // ODCLFIELD imbedded type uchar embedded; // ODCLFIELD embedded type
// most nodes // most nodes
Node* left; Node* left;
...@@ -673,7 +673,7 @@ void checkarglist(Node*); ...@@ -673,7 +673,7 @@ void checkarglist(Node*);
void checkwidth(Type*); void checkwidth(Type*);
void defercheckwidth(void); void defercheckwidth(void);
void resumecheckwidth(void); void resumecheckwidth(void);
Node* imbedded(Sym*); Node* embedded(Sym*);
/* /*
* export.c * export.c
...@@ -714,7 +714,6 @@ void walkstate(Node*); ...@@ -714,7 +714,6 @@ void walkstate(Node*);
void walktype(Node*, int); void walktype(Node*, int);
void walkas(Node*); void walkas(Node*);
void walkbool(Node*); void walkbool(Node*);
void adddot(Node*);
Type* walkswitch(Node*, Type*(*)(Node*, Type*)); Type* walkswitch(Node*, Type*(*)(Node*, Type*));
int casebody(Node*); int casebody(Node*);
void walkselect(Node*); void walkselect(Node*);
...@@ -747,6 +746,7 @@ Node* arraylit(Node*); ...@@ -747,6 +746,7 @@ Node* arraylit(Node*);
Node* maplit(Node*); Node* maplit(Node*);
Node* selectas(Node*, Node*); Node* selectas(Node*, Node*);
Node* old2new(Node*, Type*); Node* old2new(Node*, Type*);
Node* adddot(Node*);
/* /*
* const.c * const.c
......
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
%type <node> name onew_name new_name new_name_list_r %type <node> name onew_name new_name new_name_list_r
%type <node> vardcl_list_r vardcl Avardcl Bvardcl %type <node> vardcl_list_r vardcl Avardcl Bvardcl
%type <node> interfacedcl_list_r interfacedcl %type <node> interfacedcl_list_r interfacedcl
%type <node> structdcl_list_r structdcl imbed %type <node> structdcl_list_r structdcl embed
%type <node> fnres Afnres Bfnres fnliteral xfndcl fndcl fnbody %type <node> fnres Afnres Bfnres fnliteral xfndcl fndcl fnbody
%type <node> keyexpr_list braced_keyexpr_list keyval_list_r keyval %type <node> keyexpr_list braced_keyexpr_list keyval_list_r keyval
...@@ -820,7 +820,7 @@ pexpr: ...@@ -820,7 +820,7 @@ pexpr:
| pexpr '.' sym2 | pexpr '.' sym2
{ {
$$ = nod(ODOT, $1, newname($3)); $$ = nod(ODOT, $1, newname($3));
adddot($$); $$ = adddot($$);
} }
| pexpr '.' '(' type ')' | pexpr '.' '(' type ')'
{ {
...@@ -1375,21 +1375,21 @@ structdcl: ...@@ -1375,21 +1375,21 @@ structdcl:
$$ = nod(ODCLFIELD, $1, N); $$ = nod(ODCLFIELD, $1, N);
$$->type = $2; $$->type = $2;
} }
| imbed | embed
| '*' imbed | '*' embed
{ {
$$ = $2; $$ = $2;
$$->type = ptrto($$->type); $$->type = ptrto($$->type);
} }
imbed: embed:
LATYPE LATYPE
{ {
$$ = imbedded($1); $$ = embedded($1);
} }
| lpack '.' LATYPE | lpack '.' LATYPE
{ {
$$ = imbedded($3); $$ = embedded($3);
context = nil; context = nil;
} }
......
...@@ -1507,13 +1507,13 @@ void ...@@ -1507,13 +1507,13 @@ void
walkdot(Node *n) walkdot(Node *n)
{ {
Type *t, *f; Type *t, *f;
int d;
if(n->left == N || n->right == N) if(n->left == N || n->right == N)
return; return;
switch(n->op) { switch(n->op) {
case ODOTINTER: case ODOTINTER:
case ODOTMETH: case ODOTMETH:
case ODOTPTR:
return; // already done return; // already done
} }
...@@ -1539,29 +1539,6 @@ walkdot(Node *n) ...@@ -1539,29 +1539,6 @@ walkdot(Node *n)
yyerror("undefined DOT %S on %T", n->right->sym, n->left->type); yyerror("undefined DOT %S on %T", n->right->sym, n->left->type);
} }
int
adddot1(Node *n, int d)
{
return 1;
}
void
adddot(Node *n)
{
int d;
walktype(n->left, Erv);
if(n->left->type == T)
return;
if(n->right->op != ONAME)
return;
for(d=0; d<5; d++)
if(adddot1(n, d))
break;
// dump("adddot", n);
}
Node* Node*
ascompatee(int op, Node **nl, Node **nr) ascompatee(int op, Node **nl, Node **nr)
{ {
...@@ -3244,3 +3221,96 @@ loop: ...@@ -3244,3 +3221,96 @@ loop:
r = listnext(&saver); r = listnext(&saver);
goto loop; goto loop;
} }
int
lookdot0(Sym *s, Type *t)
{
Type *f, *u;
int c;
u = t;
if(isptr[u->etype])
u = u->type;
c = 0;
if(u->etype == TSTRUCT || u->etype == TINTER) {
for(f=u->type; f!=T; f=f->down)
if(f->sym == s)
c++;
}
//BOTCH need method
return c;
}
static Node* dotlist;
int
adddot1(Sym *s, Type *t, int d)
{
Type *f, *u;
int c, a;
if(d == 0)
return lookdot0(s, t);
u = t;
if(isptr[u->etype])
u = u->type;
if(u->etype != TSTRUCT && u->etype != TINTER)
return 0;
c = 0;
for(f=u->type; f!=T; f=f->down) {
if(!f->embedded)
continue;
if(f->sym == S)
continue;
a = adddot1(s, f->type, d-1);
if(a != 0 && c == 0) {
dotlist = nod(ODOT, dotlist, N);
dotlist->type = f;
}
c += a;
}
return c;
}
Node*
adddot(Node *n)
{
Type *t;
Sym *s;
Node *l;
int c, d;
walktype(n->left, Erv);
t = n->left->type;
if(t == T)
return n;
if(n->right->op != ONAME)
return n;
s = n->right->sym;
if(s == S)
return n;
dotlist = N;
for(d=0; d<5; d++) {
c = adddot1(s, t, d);
if(c > 0)
goto out;
}
return n;
out:
if(c > 1)
yyerror("ambiguous DOT reference %S", s);
// rebuild elided dots
for(l=dotlist; l!=N; l=l->left) {
n = nod(ODOT, n, n->right);
n->left->right = newname(l->type->sym);
}
return n;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment