1
0
mirror of https://github.com/golang/go synced 2024-10-03 06:21:21 -06:00

cleanup in preparation for new scoping.

walkstate -> walkstmt
walktype -> walkexpr; stmts moved to walkstmt

walktype and friends have a final Node **init
argument that can have side effects appended,
making it more explicit when they do and do not happen.
this replaces the old global addtop and addtotop.

delete switch map and interface conversion cases
(dropped from the language months ago).

R=ken
OCL=31465
CL=31468
This commit is contained in:
Russ Cox 2009-07-10 16:29:26 -07:00
parent ed124a971e
commit 0dadc4fe4f
7 changed files with 412 additions and 494 deletions

View File

@ -17,8 +17,12 @@ dflag(void)
return 1; return 1;
} }
/*
* declare (possible list) n of type t.
* append ODCL nodes to *init
*/
void void
dodclvar(Node *n, Type *t) dodclvar(Node *n, Type *t, Node **init)
{ {
if(n == N) if(n == N)
return; return;
@ -26,7 +30,7 @@ dodclvar(Node *n, Type *t)
if(t != T && (t->etype == TIDEAL || t->etype == TNIL)) if(t != T && (t->etype == TIDEAL || t->etype == TNIL))
fatal("dodclvar %T", t); fatal("dodclvar %T", t);
for(; n->op == OLIST; n = n->right) for(; n->op == OLIST; n = n->right)
dodclvar(n->left, t); dodclvar(n->left, t, init);
dowidth(t); dowidth(t);
@ -39,7 +43,7 @@ dodclvar(Node *n, Type *t)
addvar(n, t, dclcontext); addvar(n, t, dclcontext);
autoexport(n->sym); autoexport(n->sym);
if(funcdepth > 0) if(funcdepth > 0)
addtop = list(addtop, nod(ODCL, n, N)); *init = list(*init, nod(ODCL, n, N));
} }
void void
@ -1665,13 +1669,14 @@ embedded(Sym *s)
/* /*
* declare variables from grammar * declare variables from grammar
* new_name_list [type] = expr_list * new_name_list (type | [type] = expr_list)
*/ */
Node* Node*
variter(Node *vv, Type *t, Node *ee) variter(Node *vv, Type *t, Node *ee)
{ {
Iter viter, eiter; Iter viter, eiter;
Node *v, *e, *r, *a; Node *v, *e, *r, *a;
Type *tv;
vv = rev(vv); vv = rev(vv);
ee = rev(ee); ee = rev(ee);
@ -1680,29 +1685,31 @@ variter(Node *vv, Type *t, Node *ee)
e = listfirst(&eiter, &ee); e = listfirst(&eiter, &ee);
r = N; r = N;
loop: while(v != N) {
if(v == N && e == N) if(ee != N && e == N) {
return rev(r); yyerror("missing expr in var dcl");
break;
if(v == N || e == N) {
yyerror("shape error in var dcl");
return rev(r);
} }
a = nod(OAS, v, N); a = N;
if(e != N || funcdepth > 0)
a = nod(OAS, v, e);
tv = t;
if(t == T) { if(t == T) {
gettype(e, a); gettype(e, &r);
defaultlit(e, T); defaultlit(e, T);
dodclvar(v, e->type); tv = e->type;
} else }
dodclvar(v, t); dodclvar(v, tv, &r);
a->right = e;
r = list(r, a); r = list(r, a);
v = listnext(&viter); v = listnext(&viter);
if(ee != N)
e = listnext(&eiter); e = listnext(&eiter);
goto loop; }
if(e != N)
yyerror("extra expr in var dcl");
return rev(r);
} }
/* /*
@ -1713,7 +1720,7 @@ void
constiter(Node *vv, Type *t, Node *cc) constiter(Node *vv, Type *t, Node *cc)
{ {
Iter viter, citer; Iter viter, citer;
Node *v, *c, n1; Node *v, *c, *init;
if(cc == N) { if(cc == N) {
if(t != T) if(t != T)
@ -1741,9 +1748,9 @@ loop:
return; return;
} }
memset(&n1, 0, sizeof n1); init = N;
gettype(c, &n1); gettype(c, &init);
if(n1.ninit != nil) { if(init != N) {
// the expression had extra code to run. // the expression had extra code to run.
// dodclconst is going to print an error // dodclconst is going to print an error
// because the expression isn't constant, // because the expression isn't constant,
@ -1771,7 +1778,7 @@ loop:
Node* Node*
unsafenmagic(Node *l, Node *r) unsafenmagic(Node *l, Node *r)
{ {
Node *n; Node *n, *init;
Sym *s; Sym *s;
Type *t, *tr; Type *t, *tr;
long v; long v;
@ -1787,8 +1794,9 @@ unsafenmagic(Node *l, Node *r)
if(strcmp(s->package, "unsafe") != 0) if(strcmp(s->package, "unsafe") != 0)
goto no; goto no;
init = N;
if(strcmp(s->name, "Sizeof") == 0) { if(strcmp(s->name, "Sizeof") == 0) {
walktype(r, Erv); walkexpr(r, Erv, &init);
tr = r->type; tr = r->type;
if(r->op == OLITERAL && r->val.ctype == CTSTR) if(r->op == OLITERAL && r->val.ctype == CTSTR)
tr = types[TSTRING]; tr = types[TSTRING];
@ -1800,12 +1808,12 @@ unsafenmagic(Node *l, Node *r)
if(strcmp(s->name, "Offsetof") == 0) { if(strcmp(s->name, "Offsetof") == 0) {
if(r->op != ODOT && r->op != ODOTPTR) if(r->op != ODOT && r->op != ODOTPTR)
goto no; goto no;
walktype(r, Erv); walkexpr(r, Erv, &init);
v = r->xoffset; v = r->xoffset;
goto yes; goto yes;
} }
if(strcmp(s->name, "Alignof") == 0) { if(strcmp(s->name, "Alignof") == 0) {
walktype(r, Erv); walkexpr(r, Erv, &init);
tr = r->type; tr = r->type;
if(r->op == OLITERAL && r->val.ctype == CTSTR) if(r->op == OLITERAL && r->val.ctype == CTSTR)
tr = types[TSTRING]; tr = types[TSTRING];
@ -1830,7 +1838,7 @@ no:
return N; return N;
yes: yes:
addtop = N; // any side effects disappear // any side effects disappear; ignore init
val.ctype = CTINT; val.ctype = CTINT;
val.u.xval = mal(sizeof(*n->val.u.xval)); val.u.xval = mal(sizeof(*n->val.u.xval));
mpmovecfix(val.u.xval, v); mpmovecfix(val.u.xval, v);

View File

@ -601,7 +601,6 @@ EXTERN int widthptr;
EXTERN Node* retnil; EXTERN Node* retnil;
EXTERN Node* fskel; EXTERN Node* fskel;
EXTERN Node* addtop;
EXTERN Node* typeswvar; EXTERN Node* typeswvar;
EXTERN char* structpkg; EXTERN char* structpkg;
@ -765,7 +764,7 @@ void tempname(Node*, Type*);
Node* staticname(Type*); Node* staticname(Type*);
int iscomposite(Type*); int iscomposite(Type*);
Node* callnew(Type*); Node* callnew(Type*);
Node* saferef(Node*); Node* saferef(Node*, Node**);
int is64(Type*); int is64(Type*);
int noconv(Type*, Type*); int noconv(Type*, Type*);
@ -812,7 +811,7 @@ int simsimtype(Type*);
/* /*
* dcl.c * dcl.c
*/ */
void dodclvar(Node*, Type*); void dodclvar(Node*, Type*, Node**);
Type* dodcltype(Type*); Type* dodcltype(Type*);
void updatetype(Type*, Type*); void updatetype(Type*, Type*);
void dodclconst(Node*, Node*); void dodclconst(Node*, Node*);
@ -907,30 +906,29 @@ Type* pkgtype(Sym*);
/* /*
* walk.c * walk.c
*/ */
void addtotop(Node*); void gettype(Node*, Node**);
void gettype(Node*, Node*);
void walk(Node*); void walk(Node*);
void walkstate(Node*); void walkstmt(Node*);
void walktype(Node*, int); void walkexpr(Node*, int, Node**);
void walkconv(Node*); void walkconv(Node*, Node**);
void walkas(Node*); void walkas(Node*);
void walkbool(Node*); void walkbool(Node*);
void walkswitch(Node*); void walkswitch(Node*);
void walkselect(Node*); void walkselect(Node*);
void walkdot(Node*); void walkdot(Node*, Node**);
Node* ascompatee(int, Node**, Node**); Node* ascompatee(int, Node**, Node**, Node**);
Node* ascompatet(int, Node**, Type**, int); Node* ascompatet(int, Node**, Type**, int, Node**);
Node* ascompatte(int, Type**, Node**, int); Node* ascompatte(int, Type**, Node**, int, Node**);
int ascompat(Type*, Type*); int ascompat(Type*, Type*);
Node* prcompat(Node*, int); Node* prcompat(Node*, int);
Node* nodpanic(int32); Node* nodpanic(int32);
Node* newcompat(Node*); Node* newcompat(Node*);
Node* makecompat(Node*); Node* makecompat(Node*);
Node* stringop(Node*, int); Node* stringop(Node*, int, Node**);
Type* fixmap(Type*); Type* fixmap(Type*);
Node* mapop(Node*, int); Node* mapop(Node*, int, Node**);
Type* fixchan(Type*); Type* fixchan(Type*);
Node* chanop(Node*, int); Node* chanop(Node*, int, Node**);
Node* arrayop(Node*, int); Node* arrayop(Node*, int);
Node* ifacecvt(Type*, Node*, int); Node* ifacecvt(Type*, Node*, int);
Node* ifaceop(Node*); Node* ifaceop(Node*);
@ -938,18 +936,18 @@ int ifaceas(Type*, Type*, int);
int ifaceas1(Type*, Type*, int); int ifaceas1(Type*, Type*, int);
void ifacecheck(Type*, Type*, int, int); void ifacecheck(Type*, Type*, int, int);
void runifacechecks(void); void runifacechecks(void);
Node* convas(Node*); Node* convas(Node*, Node**);
void arrayconv(Type*, Node*); void arrayconv(Type*, Node*);
Node* colas(Node*, Node*); Node* colas(Node*, Node*, Node**);
Node* dorange(Node*); Node* dorange(Node*);
Node* reorder1(Node*); Node* reorder1(Node*);
Node* reorder3(Node*); Node* reorder3(Node*);
Node* reorder4(Node*); Node* reorder4(Node*);
Node* structlit(Node*, Node*); Node* structlit(Node*, Node*, Node**);
Node* arraylit(Node*, Node*); Node* arraylit(Node*, Node*, Node**);
Node* maplit(Node*, Node*); Node* maplit(Node*, Node*, Node**);
Node* selectas(Node*, Node*); Node* selectas(Node*, Node*, Node**);
Node* old2new(Node*, Type*); Node* old2new(Node*, Type*, Node**);
void addrescapes(Node*); void addrescapes(Node*);
void heapmoves(void); void heapmoves(void);

View File

@ -351,30 +351,15 @@ varoptsemi:
vardcl: vardcl:
name_list type varoptsemi name_list type varoptsemi
{ {
dodclvar($$, $2); $$ = variter($1, $2, N);
if(funcdepth == 0) {
$$ = N;
} else {
$$ = nod(OAS, $$, N);
addtotop($$);
}
} }
| name_list type varoptsemi '=' expr_list | name_list type varoptsemi '=' expr_list
{ {
if(addtop != N)
fatal("new_name_list_r type '=' expr_list");
$$ = variter($1, $2, $5); $$ = variter($1, $2, $5);
addtotop($$);
} }
| name_list '=' expr_list | name_list '=' expr_list
{ {
if(addtop != N)
fatal("new_name_list_r '=' expr_list");
$$ = variter($1, T, $3); $$ = variter($1, T, $3);
addtotop($$);
} }
constdcl: constdcl:
@ -438,16 +423,17 @@ simple_stmt:
} }
| expr_list LCOLAS expr_list | expr_list LCOLAS expr_list
{ {
if(addtop != N) Node *top;
fatal("expr_list LCOLAS expr_list");
if($3->op == OTYPESW) { if($3->op == OTYPESW) {
$$ = nod(OTYPESW, $1, $3->left); $$ = nod(OTYPESW, $1, $3->left);
break; break;
} }
$$ = colas($$, $3); top = N;
$$ = colas($$, $3, &top);
$$ = nod(OAS, $$, $3); $$ = nod(OAS, $$, $3);
$$->colas = 1; $$->colas = 1;
addtotop($$); $$->ninit = top;
} }
| expr LINC | expr LINC
{ {
@ -463,9 +449,12 @@ simple_stmt:
case: case:
LCASE expr_list ':' LCASE expr_list ':'
{ {
Node *top;
// will be converted to OCASE // will be converted to OCASE
// right will point to next case // right will point to next case
// done in casebody() // done in casebody()
top = N;
poptodcl(); poptodcl();
if(typeswvar != N && typeswvar->right != N) { if(typeswvar != N && typeswvar->right != N) {
int e; int e;
@ -476,14 +465,14 @@ case:
break; break;
} }
if($2->op == OTYPE) { if($2->op == OTYPE) {
$$ = old2new(typeswvar->right, $2->type); $$ = old2new(typeswvar->right, $2->type, &top);
$$ = nod(OTYPESW, $$, N); $$ = nod(OTYPESW, $$, N);
$$ = nod(OXCASE, $$, N); $$ = nod(OXCASE, $$, N);
addtotop($$); $$->ninit = top;
break; break;
} }
e = nerrors; e = nerrors;
gettype($2, N); gettype($2, nil);
// maybe gettype found problems that keep // maybe gettype found problems that keep
// e from being valid even outside a type switch. // e from being valid even outside a type switch.
// only complain if gettype didn't print new errors. // only complain if gettype didn't print new errors.
@ -497,15 +486,18 @@ case:
} }
| LCASE type ':' | LCASE type ':'
{ {
Node *top;
top = N;
poptodcl(); poptodcl();
if(typeswvar == N || typeswvar->right == N) { if(typeswvar == N || typeswvar->right == N) {
yyerror("type case not in a type switch"); yyerror("type case not in a type switch");
$$ = N; $$ = N;
} else } else
$$ = old2new(typeswvar->right, $2); $$ = old2new(typeswvar->right, $2, &top);
$$ = nod(OTYPESW, $$, N); $$ = nod(OTYPESW, $$, N);
$$ = nod(OXCASE, $$, N); $$ = nod(OXCASE, $$, N);
addtotop($$); $$->ninit = top;
} }
| LCASE name '=' expr ':' | LCASE name '=' expr ':'
{ {
@ -518,13 +510,16 @@ case:
} }
| LCASE name LCOLAS expr ':' | LCASE name LCOLAS expr ':'
{ {
Node *top;
// will be converted to OCASE // will be converted to OCASE
// right will point to next case // right will point to next case
// done in casebody() // done in casebody()
poptodcl(); poptodcl();
$$ = nod(OAS, selectas($2,$4), $4); top = N;
$$ = nod(OAS, selectas($2, $4, &top), $4);
$$ = nod(OXCASE, $$, N); $$ = nod(OXCASE, $$, N);
addtotop($$); $$->ninit = top;
} }
| LDEFAULT ':' | LDEFAULT ':'
{ {
@ -621,7 +616,6 @@ for_header:
| range_stmt | range_stmt
{ {
$$ = dorange($1); $$ = dorange($1);
addtotop($$);
} }
for_body: for_body:

View File

@ -249,7 +249,7 @@ mapindex(Node *n)
b = nod(OAS, b, val); b = nod(OAS, b, val);
a = nod(OLIST, a, b); a = nod(OLIST, a, b);
walktype(a, Etop); walkexpr(a, Etop, nil);
return a; return a;
} }

View File

@ -517,11 +517,13 @@ appendr(Node *na, Node *nb)
Type* Type*
aindex(Node *b, Type *t) aindex(Node *b, Type *t)
{ {
Node *top;
Type *r; Type *r;
int bound; int bound;
bound = -1; // open bound bound = -1; // open bound
walktype(b, Erv); top = N;
walkexpr(b, Erv, &top);
if(b != nil) { if(b != nil) {
switch(consttype(b)) { switch(consttype(b)) {
default: default:
@ -2452,25 +2454,26 @@ staticname(Type *t)
} }
/* /*
* return side effect-free n, moving side effects to top. * return side effect-free n, appending side effects to init.
*/ */
Node* Node*
saferef(Node *n) saferef(Node *n, Node **init)
{ {
Node *l; Node *l;
Node *r; Node *r;
Node *a;
switch(n->op) { switch(n->op) {
case ONAME: case ONAME:
return n; return n;
case ODOT: case ODOT:
l = saferef(n->left); l = saferef(n->left, init);
if(l == n->left) if(l == n->left)
return n; return n;
r = nod(OXXX, N, N); r = nod(OXXX, N, N);
*r = *n; *r = *n;
r->left = l; r->left = l;
walktype(r, Elv); walkexpr(r, Elv, init);
return r; return r;
case OINDEX: case OINDEX:
@ -2478,9 +2481,11 @@ saferef(Node *n)
case OIND: case OIND:
l = nod(OXXX, N, N); l = nod(OXXX, N, N);
tempname(l, ptrto(n->type)); tempname(l, ptrto(n->type));
addtop = list(addtop, nod(OAS, l, nod(OADDR, n, N))); a = nod(OAS, l, nod(OADDR, n, N));
walkexpr(a, Etop, init);
*init = list(*init, a);
r = nod(OIND, l, N); r = nod(OIND, l, N);
walktype(r, Elv); walkexpr(r, Elv, init);
return r; return r;
} }
fatal("saferef %N", n); fatal("saferef %N", n);
@ -2634,11 +2639,13 @@ out:
Node* Node*
adddot(Node *n) adddot(Node *n)
{ {
Node *top;
Type *t; Type *t;
Sym *s; Sym *s;
int c, d; int c, d;
walktype(n->left, Erv); top = N;
walkexpr(n->left, Erv, &top);
t = n->left->type; t = n->left->type;
if(t == T) if(t == T)
goto ret; goto ret;
@ -2666,8 +2673,8 @@ out:
n->left->right = newname(dotlist[c].field->sym); n->left->right = newname(dotlist[c].field->sym);
} }
ret: ret:
n->ninit = list(addtop, n->ninit); if(top != N)
addtop = N; n->ninit = list(top, n->ninit);
return n; return n;
} }

View File

@ -247,7 +247,7 @@ sw0(Node *c, Type *place, int arg)
yyerror("inappropriate case for a type switch"); yyerror("inappropriate case for a type switch");
return T; return T;
} }
walktype(c, Erv); walkexpr(c, Erv, nil);
break; break;
case OTYPESW: case OTYPESW:
if(arg != Stype) if(arg != Stype)
@ -298,7 +298,7 @@ sw3(Node *c, Type *place, int arg)
} }
/* /*
* over all cases, call paramenter function. * over all cases, call parameter function.
* four passes of these are used to allocate * four passes of these are used to allocate
* types to cases and switch * types to cases and switch
*/ */
@ -335,7 +335,7 @@ loop:
} }
Node* Node*
newlabel() newlabel(void)
{ {
static int label; static int label;
@ -598,7 +598,7 @@ exprswitch(Node *sw)
if(sw->ntest->val.u.bval == 0) if(sw->ntest->val.u.bval == 0)
arg = Sfalse; arg = Sfalse;
} }
walktype(sw->ntest, Erv); walkexpr(sw->ntest, Erv, &sw->ninit);
/* /*
* pass 0,1,2,3 * pass 0,1,2,3
@ -639,7 +639,7 @@ loop:
if(c0 == C) { if(c0 == C) {
cas = list(cas, def); cas = list(cas, def);
sw->nbody->left = rev(cas); sw->nbody->left = rev(cas);
walkstate(sw->nbody); walkstmt(sw->nbody);
return; return;
} }
@ -773,7 +773,7 @@ typeswitch(Node *sw)
yyerror("type switch must have an assignment"); yyerror("type switch must have an assignment");
return; return;
} }
walktype(sw->ntest->right, Erv); walkexpr(sw->ntest->right, Erv, &sw->ninit);
if(!istype(sw->ntest->right->type, TINTER)) { if(!istype(sw->ntest->right->type, TINTER)) {
yyerror("type switch must be on an interface"); yyerror("type switch must be on an interface");
return; return;
@ -818,7 +818,7 @@ loop:
if(c0 == C) { if(c0 == C) {
cas = list(cas, def); cas = list(cas, def);
sw->nbody->left = rev(cas); sw->nbody->left = rev(cas);
walkstate(sw->nbody); walkstmt(sw->nbody);
return; return;
} }
@ -860,7 +860,7 @@ walkswitch(Node *sw)
* cases have OGOTO into statements. * cases have OGOTO into statements.
* both have inserted OBREAK statements * both have inserted OBREAK statements
*/ */
walkstate(sw->ninit); walkstmt(sw->ninit);
if(sw->ntest == N) if(sw->ntest == N)
sw->ntest = nodbool(1); sw->ntest = nodbool(1);
casebody(sw); casebody(sw);

File diff suppressed because it is too large Load Diff