Commit 0dadc4fe authored by Russ Cox's avatar Russ Cox

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
parent ed124a97
...@@ -17,8 +17,12 @@ dflag(void) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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: ...@@ -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: ...@@ -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) ...@@ -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) ...@@ -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: ...@@ -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);
......
...@@ -601,7 +601,6 @@ EXTERN int widthptr; ...@@ -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*); ...@@ -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*); ...@@ -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*); ...@@ -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); ...@@ -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);
......
...@@ -351,30 +351,15 @@ varoptsemi: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -621,7 +616,6 @@ for_header:
| range_stmt | range_stmt
{ {
$$ = dorange($1); $$ = dorange($1);
addtotop($$);
} }
for_body: for_body:
......
...@@ -249,7 +249,7 @@ mapindex(Node *n) ...@@ -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;
} }
......
...@@ -517,11 +517,13 @@ appendr(Node *na, Node *nb) ...@@ -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) ...@@ -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) ...@@ -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: ...@@ -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: ...@@ -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;
} }
......
...@@ -247,7 +247,7 @@ sw0(Node *c, Type *place, int arg) ...@@ -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) ...@@ -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: ...@@ -335,7 +335,7 @@ loop:
} }
Node* Node*
newlabel() newlabel(void)
{ {
static int label; static int label;
...@@ -598,7 +598,7 @@ exprswitch(Node *sw) ...@@ -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: ...@@ -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) ...@@ -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: ...@@ -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) ...@@ -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);
......
This diff is collapsed.
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