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)
return 1;
}
/*
* declare (possible list) n of type t.
* append ODCL nodes to *init
*/
void
dodclvar(Node *n, Type *t)
dodclvar(Node *n, Type *t, Node **init)
{
if(n == N)
return;
......@@ -26,7 +30,7 @@ dodclvar(Node *n, Type *t)
if(t != T && (t->etype == TIDEAL || t->etype == TNIL))
fatal("dodclvar %T", t);
for(; n->op == OLIST; n = n->right)
dodclvar(n->left, t);
dodclvar(n->left, t, init);
dowidth(t);
......@@ -39,7 +43,7 @@ dodclvar(Node *n, Type *t)
addvar(n, t, dclcontext);
autoexport(n->sym);
if(funcdepth > 0)
addtop = list(addtop, nod(ODCL, n, N));
*init = list(*init, nod(ODCL, n, N));
}
void
......@@ -1665,13 +1669,14 @@ embedded(Sym *s)
/*
* declare variables from grammar
* new_name_list [type] = expr_list
* new_name_list (type | [type] = expr_list)
*/
Node*
variter(Node *vv, Type *t, Node *ee)
{
Iter viter, eiter;
Node *v, *e, *r, *a;
Type *tv;
vv = rev(vv);
ee = rev(ee);
......@@ -1680,29 +1685,31 @@ variter(Node *vv, Type *t, Node *ee)
e = listfirst(&eiter, &ee);
r = N;
loop:
if(v == N && e == N)
return rev(r);
if(v == N || e == N) {
yyerror("shape error in var dcl");
return rev(r);
}
a = nod(OAS, v, N);
if(t == T) {
gettype(e, a);
defaultlit(e, T);
dodclvar(v, e->type);
} else
dodclvar(v, t);
a->right = e;
while(v != N) {
if(ee != N && e == N) {
yyerror("missing expr in var dcl");
break;
}
r = list(r, a);
a = N;
if(e != N || funcdepth > 0)
a = nod(OAS, v, e);
tv = t;
if(t == T) {
gettype(e, &r);
defaultlit(e, T);
tv = e->type;
}
dodclvar(v, tv, &r);
r = list(r, a);
v = listnext(&viter);
e = listnext(&eiter);
goto loop;
v = listnext(&viter);
if(ee != N)
e = listnext(&eiter);
}
if(e != N)
yyerror("extra expr in var dcl");
return rev(r);
}
/*
......@@ -1713,7 +1720,7 @@ void
constiter(Node *vv, Type *t, Node *cc)
{
Iter viter, citer;
Node *v, *c, n1;
Node *v, *c, *init;
if(cc == N) {
if(t != T)
......@@ -1741,9 +1748,9 @@ loop:
return;
}
memset(&n1, 0, sizeof n1);
gettype(c, &n1);
if(n1.ninit != nil) {
init = N;
gettype(c, &init);
if(init != N) {
// the expression had extra code to run.
// dodclconst is going to print an error
// because the expression isn't constant,
......@@ -1771,7 +1778,7 @@ loop:
Node*
unsafenmagic(Node *l, Node *r)
{
Node *n;
Node *n, *init;
Sym *s;
Type *t, *tr;
long v;
......@@ -1787,8 +1794,9 @@ unsafenmagic(Node *l, Node *r)
if(strcmp(s->package, "unsafe") != 0)
goto no;
init = N;
if(strcmp(s->name, "Sizeof") == 0) {
walktype(r, Erv);
walkexpr(r, Erv, &init);
tr = r->type;
if(r->op == OLITERAL && r->val.ctype == CTSTR)
tr = types[TSTRING];
......@@ -1800,12 +1808,12 @@ unsafenmagic(Node *l, Node *r)
if(strcmp(s->name, "Offsetof") == 0) {
if(r->op != ODOT && r->op != ODOTPTR)
goto no;
walktype(r, Erv);
walkexpr(r, Erv, &init);
v = r->xoffset;
goto yes;
}
if(strcmp(s->name, "Alignof") == 0) {
walktype(r, Erv);
walkexpr(r, Erv, &init);
tr = r->type;
if(r->op == OLITERAL && r->val.ctype == CTSTR)
tr = types[TSTRING];
......@@ -1830,7 +1838,7 @@ no:
return N;
yes:
addtop = N; // any side effects disappear
// any side effects disappear; ignore init
val.ctype = CTINT;
val.u.xval = mal(sizeof(*n->val.u.xval));
mpmovecfix(val.u.xval, v);
......
......@@ -601,7 +601,6 @@ EXTERN int widthptr;
EXTERN Node* retnil;
EXTERN Node* fskel;
EXTERN Node* addtop;
EXTERN Node* typeswvar;
EXTERN char* structpkg;
......@@ -765,7 +764,7 @@ void tempname(Node*, Type*);
Node* staticname(Type*);
int iscomposite(Type*);
Node* callnew(Type*);
Node* saferef(Node*);
Node* saferef(Node*, Node**);
int is64(Type*);
int noconv(Type*, Type*);
......@@ -812,7 +811,7 @@ int simsimtype(Type*);
/*
* dcl.c
*/
void dodclvar(Node*, Type*);
void dodclvar(Node*, Type*, Node**);
Type* dodcltype(Type*);
void updatetype(Type*, Type*);
void dodclconst(Node*, Node*);
......@@ -907,30 +906,29 @@ Type* pkgtype(Sym*);
/*
* walk.c
*/
void addtotop(Node*);
void gettype(Node*, Node*);
void gettype(Node*, Node**);
void walk(Node*);
void walkstate(Node*);
void walktype(Node*, int);
void walkconv(Node*);
void walkstmt(Node*);
void walkexpr(Node*, int, Node**);
void walkconv(Node*, Node**);
void walkas(Node*);
void walkbool(Node*);
void walkswitch(Node*);
void walkselect(Node*);
void walkdot(Node*);
Node* ascompatee(int, Node**, Node**);
Node* ascompatet(int, Node**, Type**, int);
Node* ascompatte(int, Type**, Node**, int);
void walkdot(Node*, Node**);
Node* ascompatee(int, Node**, Node**, Node**);
Node* ascompatet(int, Node**, Type**, int, Node**);
Node* ascompatte(int, Type**, Node**, int, Node**);
int ascompat(Type*, Type*);
Node* prcompat(Node*, int);
Node* nodpanic(int32);
Node* newcompat(Node*);
Node* makecompat(Node*);
Node* stringop(Node*, int);
Node* stringop(Node*, int, Node**);
Type* fixmap(Type*);
Node* mapop(Node*, int);
Node* mapop(Node*, int, Node**);
Type* fixchan(Type*);
Node* chanop(Node*, int);
Node* chanop(Node*, int, Node**);
Node* arrayop(Node*, int);
Node* ifacecvt(Type*, Node*, int);
Node* ifaceop(Node*);
......@@ -938,18 +936,18 @@ int ifaceas(Type*, Type*, int);
int ifaceas1(Type*, Type*, int);
void ifacecheck(Type*, Type*, int, int);
void runifacechecks(void);
Node* convas(Node*);
Node* convas(Node*, Node**);
void arrayconv(Type*, Node*);
Node* colas(Node*, Node*);
Node* colas(Node*, Node*, Node**);
Node* dorange(Node*);
Node* reorder1(Node*);
Node* reorder3(Node*);
Node* reorder4(Node*);
Node* structlit(Node*, Node*);
Node* arraylit(Node*, Node*);
Node* maplit(Node*, Node*);
Node* selectas(Node*, Node*);
Node* old2new(Node*, Type*);
Node* structlit(Node*, Node*, Node**);
Node* arraylit(Node*, Node*, Node**);
Node* maplit(Node*, Node*, Node**);
Node* selectas(Node*, Node*, Node**);
Node* old2new(Node*, Type*, Node**);
void addrescapes(Node*);
void heapmoves(void);
......
......@@ -351,30 +351,15 @@ varoptsemi:
vardcl:
name_list type varoptsemi
{
dodclvar($$, $2);
if(funcdepth == 0) {
$$ = N;
} else {
$$ = nod(OAS, $$, N);
addtotop($$);
}
$$ = variter($1, $2, N);
}
| name_list type varoptsemi '=' expr_list
{
if(addtop != N)
fatal("new_name_list_r type '=' expr_list");
$$ = variter($1, $2, $5);
addtotop($$);
}
| name_list '=' expr_list
{
if(addtop != N)
fatal("new_name_list_r '=' expr_list");
$$ = variter($1, T, $3);
addtotop($$);
}
constdcl:
......@@ -438,16 +423,17 @@ simple_stmt:
}
| expr_list LCOLAS expr_list
{
if(addtop != N)
fatal("expr_list LCOLAS expr_list");
Node *top;
if($3->op == OTYPESW) {
$$ = nod(OTYPESW, $1, $3->left);
break;
}
$$ = colas($$, $3);
top = N;
$$ = colas($$, $3, &top);
$$ = nod(OAS, $$, $3);
$$->colas = 1;
addtotop($$);
$$->ninit = top;
}
| expr LINC
{
......@@ -463,9 +449,12 @@ simple_stmt:
case:
LCASE expr_list ':'
{
Node *top;
// will be converted to OCASE
// right will point to next case
// done in casebody()
top = N;
poptodcl();
if(typeswvar != N && typeswvar->right != N) {
int e;
......@@ -476,14 +465,14 @@ case:
break;
}
if($2->op == OTYPE) {
$$ = old2new(typeswvar->right, $2->type);
$$ = old2new(typeswvar->right, $2->type, &top);
$$ = nod(OTYPESW, $$, N);
$$ = nod(OXCASE, $$, N);
addtotop($$);
$$->ninit = top;
break;
}
e = nerrors;
gettype($2, N);
gettype($2, nil);
// maybe gettype found problems that keep
// e from being valid even outside a type switch.
// only complain if gettype didn't print new errors.
......@@ -497,15 +486,18 @@ case:
}
| LCASE type ':'
{
Node *top;
top = N;
poptodcl();
if(typeswvar == N || typeswvar->right == N) {
yyerror("type case not in a type switch");
$$ = N;
} else
$$ = old2new(typeswvar->right, $2);
$$ = old2new(typeswvar->right, $2, &top);
$$ = nod(OTYPESW, $$, N);
$$ = nod(OXCASE, $$, N);
addtotop($$);
$$->ninit = top;
}
| LCASE name '=' expr ':'
{
......@@ -518,13 +510,16 @@ case:
}
| LCASE name LCOLAS expr ':'
{
Node *top;
// will be converted to OCASE
// right will point to next case
// done in casebody()
poptodcl();
$$ = nod(OAS, selectas($2,$4), $4);
top = N;
$$ = nod(OAS, selectas($2, $4, &top), $4);
$$ = nod(OXCASE, $$, N);
addtotop($$);
$$->ninit = top;
}
| LDEFAULT ':'
{
......@@ -621,7 +616,6 @@ for_header:
| range_stmt
{
$$ = dorange($1);
addtotop($$);
}
for_body:
......
......@@ -249,7 +249,7 @@ mapindex(Node *n)
b = nod(OAS, b, val);
a = nod(OLIST, a, b);
walktype(a, Etop);
walkexpr(a, Etop, nil);
return a;
}
......
......@@ -517,11 +517,13 @@ appendr(Node *na, Node *nb)
Type*
aindex(Node *b, Type *t)
{
Node *top;
Type *r;
int bound;
bound = -1; // open bound
walktype(b, Erv);
top = N;
walkexpr(b, Erv, &top);
if(b != nil) {
switch(consttype(b)) {
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*
saferef(Node *n)
saferef(Node *n, Node **init)
{
Node *l;
Node *r;
Node *a;
switch(n->op) {
case ONAME:
return n;
case ODOT:
l = saferef(n->left);
l = saferef(n->left, init);
if(l == n->left)
return n;
r = nod(OXXX, N, N);
*r = *n;
r->left = l;
walktype(r, Elv);
walkexpr(r, Elv, init);
return r;
case OINDEX:
......@@ -2478,9 +2481,11 @@ saferef(Node *n)
case OIND:
l = nod(OXXX, N, N);
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);
walktype(r, Elv);
walkexpr(r, Elv, init);
return r;
}
fatal("saferef %N", n);
......@@ -2634,11 +2639,13 @@ out:
Node*
adddot(Node *n)
{
Node *top;
Type *t;
Sym *s;
int c, d;
walktype(n->left, Erv);
top = N;
walkexpr(n->left, Erv, &top);
t = n->left->type;
if(t == T)
goto ret;
......@@ -2666,8 +2673,8 @@ out:
n->left->right = newname(dotlist[c].field->sym);
}
ret:
n->ninit = list(addtop, n->ninit);
addtop = N;
if(top != N)
n->ninit = list(top, n->ninit);
return n;
}
......
......@@ -247,7 +247,7 @@ sw0(Node *c, Type *place, int arg)
yyerror("inappropriate case for a type switch");
return T;
}
walktype(c, Erv);
walkexpr(c, Erv, nil);
break;
case OTYPESW:
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
* types to cases and switch
*/
......@@ -335,7 +335,7 @@ loop:
}
Node*
newlabel()
newlabel(void)
{
static int label;
......@@ -598,7 +598,7 @@ exprswitch(Node *sw)
if(sw->ntest->val.u.bval == 0)
arg = Sfalse;
}
walktype(sw->ntest, Erv);
walkexpr(sw->ntest, Erv, &sw->ninit);
/*
* pass 0,1,2,3
......@@ -639,7 +639,7 @@ loop:
if(c0 == C) {
cas = list(cas, def);
sw->nbody->left = rev(cas);
walkstate(sw->nbody);
walkstmt(sw->nbody);
return;
}
......@@ -773,7 +773,7 @@ typeswitch(Node *sw)
yyerror("type switch must have an assignment");
return;
}
walktype(sw->ntest->right, Erv);
walkexpr(sw->ntest->right, Erv, &sw->ninit);
if(!istype(sw->ntest->right->type, TINTER)) {
yyerror("type switch must be on an interface");
return;
......@@ -818,7 +818,7 @@ loop:
if(c0 == C) {
cas = list(cas, def);
sw->nbody->left = rev(cas);
walkstate(sw->nbody);
walkstmt(sw->nbody);
return;
}
......@@ -860,7 +860,7 @@ walkswitch(Node *sw)
* cases have OGOTO into statements.
* both have inserted OBREAK statements
*/
walkstate(sw->ninit);
walkstmt(sw->ninit);
if(sw->ntest == N)
sw->ntest = nodbool(1);
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