another step toward eliminating forward declarations.

introduce NodeList* type in compiler to replace OLIST.
this clarifies where lists can and cannot occur.
list append and concatenation are now cheap.
the _r rules are gone from yacc.
rev and unrev are gone.
no more lists of lists.

the representation of assignments is a bit clunkier.
split into OAS (1=1) and OAS2 (2 or more on one side).

delete dead chanrecv3 code.

delay construction of func types.

R=ken
OCL=31745
CL=31762
This commit is contained in:
Russ Cox 2009-07-17 01:00:44 -07:00
parent 9b475bd2a4
commit e52e9ca82e
18 changed files with 1782 additions and 1943 deletions

View File

@ -26,7 +26,7 @@ compile(Node *fn)
throwreturn = sysfunc("throwreturn"); throwreturn = sysfunc("throwreturn");
} }
if(fn->nbody == N) if(fn->nbody == nil)
return; return;
// set up domain for labels // set up domain for labels
@ -42,7 +42,7 @@ compile(Node *fn)
t = structfirst(&save, getoutarg(curfn->type)); t = structfirst(&save, getoutarg(curfn->type));
while(t != T) { while(t != T) {
if(t->nname != N) if(t->nname != N)
curfn->nbody = list(nod(OAS, t->nname, N), curfn->nbody); curfn->nbody = concat(list1(nod(OAS, t->nname, N)), curfn->nbody);
t = structnext(&save); t = structnext(&save);
} }
} }
@ -65,8 +65,8 @@ compile(Node *fn)
ptxt = gins(ATEXT, curfn->nname, &nod1); ptxt = gins(ATEXT, curfn->nname, &nod1);
afunclit(&ptxt->from); afunclit(&ptxt->from);
gen(curfn->enter); genlist(curfn->enter);
gen(curfn->nbody); genlist(curfn->nbody);
checklabels(); checklabels();
if(curfn->type->outtuple != 0) if(curfn->type->outtuple != 0)
@ -326,7 +326,7 @@ cgen_aret(Node *n, Node *res)
void void
cgen_ret(Node *n) cgen_ret(Node *n)
{ {
gen(n->left); // copy out args genlist(n->list); // copy out args
if(hasdefer) if(hasdefer)
ginscall(deferreturn, 0); ginscall(deferreturn, 0);
gins(ARET, N, N); gins(ARET, N, N);

View File

@ -26,7 +26,7 @@ compile(Node *fn)
throwreturn = sysfunc("throwreturn"); throwreturn = sysfunc("throwreturn");
} }
if(fn->nbody == N) if(fn->nbody == nil)
return; return;
// set up domain for labels // set up domain for labels
@ -42,7 +42,7 @@ compile(Node *fn)
t = structfirst(&save, getoutarg(curfn->type)); t = structfirst(&save, getoutarg(curfn->type));
while(t != T) { while(t != T) {
if(t->nname != N) if(t->nname != N)
curfn->nbody = list(nod(OAS, t->nname, N), curfn->nbody); curfn->nbody = concat(list1(nod(OAS, t->nname, N)), curfn->nbody);
t = structnext(&save); t = structnext(&save);
} }
} }
@ -66,8 +66,8 @@ compile(Node *fn)
afunclit(&ptxt->from); afunclit(&ptxt->from);
ginit(); ginit();
gen(curfn->enter); genlist(curfn->enter);
gen(curfn->nbody); genlist(curfn->nbody);
gclean(); gclean();
checklabels(); checklabels();
@ -164,7 +164,7 @@ cgen_callinter(Node *n, Node *res, int proc)
i = &tmpi; i = &tmpi;
} }
gen(n->right); // args genlist(n->list); // assign the args
regalloc(&nodr, types[tptr], res); regalloc(&nodr, types[tptr], res);
regalloc(&nodo, types[tptr], &nodr); regalloc(&nodo, types[tptr], &nodr);
@ -214,7 +214,7 @@ cgen_call(Node *n, int proc)
cgen(n->left, &afun); cgen(n->left, &afun);
} }
gen(n->right); // assign the args genlist(n->list); // assign the args
t = n->left->type; t = n->left->type;
setmaxarg(t); setmaxarg(t);
@ -322,7 +322,7 @@ cgen_aret(Node *n, Node *res)
void void
cgen_ret(Node *n) cgen_ret(Node *n)
{ {
gen(n->left); // copy out args genlist(n->list); // copy out args
if(hasdefer) if(hasdefer)
ginscall(deferreturn, 0); ginscall(deferreturn, 0);
gins(ARET, N, N); gins(ARET, N, N);

View File

@ -24,7 +24,7 @@ compile(Node *fn)
throwreturn = sysfunc("throwreturn"); throwreturn = sysfunc("throwreturn");
} }
if(fn->nbody == N) if(fn->nbody == nil)
return; return;
// set up domain for labels // set up domain for labels
@ -40,7 +40,7 @@ compile(Node *fn)
t = structfirst(&save, getoutarg(curfn->type)); t = structfirst(&save, getoutarg(curfn->type));
while(t != T) { while(t != T) {
if(t->nname != N) if(t->nname != N)
curfn->nbody = list(nod(OAS, t->nname, N), curfn->nbody); curfn->nbody = concat(list1(nod(OAS, t->nname, N)), curfn->nbody);
t = structnext(&save); t = structnext(&save);
} }
} }
@ -64,8 +64,8 @@ compile(Node *fn)
afunclit(&ptxt->from); afunclit(&ptxt->from);
ginit(); ginit();
gen(curfn->enter); genlist(curfn->enter);
gen(curfn->nbody); genlist(curfn->nbody);
gclean(); gclean();
checklabels(); checklabels();
@ -200,7 +200,7 @@ cgen_callinter(Node *n, Node *res, int proc)
i = &tmpi; i = &tmpi;
} }
gen(n->right); // args genlist(n->list); // assign the args
// Can regalloc now; i is known to be addable, // Can regalloc now; i is known to be addable,
// so the agen will be easy. // so the agen will be easy.
@ -255,7 +255,7 @@ cgen_call(Node *n, int proc)
cgen(n->left, &afun); cgen(n->left, &afun);
} }
gen(n->right); // assign the args genlist(n->list); // assign the args
t = n->left->type; t = n->left->type;
setmaxarg(t); setmaxarg(t);
@ -360,7 +360,7 @@ cgen_aret(Node *n, Node *res)
void void
cgen_ret(Node *n) cgen_ret(Node *n)
{ {
gen(n->left); // copy out args genlist(n->list); // copy out args
if(hasdefer) if(hasdefer)
ginscall(deferreturn, 0); ginscall(deferreturn, 0);
gins(ARET, N, N); gins(ARET, N, N);

View File

@ -307,7 +307,7 @@ typeinit(void)
mpatoflt(minfltval[TFLOAT64], "-1.7976931348623157e+308"); mpatoflt(minfltval[TFLOAT64], "-1.7976931348623157e+308");
/* for walk to use in error messages */ /* for walk to use in error messages */
types[TFUNC] = functype(N, N, N); types[TFUNC] = functype(N, nil, nil);
/* types used in front end */ /* types used in front end */
// types[TNIL] got set early in lexinit // types[TNIL] got set early in lexinit

View File

@ -53,7 +53,6 @@ char *sysimport =
"func sys.newchan (elemsize int, elemalg int, hint int) (hchan chan any)\n" "func sys.newchan (elemsize int, elemalg int, hint int) (hchan chan any)\n"
"func sys.chanrecv1 (hchan <-chan any) (elem any)\n" "func sys.chanrecv1 (hchan <-chan any) (elem any)\n"
"func sys.chanrecv2 (hchan <-chan any) (elem any, pres bool)\n" "func sys.chanrecv2 (hchan <-chan any) (elem any, pres bool)\n"
"func sys.chanrecv3 (hchan <-chan any, elem *any) (pres bool)\n"
"func sys.chansend1 (hchan chan<- any, elem any)\n" "func sys.chansend1 (hchan chan<- any, elem any)\n"
"func sys.chansend2 (hchan chan<- any, elem any) (pres bool)\n" "func sys.chansend2 (hchan chan<- any, elem any) (pres bool)\n"
"func sys.closechan (hchan any)\n" "func sys.closechan (hchan any)\n"

View File

@ -22,16 +22,13 @@ dflag(void)
* append ODCL nodes to *init * append ODCL nodes to *init
*/ */
void void
dodclvar(Node *n, Type *t, Node **init) dodclvar(Node *n, Type *t, NodeList **init)
{ {
if(n == N) if(n == N)
return; return;
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)
dodclvar(n->left, t, init);
dowidth(t); dowidth(t);
// in case of type checking error, // in case of type checking error,
@ -51,10 +48,6 @@ dodclconst(Node *n, Node *e)
{ {
if(n == N) if(n == N)
return; return;
for(; n->op == OLIST; n=n->right)
dodclconst(n, e);
addconst(n, e, dclcontext); addconst(n, e, dclcontext);
autoexport(n->sym); autoexport(n->sym);
} }
@ -179,18 +172,6 @@ updatetype(Type *n, Type *t)
/* /*
* return nelem of list * return nelem of list
*/ */
int
listcount(Node *n)
{
int v;
Iter s;
v = 0;
for(n = listfirst(&s, &n); n != N; n = listnext(&s))
v++;
return v;
}
int int
structcount(Type *t) structcount(Type *t)
{ {
@ -208,19 +189,24 @@ structcount(Type *t)
* into a type * into a type
*/ */
Type* Type*
functype(Node *this, Node *in, Node *out) functype(Node *this, NodeList *in, NodeList *out)
{ {
Type *t; Type *t;
NodeList *rcvr;
t = typ(TFUNC); t = typ(TFUNC);
t->type = dostruct(this, TFUNC); rcvr = nil;
if(this)
rcvr = list1(this);
t->type = dostruct(rcvr, TFUNC);
t->type->down = dostruct(out, TFUNC); t->type->down = dostruct(out, TFUNC);
t->type->down->down = dostruct(in, TFUNC); t->type->down->down = dostruct(in, TFUNC);
t->thistuple = listcount(this); if(this)
t->outtuple = listcount(out); t->thistuple = 1;
t->intuple = listcount(in); t->outtuple = count(out);
t->intuple = count(in);
checkwidth(t); checkwidth(t);
return t; return t;
@ -367,9 +353,9 @@ addmethod(Node *n, Type *t, int local)
} }
if(d == T) if(d == T)
stotype(n, 0, &pa->method); stotype(list1(n), 0, &pa->method);
else else
stotype(n, 0, &d->down); stotype(list1(n), 0, &d->down);
if(dflag()) if(dflag())
print("method %S of type %T\n", sf, pa); print("method %S of type %T\n", sf, pa);
@ -545,13 +531,14 @@ funclit0(Type *t)
} }
Node* Node*
funclit1(Type *type, Node *body) funclit1(Type *type, NodeList *body)
{ {
Node *func; Node *func;
Node *a, *d, *f, *n, *args, *clos, *in, *out; Node *a, *d, *f, *n, *clos;
Type *ft, *t; Type *ft, *t;
Iter save; Iter save;
int narg, shift; int narg, shift;
NodeList *args, *l, *in, *out;
popdcl(); popdcl();
func = funclit; func = funclit;
@ -559,15 +546,15 @@ funclit1(Type *type, Node *body)
// build up type of func f that we're going to compile. // build up type of func f that we're going to compile.
// as we referred to variables from the outer function, // as we referred to variables from the outer function,
// we accumulated a list of PHEAP names in func. // we accumulated a list of PHEAP names in func->cvars.
//
narg = 0; narg = 0;
if(func->cvars == N) if(func->cvars == nil)
ft = type; ft = type;
else { else {
// add PHEAP versions as function arguments. // add PHEAP versions as function arguments.
in = N; in = nil;
for(a=listfirst(&save, &func->cvars); a; a=listnext(&save)) { for(l=func->cvars; l; l=l->next) {
a = l->n;
d = nod(ODCLFIELD, a, N); d = nod(ODCLFIELD, a, N);
d->type = ptrto(a->type); d->type = ptrto(a->type);
in = list(in, d); in = list(in, d);
@ -612,10 +599,9 @@ funclit1(Type *type, Node *body)
a->xoffset += shift; a->xoffset += shift;
} }
} }
in = rev(in);
// out arguments // out arguments
out = N; out = nil;
for(t=structfirst(&save, getoutarg(type)); t; t=structnext(&save)) { for(t=structfirst(&save, getoutarg(type)); t; t=structnext(&save)) {
d = nod(ODCLFIELD, t->nname, N); d = nod(ODCLFIELD, t->nname, N);
d->type = t->type; d->type = t->type;
@ -628,7 +614,6 @@ funclit1(Type *type, Node *body)
a->xoffset += shift; a->xoffset += shift;
} }
} }
out = rev(out);
ft = functype(N, in, out); ft = functype(N, in, out);
ft->outnamed = type->outnamed; ft->outnamed = type->outnamed;
@ -645,35 +630,35 @@ funclit1(Type *type, Node *body)
n = nod(ODCLFUNC, N, N); n = nod(ODCLFUNC, N, N);
n->nname = f; n->nname = f;
n->type = ft; n->type = ft;
if(body == N) if(body == nil)
body = nod(ORETURN, N, N); body = list1(nod(ORETURN, N, N));
n->nbody = body; n->nbody = body;
compile(n); compile(n);
funcdepth--; funcdepth--;
autodcl = func->dcl; autodcl = func->dcl;
// if there's no closure, we can use f directly // if there's no closure, we can use f directly
if(func->cvars == N) if(func->cvars == nil)
return f; return f;
// build up type for this instance of the closure func. // build up type for this instance of the closure func.
in = N; in = nil;
d = nod(ODCLFIELD, N, N); // siz d = nod(ODCLFIELD, N, N); // siz
d->type = types[TINT]; d->type = types[TINT];
in = list(in, d); in = list(in, d);
d = nod(ODCLFIELD, N, N); // f d = nod(ODCLFIELD, N, N); // f
d->type = ft; d->type = ft;
in = list(in, d); in = list(in, d);
for(a=listfirst(&save, &func->cvars); a; a=listnext(&save)) { for(l=func->cvars; l; l=l->next) {
a = l->n;
d = nod(ODCLFIELD, N, N); // arg d = nod(ODCLFIELD, N, N); // arg
d->type = ptrto(a->type); d->type = ptrto(a->type);
in = list(in, d); in = list(in, d);
} }
in = rev(in);
d = nod(ODCLFIELD, N, N); d = nod(ODCLFIELD, N, N);
d->type = type; d->type = type;
out = d; out = list1(d);
clos = syslook("closure", 1); clos = syslook("closure", 1);
clos->type = functype(N, in, out); clos->type = functype(N, in, out);
@ -681,47 +666,42 @@ funclit1(Type *type, Node *body)
// literal expression is sys.closure(siz, f, arg0, arg1, ...) // literal expression is sys.closure(siz, f, arg0, arg1, ...)
// which builds a function that calls f after filling in arg0, // which builds a function that calls f after filling in arg0,
// arg1, ... for the PHEAP arguments above. // arg1, ... for the PHEAP arguments above.
args = N; args = nil;
if(narg*widthptr > 100) if(narg*widthptr > 100)
yyerror("closure needs too many variables; runtime will reject it"); yyerror("closure needs too many variables; runtime will reject it");
a = nodintconst(narg*widthptr); a = nodintconst(narg*widthptr);
args = list(args, a); // siz args = list(args, a); // siz
args = list(args, f); // f args = list(args, f); // f
for(a=listfirst(&save, &func->cvars); a; a=listnext(&save)) { for(l=func->cvars; l; l=l->next) {
a = l->n;
d = oldname(a->sym); d = oldname(a->sym);
addrescapes(d); addrescapes(d);
args = list(args, nod(OADDR, d, N)); args = list(args, nod(OADDR, d, N));
} }
args = rev(args);
return nod(OCALL, clos, args); n = nod(OCALL, clos, N);
n->list = args;
return n;
} }
/* /*
* turn a parsed struct into a type * turn a parsed struct into a type
*/ */
Type** Type**
stotype(Node *n, int et, Type **t) stotype(NodeList *l, int et, Type **t)
{ {
Type *f, *t1; Type *f, *t1;
Iter save;
Strlit *note; Strlit *note;
int lno; int lno;
Node *init; NodeList *init;
Node *n;
init = N; init = nil;
lno = lineno; lno = lineno;
for(n = listfirst(&save, &n); n != N; n = listnext(&save)) { for(; l; l=l->next) {
note = nil; n = l->n;
lineno = n->lineno; lineno = n->lineno;
if(n->op == OLIST) { note = nil;
// recursive because it can be lists of lists
t = stotype(n, et, t);
continue;
}
if(n->op != ODCLFIELD) if(n->op != ODCLFIELD)
fatal("stotype: oops %N\n", n); fatal("stotype: oops %N\n", n);
@ -803,7 +783,7 @@ stotype(Node *n, int et, Type **t)
} }
Type* Type*
dostruct(Node *n, int et) dostruct(NodeList *l, int et)
{ {
Type *t; Type *t;
int funarg; int funarg;
@ -820,7 +800,7 @@ dostruct(Node *n, int et)
} }
t = typ(et); t = typ(et);
t->funarg = funarg; t->funarg = funarg;
stotype(n, et, &t->type); stotype(l, et, &t->type);
if(!funarg) if(!funarg)
checkwidth(t); checkwidth(t);
return t; return t;
@ -1218,7 +1198,7 @@ oldname(Sym *s)
n->closure = c; n->closure = c;
c->closure = n; c->closure = n;
if(funclit != N) if(funclit != N)
funclit->cvars = list(c, funclit->cvars); funclit->cvars = list(funclit->cvars, c);
} }
// return ref to closure var, not original // return ref to closure var, not original
return n->closure; return n->closure;
@ -1265,45 +1245,15 @@ oldtype(Sym *s)
} }
/* /*
* n is a node with a name (or a reversed list of them). * n is a node with a name.
* make it an anonymous declaration of that name's type.
*/
Node*
nametoanondcl(Node *na)
{
Node **l, *n;
Type *t;
for(l=&na; (n=*l)->op == OLIST; l=&n->left)
n->right = nametoanondcl(n->right);
n = n->sym->def;
if(n == N || n->op != OTYPE || (t = n->type) == T) {
yyerror("%S is not a type", n->sym);
t = typ(TINT32);
}
n = nod(ODCLFIELD, N, N);
n->type = t;
*l = n;
return na;
}
/*
* n is a node with a name (or a reversed list of them).
* make it a declaration of the given type. * make it a declaration of the given type.
*/ */
Node* Node*
nametodcl(Node *na, Type *t) nametodcl(Node *n, Type *t)
{ {
Node **l, *n;
for(l=&na; (n=*l)->op == OLIST; l=&n->left)
n->right = nametodcl(n->right, t);
n = nod(ODCLFIELD, n, N); n = nod(ODCLFIELD, n, N);
n->type = t; n->type = t;
*l = n; return n;
return na;
} }
/* /*
@ -1320,22 +1270,16 @@ anondcl(Type *t)
} }
static Node* static Node*
findtype(Node *n) findtype(NodeList *l)
{ {
Node *r; for(; l; l=l->next)
if(l->n->op == OKEY)
for(r=n; r->op==OLIST; r=r->right) return l->n->right;
if(r->left->op == OKEY)
return r->left->right;
if(r->op == OKEY)
return r->right;
if(n->op == OLIST)
n = n->left;
return N; return N;
} }
static Node* static Node*
xanondcl(Node *nt, int dddok) xanondcl(Node *nt)
{ {
Node *n; Node *n;
Type *t; Type *t;
@ -1347,13 +1291,11 @@ xanondcl(Node *nt, int dddok)
} }
n = nod(ODCLFIELD, N, N); n = nod(ODCLFIELD, N, N);
n->type = t; n->type = t;
if(!dddok && t->etype == TDDD)
yyerror("only last argument can have type ...");
return n; return n;
} }
static Node* static Node*
namedcl(Node *nn, Node *nt, int dddok) namedcl(Node *nn, Node *nt)
{ {
Node *n; Node *n;
Type *t; Type *t;
@ -1362,7 +1304,7 @@ namedcl(Node *nn, Node *nt, int dddok)
nn = nn->left; nn = nn->left;
if(nn->op == OTYPE && nn->sym == S) { if(nn->op == OTYPE && nn->sym == S) {
yyerror("cannot mix anonymous %T with named arguments", nn->type); yyerror("cannot mix anonymous %T with named arguments", nn->type);
return xanondcl(nn, dddok); return xanondcl(nn);
} }
t = types[TINT32]; t = types[TINT32];
if(nt == N) if(nt == N)
@ -1373,41 +1315,39 @@ namedcl(Node *nn, Node *nt, int dddok)
t = nt->type; t = nt->type;
n = nod(ODCLFIELD, newname(nn->sym), N); n = nod(ODCLFIELD, newname(nn->sym), N);
n->type = t; n->type = t;
if(!dddok && t->etype == TDDD)
yyerror("only last argument can have type ...");
return n; return n;
} }
/* /*
* check that the list of declarations is either all anonymous or all named * check that the list of declarations is either all anonymous or all named
*/ */
Node* NodeList*
checkarglist(Node *n) checkarglist(NodeList *all)
{ {
int named;
Node *r; Node *r;
Node **l; NodeList *l;
// check for all anonymous named = 0;
for(r=n; r->op==OLIST; r=r->right) for(l=all; l; l=l->next) {
if(r->left->op == OKEY) if(l->n->op == OKEY) {
goto named; named = 1;
if(r->op == OKEY) break;
goto named; }
}
// all anonymous - add names for(l=all; l; l=l->next) {
for(l=&n; (r=*l)->op==OLIST; l=&r->right) if(named)
r->left = xanondcl(r->left, 0); l->n = namedcl(l->n, findtype(l));
*l = xanondcl(r, 1); else
return n; l->n = xanondcl(l->n);
if(l->next != nil) {
r = l->n;
named: if(r != N && r->type != T && r->type->etype == TDDD)
// otherwise, each run of names ends in a type. yyerror("only last argument can have type ...");
// add a type to each one that needs one. }
for(l=&n; (r=*l)->op==OLIST; l=&r->right) }
r->left = namedcl(r->left, findtype(r), 0); return all;
*l = namedcl(r, findtype(r), 1);
return n;
} }
/* /*
@ -1429,13 +1369,13 @@ named:
* } * }
*/ */
int int
anyinit(Node *n) anyinit(NodeList *n)
{ {
uint32 h; uint32 h;
Sym *s; Sym *s;
// are there any init statements // are there any init statements
if(n != N) if(n != nil)
return 1; return 1;
// is this main // is this main
@ -1463,10 +1403,11 @@ anyinit(Node *n)
} }
void void
fninit(Node *n) fninit(NodeList *n)
{ {
Node *gatevar; Node *gatevar;
Node *a, *b, *fn, *r; Node *a, *b, *fn;
NodeList *r;
uint32 h; uint32 h;
Sym *s, *initsym; Sym *s, *initsym;
@ -1478,7 +1419,7 @@ fninit(Node *n)
if(!anyinit(n)) if(!anyinit(n))
return; return;
r = N; r = nil;
// (1) // (1)
snprint(namebuf, sizeof(namebuf), "initdone·%s", filename); snprint(namebuf, sizeof(namebuf), "initdone·%s", filename);
@ -1500,7 +1441,7 @@ fninit(Node *n)
fn = nod(ODCLFUNC, N, N); fn = nod(ODCLFUNC, N, N);
initsym = lookup(namebuf); initsym = lookup(namebuf);
fn->nname = newname(initsym); fn->nname = newname(initsym);
fn->type = functype(N, N, N); fn->type = functype(N, nil, nil);
funchdr(fn); funchdr(fn);
// (3) // (3)
@ -1511,8 +1452,8 @@ fninit(Node *n)
// (4) // (4)
b = nod(OIF, N, N); b = nod(OIF, N, N);
b->ntest = nod(OEQ, gatevar, nodintconst(2)); b->ntest = nod(OEQ, gatevar, nodintconst(2));
b->nbody = nod(ORETURN, N, N); b->nbody = list1(nod(ORETURN, N, N));
a->nbody = b; a->nbody = list1(b);
// (5) // (5)
b = syslook("throwinit", 0); b = syslook("throwinit", 0);
@ -1540,7 +1481,7 @@ fninit(Node *n)
} }
// (8) // (8)
r = list(r, initfix(n)); r = concat(r, initfix(n));
// (9) // (9)
// could check that it is fn of no args/returns // could check that it is fn of no args/returns
@ -1562,7 +1503,7 @@ fninit(Node *n)
exportsym(fn->nname->sym); exportsym(fn->nname->sym);
fn->nbody = rev(r); fn->nbody = r;
//dump("b", fn); //dump("b", fn);
//dump("r", fn->nbody); //dump("r", fn->nbody);
@ -1679,26 +1620,28 @@ embedded(Sym *s)
* declare variables from grammar * declare variables from grammar
* new_name_list (type | [type] = expr_list) * new_name_list (type | [type] = expr_list)
*/ */
Node* NodeList*
variter(Node *vv, Type *t, Node *ee) variter(NodeList *vl, Type *t, NodeList *el)
{ {
Iter viter, eiter; int doexpr;
Node *v, *e, *r, *a; Node *v, *e, *a;
Type *tv; Type *tv;
NodeList *r;
vv = rev(vv); r = nil;
ee = rev(ee); doexpr = el != nil;
for(; vl; vl=vl->next) {
v = listfirst(&viter, &vv); if(doexpr) {
e = listfirst(&eiter, &ee); if(el == nil) {
r = N; yyerror("missing expr in var dcl");
break;
while(v != N) { }
if(ee != N && e == N) { e = el->n;
yyerror("missing expr in var dcl"); el = el->next;
break; } else
} e = N;
v = vl->n;
a = N; a = N;
if(e != N || funcdepth > 0) if(e != N || funcdepth > 0)
a = nod(OAS, v, e); a = nod(OAS, v, e);
@ -1709,15 +1652,12 @@ variter(Node *vv, Type *t, Node *ee)
tv = e->type; tv = e->type;
} }
dodclvar(v, tv, &r); dodclvar(v, tv, &r);
r = list(r, a); if(a != N)
r = list(r, a);
v = listnext(&viter);
if(ee != N)
e = listnext(&eiter);
} }
if(e != N) if(el != nil)
yyerror("extra expr in var dcl"); yyerror("extra expr in var dcl");
return rev(r); return r;
} }
/* /*
@ -1725,56 +1665,51 @@ variter(Node *vv, Type *t, Node *ee)
* new_name_list [[type] = expr_list] * new_name_list [[type] = expr_list]
*/ */
void void
constiter(Node *vv, Type *t, Node *cc) constiter(NodeList *vl, Type *t, NodeList *cl)
{ {
Iter viter, citer; Node *v, *c;
Node *v, *c, *init; NodeList *init;
if(cc == N) { if(cl == nil) {
if(t != T) if(t != T)
yyerror("constdcl cannot have type without expr"); yyerror("constdcl cannot have type without expr");
cc = lastconst; cl = lastconst;
t = lasttype; t = lasttype;
} else {
lastconst = cl;
lasttype = t;
} }
lastconst = cc; cl = listtreecopy(cl);
lasttype = t;
vv = rev(vv);
cc = rev(treecopy(cc));
v = listfirst(&viter, &vv); for(; vl; vl=vl->next) {
c = listfirst(&citer, &cc); if(cl == nil) {
yyerror("missing expr in const dcl");
break;
}
c = cl->n;
cl = cl->next;
loop: init = nil;
if(v == N && c == N) { gettype(c, &init);
iota += 1; if(init != nil) {
return; // the expression had extra code to run.
// dodclconst is going to print an error
// because the expression isn't constant,
// but out of paranoia, bump nerrors so
// that compile cannot succeed accidentally
nerrors++;
}
if(t != T)
convlit(c, t);
if(t == T)
lasttype = c->type;
v = vl->n;
dodclconst(v, c);
} }
if(cl != nil)
if(v == N || c == N) { yyerror("extra expr in const dcl");
yyerror("shape error in const dcl"); iota += 1;
iota += 1;
return;
}
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,
// but out of paranoia, bump nerrors so
// that compile cannot succeed accidentally
nerrors++;
}
if(t != T)
convlit(c, t);
if(t == T)
lasttype = c->type;
dodclconst(v, c);
v = listnext(&viter);
c = listnext(&citer);
goto loop;
} }
/* /*
@ -1784,27 +1719,28 @@ loop:
* rewrite with a constant * rewrite with a constant
*/ */
Node* Node*
unsafenmagic(Node *l, Node *r) unsafenmagic(Node *fn, NodeList *args)
{ {
Node *n, *init; Node *r, *n;
Sym *s; Sym *s;
Type *t, *tr; Type *t, *tr;
long v; long v;
Val val; Val val;
if(l == N || r == N) if(fn == N || fn->op != ONAME || (s = fn->sym) == S)
goto no;
if(l->op != ONAME)
goto no;
s = l->sym;
if(s == S)
goto no; goto no;
if(strcmp(s->package, "unsafe") != 0) if(strcmp(s->package, "unsafe") != 0)
goto no; goto no;
init = N; if(args == nil) {
yyerror("missing argument for %S", s);
goto no;
}
r = args->n;
n = nod(OLITERAL, N, N);
if(strcmp(s->name, "Sizeof") == 0) { if(strcmp(s->name, "Sizeof") == 0) {
walkexpr(r, Erv, &init); walkexpr(r, Erv, &n->ninit);
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];
@ -1816,12 +1752,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;
walkexpr(r, Erv, &init); walkexpr(r, Erv, &n->ninit);
v = r->xoffset; v = r->xoffset;
goto yes; goto yes;
} }
if(strcmp(s->name, "Alignof") == 0) { if(strcmp(s->name, "Alignof") == 0) {
walkexpr(r, Erv, &init); walkexpr(r, Erv, &n->ninit);
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];
@ -1846,6 +1782,8 @@ no:
return N; return N;
yes: yes:
if(args->next != nil)
yyerror("extra arguments for %S", s);
// any side effects disappear; ignore init // 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));

View File

@ -127,6 +127,13 @@ findlab(Sym *s)
/* /*
* compile statements * compile statements
*/ */
void
genlist(NodeList *l)
{
for(; l; l=l->next)
gen(l->n);
}
void void
gen(Node *n) gen(Node *n)
{ {
@ -137,13 +144,12 @@ gen(Node *n)
lno = setlineno(n); lno = setlineno(n);
loop:
if(n == N) if(n == N)
goto ret; goto ret;
p3 = pc; // save pc for loop labels p3 = pc; // save pc for loop labels
if(n->ninit) if(n->ninit)
gen(n->ninit); genlist(n->ninit);
setlineno(n); setlineno(n);
@ -152,11 +158,6 @@ loop:
fatal("gen: unknown op %N", n); fatal("gen: unknown op %N", n);
break; break;
case OLIST:
gen(n->left);
n = n->right;
goto loop;
case OCASE: case OCASE:
case OFALL: case OFALL:
case OXCASE: case OXCASE:
@ -164,6 +165,10 @@ loop:
case OEMPTY: case OEMPTY:
break; break;
case OBLOCK:
genlist(n->list);
break;
case OLABEL: case OLABEL:
newlab(OLABEL, n->left->sym); newlab(OLABEL, n->left->sym);
break; break;
@ -232,10 +237,10 @@ loop:
gen(n->nincr); // contin: incr gen(n->nincr); // contin: incr
patch(p1, pc); // test: patch(p1, pc); // test:
if(n->ntest != N) if(n->ntest != N)
if(n->ntest->ninit != N) if(n->ntest->ninit != nil)
gen(n->ntest->ninit); genlist(n->ntest->ninit);
bgen(n->ntest, 0, breakpc); // if(!test) goto break bgen(n->ntest, 0, breakpc); // if(!test) goto break
gen(n->nbody); // body genlist(n->nbody); // body
gjmp(continpc); gjmp(continpc);
patch(breakpc, pc); // done: patch(breakpc, pc); // done:
continpc = scontin; continpc = scontin;
@ -247,13 +252,13 @@ loop:
p2 = gjmp(P); // p2: goto else p2 = gjmp(P); // p2: goto else
patch(p1, pc); // test: patch(p1, pc); // test:
if(n->ntest != N) if(n->ntest != N)
if(n->ntest->ninit != N) if(n->ntest->ninit != nil)
gen(n->ntest->ninit); genlist(n->ntest->ninit);
bgen(n->ntest, 0, p2); // if(!test) goto p2 bgen(n->ntest, 0, p2); // if(!test) goto p2
gen(n->nbody); // then genlist(n->nbody); // then
p3 = gjmp(P); // goto done p3 = gjmp(P); // goto done
patch(p2, pc); // else: patch(p2, pc); // else:
gen(n->nelse); // else genlist(n->nelse); // else
patch(p3, pc); // done: patch(p3, pc); // done:
break; break;
@ -272,7 +277,7 @@ loop:
} }
patch(p1, pc); // test: patch(p1, pc); // test:
gen(n->nbody); // switch(test) body genlist(n->nbody); // switch(test) body
patch(breakpc, pc); // done: patch(breakpc, pc); // done:
breakpc = sbreak; breakpc = sbreak;
break; break;
@ -292,7 +297,7 @@ loop:
} }
patch(p1, pc); // test: patch(p1, pc); // test:
gen(n->nbody); // select() body genlist(n->nbody); // select() body
patch(breakpc, pc); // done: patch(breakpc, pc); // done:
breakpc = sbreak; breakpc = sbreak;
break; break;
@ -432,12 +437,6 @@ cgen_as(Node *nl, Node *nr)
iszer = 0; iszer = 0;
if(nr == N || isnil(nr)) { if(nr == N || isnil(nr)) {
if(nl->op == OLIST) {
cgen_as(nl->left, nr);
cgen_as(nl->right, nr);
return;
}
// externals and heaps should already be clear // externals and heaps should already be clear
if(nr == N) { if(nr == N) {
if(nl->class == PEXTERN) if(nl->class == PEXTERN)

View File

@ -129,6 +129,7 @@ struct Val
typedef struct Sym Sym; typedef struct Sym Sym;
typedef struct Node Node; typedef struct Node Node;
typedef struct NodeList NodeList;
typedef struct Type Type; typedef struct Type Type;
typedef struct Dcl Dcl; typedef struct Dcl Dcl;
@ -198,24 +199,26 @@ struct Node
Node* left; Node* left;
Node* right; Node* right;
Type* type; Type* type;
NodeList* list;
NodeList* rlist;
// for-body // for-body
Node* ninit; NodeList* ninit;
Node* ntest; Node* ntest;
Node* nincr; Node* nincr;
Node* nbody; NodeList* nbody;
// if-body // if-body
Node* nelse; NodeList* nelse;
// cases // cases
Node* ncase; Node* ncase;
// func // func
Node* nname; Node* nname;
Node* enter; NodeList* enter;
Node* exit; NodeList* exit;
Node* cvars; // closure params NodeList* cvars; // closure params
Dcl* dcl; // outer autodcl Dcl* dcl; // outer autodcl
// OLITERAL/OREGISTER // OLITERAL/OREGISTER
@ -242,6 +245,13 @@ struct Node
}; };
#define N ((Node*)0) #define N ((Node*)0)
struct NodeList
{
Node* n;
NodeList* next;
NodeList* end;
};
struct Sym struct Sym
{ {
ushort block; // blocknumber to catch redeclaration ushort block; // blocknumber to catch redeclaration
@ -308,12 +318,12 @@ enum
ODCL, ODCL,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, ODOT, ODOTPTR, ODOTMETH, ODOTINTER,
ODCLFUNC, ODCLFIELD, ODCLARG, ODCLFUNC, ODCLFIELD, ODCLARG,
OLIST, OCMP, OPTR, OARRAY, ORANGE, OCMP, OPTR, OARRAY, ORANGE,
ORETURN, OFOR, OIF, OSWITCH, ODEFER, ORETURN, OFOR, OIF, OSWITCH, ODEFER,
OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL, OAS, OAS2, OASOP, OCASE, OXCASE, OFALL, OXFALL,
OGOTO, OPROC, OMAKE, ONEW, OEMPTY, OSELECT, OGOTO, OPROC, OMAKE, ONEW, OEMPTY, OSELECT,
OLEN, OCAP, OPANIC, OPANICN, OPRINT, OPRINTN, OTYPEOF, OLEN, OCAP, OPANIC, OPANICN, OPRINT, OPRINTN, OTYPEOF,
OCLOSE, OCLOSED, OCLOSE, OCLOSED, OBLOCK,
OOROR, OOROR,
OANDAND, OANDAND,
@ -590,7 +600,7 @@ EXTERN int statuniqgen; // name generator for static temps
EXTERN int loophack; EXTERN int loophack;
EXTERN uint32 iota; EXTERN uint32 iota;
EXTERN Node* lastconst; EXTERN NodeList* lastconst;
EXTERN Type* lasttype; EXTERN Type* lasttype;
EXTERN int32 vargen; EXTERN int32 vargen;
EXTERN int32 exportgen; EXTERN int32 exportgen;
@ -605,7 +615,6 @@ EXTERN int maxround;
EXTERN int widthptr; EXTERN int widthptr;
EXTERN Node* retnil; EXTERN Node* retnil;
EXTERN Node* fskel;
EXTERN Node* typeswvar; EXTERN Node* typeswvar;
@ -726,15 +735,12 @@ void linehist(char*, int32, int);
int32 setlineno(Node*); int32 setlineno(Node*);
Node* nod(int, Node*, Node*); Node* nod(int, Node*, Node*);
Node* nodlit(Val); Node* nodlit(Val);
Node* list(Node*, Node*);
Type* typ(int); Type* typ(int);
Dcl* dcl(void); Dcl* dcl(void);
int algtype(Type*); int algtype(Type*);
Node* rev(Node*);
Node* unrev(Node*);
Node* appendr(Node*, Node*);
void dodump(Node*, int); void dodump(Node*, int);
void dump(char*, Node*); void dump(char*, Node*);
void dumplist(char*, NodeList*);
Type* aindex(Node*, Type*); Type* aindex(Node*, Type*);
int isnil(Node*); int isnil(Node*);
int isptrto(Type*, int); int isptrto(Type*, int);
@ -762,17 +768,23 @@ Node* nodbool(int);
void ullmancalc(Node*); void ullmancalc(Node*);
void badtype(int, Type*, Type*); void badtype(int, Type*, Type*);
Type* ptrto(Type*); Type* ptrto(Type*);
Node* cleanidlist(Node*); NodeList* cleanidlist(NodeList*);
Node* syslook(char*, int); Node* syslook(char*, int);
Node* treecopy(Node*); Node* treecopy(Node*);
NodeList* listtreecopy(NodeList*);
int isselect(Node*); int isselect(Node*);
void tempname(Node*, Type*); 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**); Node* saferef(Node*, NodeList**);
int is64(Type*); int is64(Type*);
int noconv(Type*, Type*); int noconv(Type*, Type*);
NodeList* list1(Node*);
NodeList* list(NodeList*, Node*);
NodeList* concat(NodeList*, NodeList*);
int count(NodeList*);
Node* liststmt(NodeList*);
Type** getthis(Type*); Type** getthis(Type*);
Type** getoutarg(Type*); Type** getoutarg(Type*);
@ -782,8 +794,6 @@ Type* getthisx(Type*);
Type* getoutargx(Type*); Type* getoutargx(Type*);
Type* getinargx(Type*); Type* getinargx(Type*);
Node* listfirst(Iter*, Node**);
Node* listnext(Iter*);
Type* structfirst(Iter*, Type**); Type* structfirst(Iter*, Type**);
Type* structnext(Iter*); Type* structnext(Iter*);
Type* funcfirst(Iter*, Type*); Type* funcfirst(Iter*, Type*);
@ -817,18 +827,17 @@ int simsimtype(Type*);
/* /*
* dcl.c * dcl.c
*/ */
void dodclvar(Node*, Type*, Node**); void dodclvar(Node*, Type*, NodeList**);
Type* dodcltype(Type*); Type* dodcltype(Type*);
void updatetype(Type*, Type*); void updatetype(Type*, Type*);
void dodclconst(Node*, Node*); void dodclconst(Node*, Node*);
void defaultlit(Node*, Type*); void defaultlit(Node*, Type*);
void defaultlit2(Node*, Node*); void defaultlit2(Node*, Node*);
int listcount(Node*);
int structcount(Type*); int structcount(Type*);
void addmethod(Node*, Type*, int); void addmethod(Node*, Type*, int);
Node* methodname(Node*, Type*); Node* methodname(Node*, Type*);
Sym* methodsym(Sym*, Type*); Sym* methodsym(Sym*, Type*);
Type* functype(Node*, Node*, Node*); Type* functype(Node*, NodeList*, NodeList*);
char* thistypenam(Node*); char* thistypenam(Node*);
void funcnam(Type*, char*); void funcnam(Type*, char*);
Node* renameinit(Node*); Node* renameinit(Node*);
@ -836,8 +845,8 @@ void funchdr(Node*);
void funcargs(Type*); void funcargs(Type*);
void funcbody(Node*); void funcbody(Node*);
Node* typenod(Type*); Node* typenod(Type*);
Type* dostruct(Node*, int); Type* dostruct(NodeList*, int);
Type** stotype(Node*, int, Type**); Type** stotype(NodeList*, int, Type**);
Type* sortinter(Type*); Type* sortinter(Type*);
void markdcl(void); void markdcl(void);
void popdcl(void); void popdcl(void);
@ -855,27 +864,26 @@ Node* newname(Sym*);
Node* oldname(Sym*); Node* oldname(Sym*);
Type* newtype(Sym*); Type* newtype(Sym*);
Type* oldtype(Sym*); Type* oldtype(Sym*);
void fninit(Node*); void fninit(NodeList*);
Node* nametoanondcl(Node*);
Node* nametodcl(Node*, Type*); Node* nametodcl(Node*, Type*);
Node* anondcl(Type*); Node* anondcl(Type*);
Node* checkarglist(Node*); NodeList* checkarglist(NodeList*);
void checkwidth(Type*); void checkwidth(Type*);
void defercheckwidth(void); void defercheckwidth(void);
void resumecheckwidth(void); void resumecheckwidth(void);
Node* embedded(Sym*); Node* embedded(Sym*);
Node* variter(Node*, Type*, Node*); NodeList* variter(NodeList*, Type*, NodeList*);
void constiter(Node*, Type*, Node*); void constiter(NodeList*, Type*, NodeList*);
void funclit0(Type*); void funclit0(Type*);
Node* funclit1(Type*, Node*); Node* funclit1(Type*, NodeList*);
Node* unsafenmagic(Node*, Node*); Node* unsafenmagic(Node*, NodeList*);
/* /*
* sinit.c * sinit.c
*/ */
Node* initfix(Node*); NodeList* initfix(NodeList*);
/* /*
* export.c * export.c
@ -912,30 +920,33 @@ Type* pkgtype(Sym*);
/* /*
* walk.c * walk.c
*/ */
void gettype(Node*, Node**); void gettype(Node*, NodeList**);
void walk(Node*); void walk(Node*);
void walkstmt(Node*); void walkstmt(Node*);
void walkexpr(Node*, int, Node**); void walkstmtlist(NodeList*);
void walkconv(Node*, Node**); void walkexpr(Node*, int, NodeList**);
void walkdottype(Node*, Node**); void walkexprlist(NodeList*, int, NodeList**);
void walkconv(Node*, NodeList**);
void walkdottype(Node*, NodeList**);
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*, Node**); void walkdot(Node*, NodeList**);
Node* ascompatee(int, Node**, Node**, Node**); Node* ascompatee1(int, Node*, Node*, NodeList**);
Node* ascompatet(int, Node**, Type**, int, Node**); NodeList* ascompatee(int, NodeList*, NodeList*, NodeList**);
Node* ascompatte(int, Type**, Node**, int, Node**); NodeList* ascompatet(int, NodeList*, Type**, int, NodeList**);
NodeList* ascompatte(int, Type**, NodeList*, int, NodeList**);
int ascompat(Type*, Type*); int ascompat(Type*, Type*);
Node* prcompat(Node*, int); Node* prcompat(NodeList*, int, int);
Node* nodpanic(int32); Node* nodpanic(int32);
Node* newcompat(Node*); Node* newcompat(Node*);
Node* makecompat(Node*); Node* makecompat(Node*);
Node* stringop(Node*, int, Node**); Node* stringop(Node*, int, NodeList**);
Type* fixmap(Type*); Type* fixmap(Type*);
Node* mapop(Node*, int, Node**); Node* mapop(Node*, int, NodeList**);
Type* fixchan(Type*); Type* fixchan(Type*);
Node* chanop(Node*, int, Node**); Node* chanop(Node*, int, NodeList**);
Node* arrayop(Node*, int); Node* arrayop(Node*, int);
Node* ifacecvt(Type*, Node*, int); Node* ifacecvt(Type*, Node*, int);
Node* ifaceop(Node*); Node* ifaceop(Node*);
@ -943,18 +954,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**); Node* convas(Node*, NodeList**);
void arrayconv(Type*, Node*); void arrayconv(Type*, Node*);
Node* colas(Node*, Node*, Node**); Node* colas(NodeList*, NodeList*);
Node* dorange(Node*); Node* dorange(Node*);
Node* reorder1(Node*); NodeList* reorder1(NodeList*);
Node* reorder3(Node*); NodeList* reorder3(NodeList*);
Node* reorder4(Node*); NodeList* reorder4(NodeList*);
Node* structlit(Node*, Node*, Node**); Node* structlit(Node*, Node*, NodeList**);
Node* arraylit(Node*, Node*, Node**); Node* arraylit(Node*, Node*, NodeList**);
Node* maplit(Node*, Node*, Node**); Node* maplit(Node*, Node*, NodeList**);
Node* selectas(Node*, Node*, Node**); Node* selectas(Node*, Node*, NodeList**);
Node* old2new(Node*, Type*, Node**); Node* old2new(Node*, Type*, NodeList**);
void addrescapes(Node*); void addrescapes(Node*);
void heapmoves(void); void heapmoves(void);
@ -1044,6 +1055,7 @@ void cgen_proc(Node *n, int proc);
void checklabels(void); void checklabels(void);
Label* findlab(Sym *s); Label* findlab(Sym *s);
void gen(Node *n); void gen(Node *n);
void genlist(NodeList *l);
void newlab(int op, Sym *s); void newlab(int op, Sym *s);
Node* sysfunc(char *name); Node* sysfunc(char *name);
Plist* newplist(void); Plist* newplist(void);

File diff suppressed because it is too large Load Diff

View File

@ -94,12 +94,6 @@ main(int argc, char *argv[])
typelist = mal(sizeof(*typelist)); typelist = mal(sizeof(*typelist));
typelist->back = typelist; typelist->back = typelist;
// function field skeleton
fskel = nod(OLIST, N, nod(OLIST, N, N));
fskel->left = nod(ODCLFIELD, N, N);
fskel->right->left = nod(ODCLFIELD, N, N);
fskel->right->right = nod(ODCLFIELD, N, N);
nerrors = 0; nerrors = 0;
yyparse(); yyparse();
runifacechecks(); runifacechecks();

View File

@ -90,10 +90,11 @@ lsort(Sig *l, int(*f)(Sig*, Sig*))
static Type* static Type*
methodfunc(Type *f) methodfunc(Type *f)
{ {
Node *in, *out, *d; NodeList *in, *out;
Node *d;
Type *t; Type *t;
in = N; in = nil;
if(!isifacemethod(f)) { if(!isifacemethod(f)) {
d = nod(ODCLFIELD, N, N); d = nod(ODCLFIELD, N, N);
d->type = getthisx(f->type)->type->type; d->type = getthisx(f->type)->type->type;
@ -105,14 +106,14 @@ methodfunc(Type *f)
in = list(in, d); in = list(in, d);
} }
out = N; out = nil;
for(t=getoutargx(f->type)->type; t; t=t->down) { for(t=getoutargx(f->type)->type; t; t=t->down) {
d = nod(ODCLFIELD, N, N); d = nod(ODCLFIELD, N, N);
d->type = t->type; d->type = t->type;
out = list(out, d); out = list(out, d);
} }
return functype(N, rev(in), rev(out)); return functype(N, in, out);
} }
/* /*

View File

@ -6,7 +6,7 @@
static struct static struct
{ {
Node* list; NodeList* list;
Node* mapname; Node* mapname;
Type* type; Type* type;
} xxx; } xxx;
@ -59,35 +59,25 @@ typeclass(Type *t)
} }
void void
initlin(Node* n) initlin(NodeList *l)
{ {
Node *n;
loop: for(; l; l=l->next) {
if(n == N) n = l->n;
return; initlin(n->ninit);
initlin(n->ninit); n->ninit = nil;
switch(n->op) {
default:
print("o = %O\n", n->op);
n->ninit = N;
xxx.list = list(xxx.list, n); xxx.list = list(xxx.list, n);
break; switch(n->op) {
default:
print("o = %O\n", n->op);
break;
case OCALL: case OCALL:
// call to mapassign1 // call to mapassign1
n->ninit = N; case OAS:
xxx.list = list(xxx.list, n); break;
break; }
case OAS:
n->ninit = N;
xxx.list = list(xxx.list, n);
break;
case OLIST:
initlin(n->left);
n = n->right;
goto loop;
} }
} }
@ -115,23 +105,22 @@ sametmp(Node *n1, Node *n2)
Node* Node*
findarg(Node *n, char *arg, char *fn) findarg(Node *n, char *arg, char *fn)
{ {
Iter param;
Node *a; Node *a;
NodeList *l;
if(n == N || n->op != OCALL || if(n == N || n->op != OCALL ||
n->left == N || n->left->sym == S || n->left == N || n->left->sym == S ||
strcmp(n->left->sym->name, fn) != 0) strcmp(n->left->sym->name, fn) != 0)
return N; return N;
a = listfirst(&param, &n->right); for(l=n->list; l; l=l->next) {
while(a != N) { a = l->n;
if(a->op == OAS && if(a->op == OAS &&
a->left != N && a->right != N && a->left != N && a->right != N &&
a->left->op == OINDREG && a->left->op == OINDREG &&
a->left->sym != S) a->left->sym != S)
if(strcmp(a->left->sym->name, arg) == 0) if(strcmp(a->left->sym->name, arg) == 0)
return a->right; return a->right;
a = listnext(&param);
} }
return N; return N;
} }
@ -226,7 +215,7 @@ no:
Node* Node*
mapindex(Node *n) mapindex(Node *n)
{ {
Node *index, *val, *key, *a, *b; Node *index, *val, *key, *a, *b, *r;
// pull all the primatives // pull all the primatives
key = findarg(n, "key", "mapassign1"); key = findarg(n, "key", "mapassign1");
@ -248,10 +237,9 @@ mapindex(Node *n)
b = nod(ODOT, b, newname(lookup("val"))); b = nod(ODOT, b, newname(lookup("val")));
b = nod(OAS, b, val); b = nod(OAS, b, val);
a = nod(OLIST, a, b); r = liststmt(list(list1(a), b));
walkexpr(a, Etop, nil); walkstmt(r);
return r;
return a;
} }
// for a copy out reference, A = B, // for a copy out reference, A = B,
@ -261,8 +249,8 @@ mapindex(Node *n)
void void
initsub(Node *n, Node *nam) initsub(Node *n, Node *nam)
{ {
Iter iter;
Node *r, *w, *c; Node *r, *w, *c;
NodeList *l;
int class, state; int class, state;
// we could probably get a little more // we could probably get a little more
@ -287,7 +275,8 @@ initsub(Node *n, Node *nam)
return; return;
str: str:
for(r=listfirst(&iter, &xxx.list); r != N; r = listnext(&iter)) { for(l=xxx.list; l; l=l->next) {
r = l->n;
if(r->op != OAS && r->op != OEMPTY) if(r->op != OAS && r->op != OEMPTY)
continue; continue;
@ -326,7 +315,8 @@ str:
return; return;
ary: ary:
for(r=listfirst(&iter, &xxx.list); r != N; r = listnext(&iter)) { for(l=xxx.list; l; l=l->next) {
r = l->n;
if(r->op != OAS && r->op != OEMPTY) if(r->op != OAS && r->op != OEMPTY)
continue; continue;
@ -366,7 +356,8 @@ ary:
sli: sli:
w = N; w = N;
for(r=listfirst(&iter, &xxx.list); r != N; r = listnext(&iter)) { for(l=xxx.list; l; l=l->next) {
r = l->n;
if(r->op != OAS && r->op != OEMPTY) if(r->op != OAS && r->op != OEMPTY)
continue; continue;
@ -411,7 +402,8 @@ sli:
map: map:
return; return;
w = N; w = N;
for(r=listfirst(&iter, &xxx.list); r != N; r = listnext(&iter)) { for(l=xxx.list; l; l=l->next) {
r = l->n;
if(r->op == OCALL) { if(r->op == OCALL) {
// middle usage "(CALL mapassign1 key, val, map)" // middle usage "(CALL mapassign1 key, val, map)"
c = mapindex(r); c = mapindex(r);
@ -454,27 +446,23 @@ return;
} }
Node* NodeList*
initfix(Node* n) initfix(NodeList *l)
{ {
Iter iter;
Node *r; Node *r;
xxx.list = N; xxx.list = nil;
initlin(n); initlin(l);
xxx.list = rev(xxx.list);
if(0) if(0)
return xxx.list; return xxx.list;
// look for the copy-out reference // look for the copy-out reference
r = listfirst(&iter, &xxx.list); for(l=xxx.list; l; l=l->next) {
while(r != N) { r = l->n;
if(r->op == OAS) if(r->op == OAS)
if(inittmp(r->right)) { if(inittmp(r->right))
initsub(r->left, r->right); initsub(r->left, r->right);
}
r = listnext(&iter);
} }
return xxx.list; return xxx.list;
} }

View File

@ -215,7 +215,7 @@ restrictlookup(char *name, char *pkg)
yyerror("cannot refer to %s.%s", pkg, name); yyerror("cannot refer to %s.%s", pkg, name);
return pkglookup(name, pkg); return pkglookup(name, pkg);
} }
// find all the exported symbols in package opkg // find all the exported symbols in package opkg
// and make them available in the current package // and make them available in the current package
@ -381,16 +381,6 @@ iskeytype(Type *t)
return algtype(t) != ANOEQ; return algtype(t) != ANOEQ;
} }
Node*
list(Node *a, Node *b)
{
if(a == N)
return b;
if(b == N)
return a;
return nod(OLIST, a, b);
}
Type* Type*
typ(int et) typ(int et)
{ {
@ -461,80 +451,16 @@ nodbool(int b)
return c; return c;
} }
Node*
rev(Node *na)
{
Node *i, *n;
/*
* since yacc wants to build lists
* stacked down on the left -
* this routine converts them to
* stack down on the right -
* in memory without recursion
*/
if(na == N || na->op != OLIST)
return na;
i = na;
for(n = na->left; n != N; n = n->left) {
if(n->op != OLIST)
break;
i->left = n->right;
n->right = i;
i = n;
}
i->left = n;
return i;
}
Node*
unrev(Node *na)
{
Node *i, *n;
/*
* this restores a reverse list
*/
if(na == N || na->op != OLIST)
return na;
i = na;
for(n = na->right; n != N; n = n->right) {
if(n->op != OLIST)
break;
i->right = n->left;
n->left = i;
i = n;
}
i->right = n;
return i;
}
/*
* na and nb are reversed lists.
* append them into one big reversed list.
*/
Node*
appendr(Node *na, Node *nb)
{
Node **l, *n;
for(l=&nb; (n=*l)->op == OLIST; l=&n->left)
;
*l = nod(OLIST, na, *l);
return nb;
}
Type* Type*
aindex(Node *b, Type *t) aindex(Node *b, Type *t)
{ {
Node *top; NodeList *init;
Type *r; Type *r;
int bound; int bound;
bound = -1; // open bound bound = -1; // open bound
top = N; init = nil;
walkexpr(b, Erv, &top); walkexpr(b, Erv, &init);
if(b != nil) { if(b != nil) {
switch(consttype(b)) { switch(consttype(b)) {
default: default:
@ -565,39 +491,36 @@ indent(int dep)
print(". "); print(". ");
} }
void
dodumplist(NodeList *l, int dep)
{
for(; l; l=l->next)
dodump(l->n, dep);
}
void void
dodump(Node *n, int dep) dodump(Node *n, int dep)
{ {
loop:
if(n == N) if(n == N)
return; return;
switch(n->op) {
case OLIST:
if(n->left != N && n->left->op == OLIST)
dodump(n->left, dep+1);
else
dodump(n->left, dep);
n = n->right;
goto loop;
}
indent(dep); indent(dep);
if(dep > 10) { if(dep > 10) {
print("...\n"); print("...\n");
return; return;
} }
if(n->ninit != N) { if(n->ninit != nil) {
print("%O-init\n", n->op); print("%O-init\n", n->op);
dodump(n->ninit, dep+1); dodumplist(n->ninit, dep+1);
indent(dep); indent(dep);
} }
switch(n->op) { switch(n->op) {
default: default:
print("%N\n", n); print("%N\n", n);
dodump(n->left, dep+1);
dodump(n->right, dep+1);
break; break;
case OTYPE: case OTYPE:
@ -607,32 +530,32 @@ loop:
case OIF: case OIF:
print("%O%J\n", n->op, n); print("%O%J\n", n->op, n);
dodump(n->ntest, dep+1); dodump(n->ntest, dep+1);
if(n->nbody != N) { if(n->nbody != nil) {
indent(dep); indent(dep);
print("%O-then\n", n->op); print("%O-then\n", n->op);
dodump(n->nbody, dep+1); dodumplist(n->nbody, dep+1);
} }
if(n->nelse != N) { if(n->nelse != nil) {
indent(dep); indent(dep);
print("%O-else\n", n->op); print("%O-else\n", n->op);
dodump(n->nelse, dep+1); dodumplist(n->nelse, dep+1);
} }
return; break;
case OSELECT: case OSELECT:
print("%O%J\n", n->op, n); print("%O%J\n", n->op, n);
dodump(n->nbody, dep+1); dodumplist(n->nbody, dep+1);
return; break;
case OSWITCH: case OSWITCH:
case OFOR: case OFOR:
print("%O%J\n", n->op, n); print("%O%J\n", n->op, n);
dodump(n->ntest, dep+1); dodump(n->ntest, dep+1);
if(n->nbody != N) { if(n->nbody != nil) {
indent(dep); indent(dep);
print("%O-body\n", n->op); print("%O-body\n", n->op);
dodump(n->nbody, dep+1); dodumplist(n->nbody, dep+1);
} }
if(n->nincr != N) { if(n->nincr != N) {
@ -640,7 +563,7 @@ loop:
print("%O-incr\n", n->op); print("%O-incr\n", n->op);
dodump(n->nincr, dep+1); dodump(n->nincr, dep+1);
} }
return; break;
case OCASE: case OCASE:
// the right side points to label of the body // the right side points to label of the body
@ -649,13 +572,26 @@ loop:
else else
print("%O%J\n", n->op, n); print("%O%J\n", n->op, n);
dodump(n->left, dep+1); dodump(n->left, dep+1);
return; break;
} }
dodump(n->left, dep+1); if(n->list != nil) {
n = n->right; indent(dep);
dep++; print("%O-list\n", n->op);
goto loop; dodumplist(n->list, dep+1);
}
if(n->rlist != nil) {
indent(dep);
print("%O-rlist\n", n->op);
dodumplist(n->rlist, dep+1);
}
}
void
dumplist(char *s, NodeList *l)
{
print("%s\n", s);
dodumplist(l, 1);
} }
void void
@ -687,7 +623,9 @@ opnames[] =
[OARRAY] = "ARRAY", [OARRAY] = "ARRAY",
[OASOP] = "ASOP", [OASOP] = "ASOP",
[OAS] = "AS", [OAS] = "AS",
[OAS2] = "AS2",
[OBAD] = "BAD", [OBAD] = "BAD",
[OBLOCK] = "BLOCK",
[OBREAK] = "BREAK", [OBREAK] = "BREAK",
[OCALLINTER] = "CALLINTER", [OCALLINTER] = "CALLINTER",
[OCALLMETH] = "CALLMETH", [OCALLMETH] = "CALLMETH",
@ -735,7 +673,6 @@ opnames[] =
[OLABEL] = "LABEL", [OLABEL] = "LABEL",
[OLEN] = "LEN", [OLEN] = "LEN",
[OLE] = "LE", [OLE] = "LE",
[OLIST] = "LIST",
[OLITERAL] = "LITERAL", [OLITERAL] = "LITERAL",
[OLSH] = "LSH", [OLSH] = "LSH",
[OLT] = "LT", [OLT] = "LT",
@ -1422,6 +1359,7 @@ treecopy(Node *n)
*m = *n; *m = *n;
m->left = treecopy(n->left); m->left = treecopy(n->left);
m->right = treecopy(n->right); m->right = treecopy(n->right);
m->list = listtreecopy(n->list);
break; break;
case OLITERAL: case OLITERAL:
@ -2154,34 +2092,6 @@ badtype(int o, Type *tl, Type *tr)
} }
} }
/*
* this routine gets called to propagate the type
* of the last decl up to the arguments before it.
* (a,b,c int) comes out (a int, b int, c int).
*/
Node*
cleanidlist(Node *na)
{
Node *last, *n;
if(na->op != OLIST) {
if(na->op != ODCLFIELD)
fatal("cleanidlist: %O", na->op);
if(na->right == N)
fatal("cleanidlist: no type");
return na;
}
for(last=na; last->op == OLIST; last=last->right)
;
for(n=na; n->op == OLIST; n=n->right) {
n->left->right = last->right;
n->left->val = last->val;
}
return na;
}
/* /*
* iterator to walk a structure declaration * iterator to walk a structure declaration
*/ */
@ -2285,63 +2195,6 @@ funcnext(Iter *s)
return fp; return fp;
} }
/*
* iterator to walk a list
*/
Node*
listfirst(Iter *s, Node **nn)
{
Node *n;
n = *nn;
if(n == N) {
s->done = 1;
s->an = &s->n;
s->n = N;
return N;
}
if(n->op == OLIST) {
s->done = 0;
s->n = n;
s->an = &n->left;
return n->left;
}
s->done = 1;
s->an = nn;
return n;
}
Node*
listnext(Iter *s)
{
Node *n, *r;
if(s->done) {
s->an = &s->n;
s->n = N;
return N;
}
n = s->n;
r = n->right;
if(r == N) {
s->an = &s->n;
s->n = N;
return N;
}
if(r->op == OLIST) {
s->n = r;
s->an = &r->left;
return r->left;
}
s->done = 1;
s->an = &n->right;
return n->right;
}
Type** Type**
getthis(Type *t) getthis(Type *t)
{ {
@ -2475,7 +2328,7 @@ staticname(Type *t)
* return side effect-free n, appending side effects to init. * return side effect-free n, appending side effects to init.
*/ */
Node* Node*
saferef(Node *n, Node **init) saferef(Node *n, NodeList **init)
{ {
Node *l; Node *l;
Node *r; Node *r;
@ -2657,13 +2510,13 @@ out:
Node* Node*
adddot(Node *n) adddot(Node *n)
{ {
Node *top; NodeList *init;
Type *t; Type *t;
Sym *s; Sym *s;
int c, d; int c, d;
top = N; init = nil;
walkexpr(n->left, Erv, &top); walkexpr(n->left, Erv, &init);
t = n->left->type; t = n->left->type;
if(t == T) if(t == T)
goto ret; goto ret;
@ -2691,8 +2544,7 @@ out:
n->left->right = newname(dotlist[c].field->sym); n->left->right = newname(dotlist[c].field->sym);
} }
ret: ret:
if(top != N) n->ninit = concat(init, n->ninit);
n->ninit = list(top, n->ninit);
return n; return n;
} }
@ -2847,16 +2699,17 @@ expandmeth(Sym *s, Type *t)
/* /*
* Given funarg struct list, return list of ODCLFIELD Node fn args. * Given funarg struct list, return list of ODCLFIELD Node fn args.
*/ */
Node* NodeList*
structargs(Type **tl, int mustname) structargs(Type **tl, int mustname)
{ {
Iter savet; Iter savet;
Node *args, *a; Node *a;
NodeList *args;
Type *t; Type *t;
char nam[100]; char nam[100];
int n; int n;
args = N; args = nil;
n = 0; n = 0;
for(t = structfirst(&savet, tl); t != T; t = structnext(&savet)) { for(t = structfirst(&savet, tl); t != T; t = structnext(&savet)) {
if(t->sym) if(t->sym)
@ -2869,7 +2722,6 @@ structargs(Type **tl, int mustname)
a = anondcl(t->type); a = anondcl(t->type);
args = list(args, a); args = list(args, a);
} }
args = rev(args);
return args; return args;
} }
@ -2899,9 +2751,8 @@ structargs(Type **tl, int mustname)
void void
genwrapper(Type *rcvr, Type *method, Sym *newnam) genwrapper(Type *rcvr, Type *method, Sym *newnam)
{ {
Node *this, *in, *out, *fn, *args, *call; Node *this, *fn, *call, *n;
Node *l; NodeList *l, *args, *in, *out;
Iter savel;
if(debug['r']) if(debug['r'])
print("genwrapper rcvrtype=%T method=%T newnam=%S\n", print("genwrapper rcvrtype=%T method=%T newnam=%S\n",
@ -2920,19 +2771,22 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam)
funchdr(fn); funchdr(fn);
// arg list // arg list
args = N; args = nil;
for(l = listfirst(&savel, &in); l; l = listnext(&savel)) for(l=in; l; l=l->next)
args = list(args, l->left); args = list(args, l->n->left);
args = rev(args);
// generate call // generate call
call = nod(OCALL, adddot(nod(ODOT, this->left, newname(method->sym))), args); call = nod(OCALL, adddot(nod(ODOT, this->left, newname(method->sym))), N);
fn->nbody = call; call->list = args;
if(method->type->outtuple > 0) fn->nbody = list1(call);
fn->nbody = nod(ORETURN, call, N); if(method->type->outtuple > 0) {
n = nod(ORETURN, N, N);
n->list = fn->nbody;
fn->nbody = list1(n);
}
if(debug['r']) if(debug['r'])
dump("genwrapper body", fn->nbody); dumplist("genwrapper body", fn->nbody);
funcbody(fn); funcbody(fn);
} }
@ -3137,3 +2991,71 @@ simsimtype(Type *t)
return et; return et;
} }
NodeList*
concat(NodeList *a, NodeList *b)
{
if(a == nil)
return b;
if(b == nil)
return a;
a->end->next = b;
a->end = b->end;
b->end = nil;
return a;
}
NodeList*
list1(Node *n)
{
NodeList *l;
if(n == nil)
return nil;
if(n->op == OBLOCK && n->ninit == nil)
return n->list;
l = mal(sizeof *l);
l->n = n;
l->end = l;
return l;
}
NodeList*
list(NodeList *l, Node *n)
{
return concat(l, list1(n));
}
NodeList*
listtreecopy(NodeList *l)
{
NodeList *out;
out = nil;
for(; l; l=l->next)
out = list(out, treecopy(l->n));
return out;
}
Node*
liststmt(NodeList *l)
{
Node *n;
n = nod(OBLOCK, N, N);
n->list = l;
if(l)
n->lineno = l->n->lineno;
return n;
}
int
count(NodeList *l)
{
int n;
n = 0;
for(; l; l=l->next)
n++;
return n;
}

View File

@ -305,33 +305,27 @@ sw3(Node *c, Type *place, int arg)
Type* Type*
walkcases(Node *sw, Type*(*call)(Node*, Type*, int arg), int arg) walkcases(Node *sw, Type*(*call)(Node*, Type*, int arg), int arg)
{ {
Iter save;
Node *n; Node *n;
NodeList *l;
Type *place; Type *place;
int32 lno; int32 lno;
lno = setlineno(sw); lno = setlineno(sw);
place = call(sw->ntest, T, arg); place = call(sw->ntest, T, arg);
n = listfirst(&save, &sw->nbody->left); for(l=sw->list; l; l=l->next) {
if(n == N || n->op == OEMPTY) n = l->n;
return T;
loop: if(n->op != OCASE)
if(n == N) { fatal("walkcases: not case %O\n", n->op);
lineno = lno;
return place; if(n->left != N && !n->diag) {
setlineno(n);
place = call(n->left, place, arg);
}
} }
lineno = lno;
if(n->op != OCASE) return place;
fatal("walkcases: not case %O\n", n->op);
if(n->left != N && !n->diag) {
setlineno(n);
place = call(n->left, place, arg);
}
n = listnext(&save);
goto loop;
} }
Node* Node*
@ -352,35 +346,32 @@ newlabel(void)
void void
casebody(Node *sw) casebody(Node *sw)
{ {
Iter save, save1; Node *os, *oc, *n, *c, *last;
Node *os, *oc, *n, *n1, *c; Node *def;
Node *cas, *stat, *def; NodeList *cas, *stat, *l, *lc;
Node *go, *br; Node *go, *br;
int32 lno; int32 lno;
lno = setlineno(sw); lno = setlineno(sw);
n = listfirst(&save, &sw->nbody); if(sw->list == nil)
if(n == N || n->op == OEMPTY) {
sw->nbody = nod(OLIST, N, N);
return; return;
}
cas = N; // cases cas = nil; // cases
stat = N; // statements stat = nil; // statements
def = N; // defaults def = N; // defaults
os = N; // last statement os = N; // last statement
oc = N; // last case oc = N; // last case
br = nod(OBREAK, N, N); br = nod(OBREAK, N, N);
for(; n != N; n = listnext(&save)) { for(l=sw->list; l; l=l->next) {
n = l->n;
lno = setlineno(n); lno = setlineno(n);
if(n->op != OXCASE) if(n->op != OXCASE)
fatal("casebody %O", n->op); fatal("casebody %O", n->op);
n->op = OCASE; n->op = OCASE;
go = nod(OGOTO, newlabel(), N); go = nod(OGOTO, newlabel(), N);
c = n->left; if(n->list == nil) {
if(c == N) {
if(def != N) if(def != N)
yyerror("more than one default case"); yyerror("more than one default case");
// reuse original default case // reuse original default case
@ -388,105 +379,97 @@ casebody(Node *sw)
def = n; def = n;
} }
// expand multi-valued cases if(n->list != nil && n->list->next == nil) {
for(; c!=N; c=c->right) { // one case - reuse OCASE node.
if(c->op != OLIST) { c = n->list->n;
// reuse original case n->left = c;
n->left = c; n->right = go;
n->right = go; n->list = nil;
cas = list(cas, n); cas = list(cas, n);
break; } else {
// expand multi-valued cases
for(lc=n->list; lc; lc=lc->next) {
c = lc->n;
cas = list(cas, nod(OCASE, c, go));
} }
cas = list(cas, nod(OCASE, c->left, go));
} }
stat = list(stat, nod(OLABEL, go->left, N)); stat = list(stat, nod(OLABEL, go->left, N));
stat = concat(stat, n->nbody);
os = N;
for(n1 = listfirst(&save1, &n->nbody); n1 != N; n1 = listnext(&save1)) {
os = n1;
stat = list(stat, n1);
}
// botch - shouldnt fall thru declaration // botch - shouldnt fall thru declaration
if(os != N && os->op == OXFALL) last = stat->end->n;
os->op = OFALL; if(last->op == OXFALL)
last->op = OFALL;
else else
stat = list(stat, br); stat = list(stat, br);
} }
stat = list(stat, br); stat = list(stat, br);
cas = list(cas, def); if(def)
cas = list(cas, def);
sw->nbody = nod(OLIST, rev(cas), rev(stat)); sw->list = cas;
//dump("case", sw->nbody->left); sw->nbody = stat;
//dump("stat", sw->nbody->right);
lineno = lno; lineno = lno;
} }
Case* Case*
mkcaselist(Node *sw, int arg) mkcaselist(Node *sw, int arg)
{ {
Iter save;
Node *n; Node *n;
Case *c, *c1; Case *c, *c1;
NodeList *l;
int ord; int ord;
c = C; c = C;
ord = 0; ord = 0;
n = listfirst(&save, &sw->nbody->left); for(l=sw->list; l; l=l->next) {
n = l->n;
c1 = mal(sizeof(*c1));
c1->link = c;
c = c1;
loop: ord++;
if(n == N) c->ordinal = ord;
goto done; c->node = n;
c1 = mal(sizeof(*c1)); if(n->left == N) {
c1->link = c; c->type = Tdefault;
c = c1; continue;
}
ord++; switch(arg) {
c->ordinal = ord; case Stype:
c->node = n; c->hash = 0;
if(n->left->left == N) {
c->type = Ttypenil;
continue;
}
if(istype(n->left->left->type, TINTER)) {
c->type = Ttypevar;
continue;
}
if(n->left == N) { c->hash = typehash(n->left->left->type, 1, 0);
c->type = Tdefault; c->type = Ttypeconst;
goto next; continue;
case Snorm:
case Strue:
case Sfalse:
c->type = Texprvar;
switch(consttype(n->left)) {
case CTFLT:
case CTINT:
case CTSTR:
c->type = Texprconst;
}
continue;
}
} }
switch(arg) {
case Stype:
c->hash = 0;
if(n->left->left == N) {
c->type = Ttypenil;
goto next;
}
if(istype(n->left->left->type, TINTER)) {
c->type = Ttypevar;
goto next;
}
c->hash = typehash(n->left->left->type, 1, 0);
c->type = Ttypeconst;
goto next;
case Snorm:
case Strue:
case Sfalse:
c->type = Texprvar;
switch(consttype(n->left)) {
case CTFLT:
case CTINT:
case CTSTR:
c->type = Texprconst;
}
goto next;
}
next:
n = listnext(&save);
goto loop;
done:
if(c == C) if(c == C)
return C; return C;
@ -528,12 +511,12 @@ static Node* exprname;
Node* Node*
exprbsw(Case *c0, int ncase, int arg) exprbsw(Case *c0, int ncase, int arg)
{ {
Node *cas; NodeList *cas;
Node *a, *n; Node *a, *n;
Case *c; Case *c;
int i, half, lno; int i, half, lno;
cas = N; cas = nil;
if(ncase < Ncase) { if(ncase < Ncase) {
for(i=0; i<ncase; i++) { for(i=0; i<ncase; i++) {
n = c0->node; n = c0->node;
@ -543,19 +526,19 @@ exprbsw(Case *c0, int ncase, int arg)
case Strue: case Strue:
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = n->left; // if val a->ntest = n->left; // if val
a->nbody = n->right; // then goto l a->nbody = list1(n->right); // then goto l
break; break;
case Sfalse: case Sfalse:
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = nod(ONOT, n->left, N); // if !val a->ntest = nod(ONOT, n->left, N); // if !val
a->nbody = n->right; // then goto l a->nbody = list1(n->right); // then goto l
break; break;
default: default:
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = nod(OEQ, exprname, n->left); // if name == val a->ntest = nod(OEQ, exprname, n->left); // if name == val
a->nbody = n->right; // then goto l a->nbody = list1(n->right); // then goto l
break; break;
} }
@ -563,7 +546,7 @@ exprbsw(Case *c0, int ncase, int arg)
c0 = c0->link; c0 = c0->link;
lineno = lno; lineno = lno;
} }
return cas; return liststmt(cas);
} }
// find the middle and recur // find the middle and recur
@ -573,8 +556,8 @@ exprbsw(Case *c0, int ncase, int arg)
c = c->link; c = c->link;
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = nod(OLE, exprname, c->node->left); a->ntest = nod(OLE, exprname, c->node->left);
a->nbody = exprbsw(c0, half, arg); a->nbody = list1(exprbsw(c0, half, arg));
a->nelse = exprbsw(c->link, ncase-half, arg); a->nelse = list1(exprbsw(c->link, ncase-half, arg));
return a; return a;
} }
@ -585,7 +568,8 @@ exprbsw(Case *c0, int ncase, int arg)
void void
exprswitch(Node *sw) exprswitch(Node *sw)
{ {
Node *def, *cas; Node *def;
NodeList *cas;
Node *a; Node *a;
Case *c0, *c, *c1; Case *c0, *c, *c1;
Type *t; Type *t;
@ -620,11 +604,11 @@ exprswitch(Node *sw)
* convert the switch into OIF statements * convert the switch into OIF statements
*/ */
exprname = N; exprname = N;
cas = N; cas = nil;
if(arg != Strue && arg != Sfalse) { if(arg != Strue && arg != Sfalse) {
exprname = nod(OXXX, N, N); exprname = nod(OXXX, N, N);
tempname(exprname, sw->ntest->type); tempname(exprname, sw->ntest->type);
cas = nod(OAS, exprname, sw->ntest); cas = list1(nod(OAS, exprname, sw->ntest));
} }
c0 = mkcaselist(sw, arg); c0 = mkcaselist(sw, arg);
@ -638,8 +622,9 @@ exprswitch(Node *sw)
loop: loop:
if(c0 == C) { if(c0 == C) {
cas = list(cas, def); cas = list(cas, def);
sw->nbody->left = rev(cas); sw->nbody = concat(cas, sw->nbody);
walkstmt(sw->nbody); sw->list = nil;
walkstmtlist(sw->nbody);
return; return;
} }
@ -680,34 +665,36 @@ static Node* boolname;
Node* Node*
typeone(Node *t) typeone(Node *t)
{ {
Node *a, *b, *dcl; NodeList *init;
Node *a, *b, *var;
a = t->left->left; // var var = t->left->left;
dcl = nod(ODCL, a, N); init = list1(nod(ODCL, var, N));
a = nod(OLIST, a, boolname); // var,bool
a = nod(OAS2, N, N);
a->list = list(list1(var), boolname); // var,bool =
b = nod(ODOTTYPE, facename, N); b = nod(ODOTTYPE, facename, N);
b->type = t->left->left->type; // interface.(type) b->type = t->left->left->type; // interface.(type)
a->rlist = list1(b);
a = nod(OAS, a, b); // var,bool = interface.(type) init = list(init, a);
b = nod(OIF, N, N); b = nod(OIF, N, N);
b->ntest = boolname; b->ntest = boolname;
b->nbody = t->right; // if bool { goto l } b->nbody = list1(t->right); // if bool { goto l }
return list(list(dcl, a), b); a = liststmt(list(init, b));
return a;
} }
Node* Node*
typebsw(Case *c0, int ncase) typebsw(Case *c0, int ncase)
{ {
Node *cas; NodeList *cas;
Node *a, *n; Node *a, *n;
Case *c; Case *c;
int i, half; int i, half;
Val v; Val v;
cas = N; cas = nil;
if(ncase < Ncase) { if(ncase < Ncase) {
for(i=0; i<ncase; i++) { for(i=0; i<ncase; i++) {
@ -719,7 +706,7 @@ typebsw(Case *c0, int ncase)
v.ctype = CTNIL; v.ctype = CTNIL;
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = nod(OEQ, facename, nodlit(v)); a->ntest = nod(OEQ, facename, nodlit(v));
a->nbody = n->right; // if i==nil { goto l } a->nbody = list1(n->right); // if i==nil { goto l }
cas = list(cas, a); cas = list(cas, a);
break; break;
@ -731,13 +718,13 @@ typebsw(Case *c0, int ncase)
case Ttypeconst: case Ttypeconst:
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = nod(OEQ, hashname, nodintconst(c0->hash)); a->ntest = nod(OEQ, hashname, nodintconst(c0->hash));
a->nbody = rev(typeone(n)); a->nbody = list1(typeone(n));
cas = list(cas, a); cas = list(cas, a);
break; break;
} }
c0 = c0->link; c0 = c0->link;
} }
return cas; return liststmt(cas);
} }
// find the middle and recur // find the middle and recur
@ -747,8 +734,8 @@ typebsw(Case *c0, int ncase)
c = c->link; c = c->link;
a = nod(OIF, N, N); a = nod(OIF, N, N);
a->ntest = nod(OLE, hashname, nodintconst(c->hash)); a->ntest = nod(OLE, hashname, nodintconst(c->hash));
a->nbody = typebsw(c0, half); a->nbody = list1(typebsw(c0, half));
a->nelse = typebsw(c->link, ncase-half); a->nelse = list1(typebsw(c->link, ncase-half));
return a; return a;
} }
@ -760,7 +747,8 @@ typebsw(Case *c0, int ncase)
void void
typeswitch(Node *sw) typeswitch(Node *sw)
{ {
Node *cas, *def; Node *def;
NodeList *cas;
Node *a; Node *a;
Case *c, *c0, *c1; Case *c, *c0, *c1;
int ncase; int ncase;
@ -779,7 +767,7 @@ typeswitch(Node *sw)
return; return;
} }
walkcases(sw, sw0, Stype); walkcases(sw, sw0, Stype);
cas = N; cas = nil;
/* /*
* predeclare temporary variables * predeclare temporary variables
@ -802,7 +790,8 @@ typeswitch(Node *sw)
else else
a = syslook("ifacethash", 1); a = syslook("ifacethash", 1);
argtype(a, t); argtype(a, t);
a = nod(OCALL, a, facename); a = nod(OCALL, a, N);
a->list = list1(facename);
a = nod(OAS, hashname, a); a = nod(OAS, hashname, a);
cas = list(cas, a); cas = list(cas, a);
@ -817,8 +806,9 @@ typeswitch(Node *sw)
loop: loop:
if(c0 == C) { if(c0 == C) {
cas = list(cas, def); cas = list(cas, def);
sw->nbody->left = rev(cas); sw->nbody = concat(cas, sw->nbody);
walkstmt(sw->nbody); sw->list = nil;
walkstmtlist(sw->nbody);
return; return;
} }
@ -860,7 +850,7 @@ walkswitch(Node *sw)
* cases have OGOTO into statements. * cases have OGOTO into statements.
* both have inserted OBREAK statements * both have inserted OBREAK statements
*/ */
walkstmt(sw->ninit); walkstmtlist(sw->ninit);
if(sw->ntest == N) if(sw->ntest == N)
sw->ntest = nodbool(1); sw->ntest = nodbool(1);
casebody(sw); casebody(sw);

View File

@ -67,7 +67,6 @@ func mapiter2(hiter *any) (key any, val any);
func newchan(elemsize int, elemalg int, hint int) (hchan chan any); func newchan(elemsize int, elemalg int, hint int) (hchan chan any);
func chanrecv1(hchan <-chan any) (elem any); func chanrecv1(hchan <-chan any) (elem any);
func chanrecv2(hchan <-chan any) (elem any, pres bool); func chanrecv2(hchan <-chan any) (elem any, pres bool);
func chanrecv3(hchan <-chan any, elem *any) (pres bool);
func chansend1(hchan chan<- any, elem any); func chansend1(hchan chan<- any, elem any);
func chansend2(hchan chan<- any, elem any) (pres bool); func chansend2(hchan chan<- any, elem any) (pres bool);
func closechan(hchan any); func closechan(hchan any);

File diff suppressed because it is too large Load Diff

View File

@ -431,13 +431,6 @@ sys·chanrecv2(Hchan* c, ...)
chanrecv(c, ae, ap); chanrecv(c, ae, ap);
} }
// chanrecv3(hchan *chan any, elem *any) (pres bool);
void
sys·chanrecv3(Hchan* c, byte* ep, byte pres)
{
chanrecv(c, ep, &pres);
}
// newselect(size uint32) (sel *byte); // newselect(size uint32) (sel *byte);
void void
sys·newselect(int32 size, ...) sys·newselect(int32 size, ...)

View File

@ -99,8 +99,7 @@ throw: interface conversion
panic PC=xxx panic PC=xxx
=========== bugs/bug159.go =========== bugs/bug159.go
xyz: expected 1 2 3 got 3 2 1 abc: expected 4 5 6 got 4 4 -4
abc: expected 4 5 6 got -4 4 4
BUG: bug159 BUG: bug159
=========== bugs/bug162.go =========== bugs/bug162.go