Commit e52e9ca8 authored by Russ Cox's avatar Russ Cox

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
parent 9b475bd2
......@@ -26,7 +26,7 @@ compile(Node *fn)
throwreturn = sysfunc("throwreturn");
}
if(fn->nbody == N)
if(fn->nbody == nil)
return;
// set up domain for labels
......@@ -42,7 +42,7 @@ compile(Node *fn)
t = structfirst(&save, getoutarg(curfn->type));
while(t != T) {
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);
}
}
......@@ -65,8 +65,8 @@ compile(Node *fn)
ptxt = gins(ATEXT, curfn->nname, &nod1);
afunclit(&ptxt->from);
gen(curfn->enter);
gen(curfn->nbody);
genlist(curfn->enter);
genlist(curfn->nbody);
checklabels();
if(curfn->type->outtuple != 0)
......@@ -326,7 +326,7 @@ cgen_aret(Node *n, Node *res)
void
cgen_ret(Node *n)
{
gen(n->left); // copy out args
genlist(n->list); // copy out args
if(hasdefer)
ginscall(deferreturn, 0);
gins(ARET, N, N);
......
......@@ -26,7 +26,7 @@ compile(Node *fn)
throwreturn = sysfunc("throwreturn");
}
if(fn->nbody == N)
if(fn->nbody == nil)
return;
// set up domain for labels
......@@ -42,7 +42,7 @@ compile(Node *fn)
t = structfirst(&save, getoutarg(curfn->type));
while(t != T) {
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);
}
}
......@@ -66,8 +66,8 @@ compile(Node *fn)
afunclit(&ptxt->from);
ginit();
gen(curfn->enter);
gen(curfn->nbody);
genlist(curfn->enter);
genlist(curfn->nbody);
gclean();
checklabels();
......@@ -164,7 +164,7 @@ cgen_callinter(Node *n, Node *res, int proc)
i = &tmpi;
}
gen(n->right); // args
genlist(n->list); // assign the args
regalloc(&nodr, types[tptr], res);
regalloc(&nodo, types[tptr], &nodr);
......@@ -214,7 +214,7 @@ cgen_call(Node *n, int proc)
cgen(n->left, &afun);
}
gen(n->right); // assign the args
genlist(n->list); // assign the args
t = n->left->type;
setmaxarg(t);
......@@ -322,7 +322,7 @@ cgen_aret(Node *n, Node *res)
void
cgen_ret(Node *n)
{
gen(n->left); // copy out args
genlist(n->list); // copy out args
if(hasdefer)
ginscall(deferreturn, 0);
gins(ARET, N, N);
......
......@@ -24,7 +24,7 @@ compile(Node *fn)
throwreturn = sysfunc("throwreturn");
}
if(fn->nbody == N)
if(fn->nbody == nil)
return;
// set up domain for labels
......@@ -40,7 +40,7 @@ compile(Node *fn)
t = structfirst(&save, getoutarg(curfn->type));
while(t != T) {
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);
}
}
......@@ -64,8 +64,8 @@ compile(Node *fn)
afunclit(&ptxt->from);
ginit();
gen(curfn->enter);
gen(curfn->nbody);
genlist(curfn->enter);
genlist(curfn->nbody);
gclean();
checklabels();
......@@ -200,7 +200,7 @@ cgen_callinter(Node *n, Node *res, int proc)
i = &tmpi;
}
gen(n->right); // args
genlist(n->list); // assign the args
// Can regalloc now; i is known to be addable,
// so the agen will be easy.
......@@ -255,7 +255,7 @@ cgen_call(Node *n, int proc)
cgen(n->left, &afun);
}
gen(n->right); // assign the args
genlist(n->list); // assign the args
t = n->left->type;
setmaxarg(t);
......@@ -360,7 +360,7 @@ cgen_aret(Node *n, Node *res)
void
cgen_ret(Node *n)
{
gen(n->left); // copy out args
genlist(n->list); // copy out args
if(hasdefer)
ginscall(deferreturn, 0);
gins(ARET, N, N);
......
......@@ -307,7 +307,7 @@ typeinit(void)
mpatoflt(minfltval[TFLOAT64], "-1.7976931348623157e+308");
/* 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[TNIL] got set early in lexinit
......
......@@ -53,7 +53,6 @@ char *sysimport =
"func sys.newchan (elemsize int, elemalg int, hint int) (hchan chan any)\n"
"func sys.chanrecv1 (hchan <-chan any) (elem any)\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.chansend2 (hchan chan<- any, elem any) (pres bool)\n"
"func sys.closechan (hchan any)\n"
......
This diff is collapsed.
......@@ -127,6 +127,13 @@ findlab(Sym *s)
/*
* compile statements
*/
void
genlist(NodeList *l)
{
for(; l; l=l->next)
gen(l->n);
}
void
gen(Node *n)
{
......@@ -137,13 +144,12 @@ gen(Node *n)
lno = setlineno(n);
loop:
if(n == N)
goto ret;
p3 = pc; // save pc for loop labels
if(n->ninit)
gen(n->ninit);
genlist(n->ninit);
setlineno(n);
......@@ -152,11 +158,6 @@ loop:
fatal("gen: unknown op %N", n);
break;
case OLIST:
gen(n->left);
n = n->right;
goto loop;
case OCASE:
case OFALL:
case OXCASE:
......@@ -164,6 +165,10 @@ loop:
case OEMPTY:
break;
case OBLOCK:
genlist(n->list);
break;
case OLABEL:
newlab(OLABEL, n->left->sym);
break;
......@@ -232,10 +237,10 @@ loop:
gen(n->nincr); // contin: incr
patch(p1, pc); // test:
if(n->ntest != N)
if(n->ntest->ninit != N)
gen(n->ntest->ninit);
if(n->ntest->ninit != nil)
genlist(n->ntest->ninit);
bgen(n->ntest, 0, breakpc); // if(!test) goto break
gen(n->nbody); // body
genlist(n->nbody); // body
gjmp(continpc);
patch(breakpc, pc); // done:
continpc = scontin;
......@@ -247,13 +252,13 @@ loop:
p2 = gjmp(P); // p2: goto else
patch(p1, pc); // test:
if(n->ntest != N)
if(n->ntest->ninit != N)
gen(n->ntest->ninit);
if(n->ntest->ninit != nil)
genlist(n->ntest->ninit);
bgen(n->ntest, 0, p2); // if(!test) goto p2
gen(n->nbody); // then
genlist(n->nbody); // then
p3 = gjmp(P); // goto done
patch(p2, pc); // else:
gen(n->nelse); // else
genlist(n->nelse); // else
patch(p3, pc); // done:
break;
......@@ -272,7 +277,7 @@ loop:
}
patch(p1, pc); // test:
gen(n->nbody); // switch(test) body
genlist(n->nbody); // switch(test) body
patch(breakpc, pc); // done:
breakpc = sbreak;
break;
......@@ -292,7 +297,7 @@ loop:
}
patch(p1, pc); // test:
gen(n->nbody); // select() body
genlist(n->nbody); // select() body
patch(breakpc, pc); // done:
breakpc = sbreak;
break;
......@@ -432,12 +437,6 @@ cgen_as(Node *nl, Node *nr)
iszer = 0;
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
if(nr == N) {
if(nl->class == PEXTERN)
......
......@@ -129,6 +129,7 @@ struct Val
typedef struct Sym Sym;
typedef struct Node Node;
typedef struct NodeList NodeList;
typedef struct Type Type;
typedef struct Dcl Dcl;
......@@ -198,24 +199,26 @@ struct Node
Node* left;
Node* right;
Type* type;
NodeList* list;
NodeList* rlist;
// for-body
Node* ninit;
NodeList* ninit;
Node* ntest;
Node* nincr;
Node* nbody;
NodeList* nbody;
// if-body
Node* nelse;
NodeList* nelse;
// cases
Node* ncase;
// func
Node* nname;
Node* enter;
Node* exit;
Node* cvars; // closure params
NodeList* enter;
NodeList* exit;
NodeList* cvars; // closure params
Dcl* dcl; // outer autodcl
// OLITERAL/OREGISTER
......@@ -242,6 +245,13 @@ struct Node
};
#define N ((Node*)0)
struct NodeList
{
Node* n;
NodeList* next;
NodeList* end;
};
struct Sym
{
ushort block; // blocknumber to catch redeclaration
......@@ -308,12 +318,12 @@ enum
ODCL,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER,
ODCLFUNC, ODCLFIELD, ODCLARG,
OLIST, OCMP, OPTR, OARRAY, ORANGE,
OCMP, OPTR, OARRAY, ORANGE,
ORETURN, OFOR, OIF, OSWITCH, ODEFER,
OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL,
OAS, OAS2, OASOP, OCASE, OXCASE, OFALL, OXFALL,
OGOTO, OPROC, OMAKE, ONEW, OEMPTY, OSELECT,
OLEN, OCAP, OPANIC, OPANICN, OPRINT, OPRINTN, OTYPEOF,
OCLOSE, OCLOSED,
OCLOSE, OCLOSED, OBLOCK,
OOROR,
OANDAND,
......@@ -590,7 +600,7 @@ EXTERN int statuniqgen; // name generator for static temps
EXTERN int loophack;
EXTERN uint32 iota;
EXTERN Node* lastconst;
EXTERN NodeList* lastconst;
EXTERN Type* lasttype;
EXTERN int32 vargen;
EXTERN int32 exportgen;
......@@ -605,7 +615,6 @@ EXTERN int maxround;
EXTERN int widthptr;
EXTERN Node* retnil;
EXTERN Node* fskel;
EXTERN Node* typeswvar;
......@@ -726,15 +735,12 @@ void linehist(char*, int32, int);
int32 setlineno(Node*);
Node* nod(int, Node*, Node*);
Node* nodlit(Val);
Node* list(Node*, Node*);
Type* typ(int);
Dcl* dcl(void);
int algtype(Type*);
Node* rev(Node*);
Node* unrev(Node*);
Node* appendr(Node*, Node*);
void dodump(Node*, int);
void dump(char*, Node*);
void dumplist(char*, NodeList*);
Type* aindex(Node*, Type*);
int isnil(Node*);
int isptrto(Type*, int);
......@@ -762,17 +768,23 @@ Node* nodbool(int);
void ullmancalc(Node*);
void badtype(int, Type*, Type*);
Type* ptrto(Type*);
Node* cleanidlist(Node*);
NodeList* cleanidlist(NodeList*);
Node* syslook(char*, int);
Node* treecopy(Node*);
NodeList* listtreecopy(NodeList*);
int isselect(Node*);
void tempname(Node*, Type*);
Node* staticname(Type*);
int iscomposite(Type*);
Node* callnew(Type*);
Node* saferef(Node*, Node**);
Node* saferef(Node*, NodeList**);
int is64(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** getoutarg(Type*);
......@@ -782,8 +794,6 @@ Type* getthisx(Type*);
Type* getoutargx(Type*);
Type* getinargx(Type*);
Node* listfirst(Iter*, Node**);
Node* listnext(Iter*);
Type* structfirst(Iter*, Type**);
Type* structnext(Iter*);
Type* funcfirst(Iter*, Type*);
......@@ -817,18 +827,17 @@ int simsimtype(Type*);
/*
* dcl.c
*/
void dodclvar(Node*, Type*, Node**);
void dodclvar(Node*, Type*, NodeList**);
Type* dodcltype(Type*);
void updatetype(Type*, Type*);
void dodclconst(Node*, Node*);
void defaultlit(Node*, Type*);
void defaultlit2(Node*, Node*);
int listcount(Node*);
int structcount(Type*);
void addmethod(Node*, Type*, int);
Node* methodname(Node*, Type*);
Sym* methodsym(Sym*, Type*);
Type* functype(Node*, Node*, Node*);
Type* functype(Node*, NodeList*, NodeList*);
char* thistypenam(Node*);
void funcnam(Type*, char*);
Node* renameinit(Node*);
......@@ -836,8 +845,8 @@ void funchdr(Node*);
void funcargs(Type*);
void funcbody(Node*);
Node* typenod(Type*);
Type* dostruct(Node*, int);
Type** stotype(Node*, int, Type**);
Type* dostruct(NodeList*, int);
Type** stotype(NodeList*, int, Type**);
Type* sortinter(Type*);
void markdcl(void);
void popdcl(void);
......@@ -855,27 +864,26 @@ Node* newname(Sym*);
Node* oldname(Sym*);
Type* newtype(Sym*);
Type* oldtype(Sym*);
void fninit(Node*);
Node* nametoanondcl(Node*);
void fninit(NodeList*);
Node* nametodcl(Node*, Type*);
Node* anondcl(Type*);
Node* checkarglist(Node*);
NodeList* checkarglist(NodeList*);
void checkwidth(Type*);
void defercheckwidth(void);
void resumecheckwidth(void);
Node* embedded(Sym*);
Node* variter(Node*, Type*, Node*);
void constiter(Node*, Type*, Node*);
NodeList* variter(NodeList*, Type*, NodeList*);
void constiter(NodeList*, Type*, NodeList*);
void funclit0(Type*);
Node* funclit1(Type*, Node*);
Node* unsafenmagic(Node*, Node*);
Node* funclit1(Type*, NodeList*);
Node* unsafenmagic(Node*, NodeList*);
/*
* sinit.c
*/
Node* initfix(Node*);
NodeList* initfix(NodeList*);
/*
* export.c
......@@ -912,30 +920,33 @@ Type* pkgtype(Sym*);
/*
* walk.c
*/
void gettype(Node*, Node**);
void gettype(Node*, NodeList**);
void walk(Node*);
void walkstmt(Node*);
void walkexpr(Node*, int, Node**);
void walkconv(Node*, Node**);
void walkdottype(Node*, Node**);
void walkstmtlist(NodeList*);
void walkexpr(Node*, int, NodeList**);
void walkexprlist(NodeList*, int, NodeList**);
void walkconv(Node*, NodeList**);
void walkdottype(Node*, NodeList**);
void walkas(Node*);
void walkbool(Node*);
void walkswitch(Node*);
void walkselect(Node*);
void walkdot(Node*, Node**);
Node* ascompatee(int, Node**, Node**, Node**);
Node* ascompatet(int, Node**, Type**, int, Node**);
Node* ascompatte(int, Type**, Node**, int, Node**);
void walkdot(Node*, NodeList**);
Node* ascompatee1(int, Node*, Node*, NodeList**);
NodeList* ascompatee(int, NodeList*, NodeList*, NodeList**);
NodeList* ascompatet(int, NodeList*, Type**, int, NodeList**);
NodeList* ascompatte(int, Type**, NodeList*, int, NodeList**);
int ascompat(Type*, Type*);
Node* prcompat(Node*, int);
Node* prcompat(NodeList*, int, int);
Node* nodpanic(int32);
Node* newcompat(Node*);
Node* makecompat(Node*);
Node* stringop(Node*, int, Node**);
Node* stringop(Node*, int, NodeList**);
Type* fixmap(Type*);
Node* mapop(Node*, int, Node**);
Node* mapop(Node*, int, NodeList**);
Type* fixchan(Type*);
Node* chanop(Node*, int, Node**);
Node* chanop(Node*, int, NodeList**);
Node* arrayop(Node*, int);
Node* ifacecvt(Type*, Node*, int);
Node* ifaceop(Node*);
......@@ -943,18 +954,18 @@ int ifaceas(Type*, Type*, int);
int ifaceas1(Type*, Type*, int);
void ifacecheck(Type*, Type*, int, int);
void runifacechecks(void);
Node* convas(Node*, Node**);
Node* convas(Node*, NodeList**);
void arrayconv(Type*, Node*);
Node* colas(Node*, Node*, Node**);
Node* colas(NodeList*, NodeList*);
Node* dorange(Node*);
Node* reorder1(Node*);
Node* reorder3(Node*);
Node* reorder4(Node*);
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**);
NodeList* reorder1(NodeList*);
NodeList* reorder3(NodeList*);
NodeList* reorder4(NodeList*);
Node* structlit(Node*, Node*, NodeList**);
Node* arraylit(Node*, Node*, NodeList**);
Node* maplit(Node*, Node*, NodeList**);
Node* selectas(Node*, Node*, NodeList**);
Node* old2new(Node*, Type*, NodeList**);
void addrescapes(Node*);
void heapmoves(void);
......@@ -1044,6 +1055,7 @@ void cgen_proc(Node *n, int proc);
void checklabels(void);
Label* findlab(Sym *s);
void gen(Node *n);
void genlist(NodeList *l);
void newlab(int op, Sym *s);
Node* sysfunc(char *name);
Plist* newplist(void);
......
This diff is collapsed.
......@@ -94,12 +94,6 @@ main(int argc, char *argv[])
typelist = mal(sizeof(*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;
yyparse();
runifacechecks();
......
......@@ -90,10 +90,11 @@ lsort(Sig *l, int(*f)(Sig*, Sig*))
static Type*
methodfunc(Type *f)
{
Node *in, *out, *d;
NodeList *in, *out;
Node *d;
Type *t;
in = N;
in = nil;
if(!isifacemethod(f)) {
d = nod(ODCLFIELD, N, N);
d->type = getthisx(f->type)->type->type;
......@@ -105,14 +106,14 @@ methodfunc(Type *f)
in = list(in, d);
}
out = N;
out = nil;
for(t=getoutargx(f->type)->type; t; t=t->down) {
d = nod(ODCLFIELD, N, N);
d->type = t->type;
out = list(out, d);
}
return functype(N, rev(in), rev(out));
return functype(N, in, out);
}
/*
......
......@@ -6,7 +6,7 @@
static struct
{
Node* list;
NodeList* list;
Node* mapname;
Type* type;
} xxx;
......@@ -59,35 +59,25 @@ typeclass(Type *t)
}
void
initlin(Node* n)
initlin(NodeList *l)
{
Node *n;
loop:
if(n == N)
return;
initlin(n->ninit);
switch(n->op) {
default:
print("o = %O\n", n->op);
n->ninit = N;
xxx.list = list(xxx.list, n);
break;
case OCALL:
// call to mapassign1
n->ninit = N;
for(; l; l=l->next) {
n = l->n;
initlin(n->ninit);
n->ninit = nil;
xxx.list = list(xxx.list, n);
break;
case OAS:
n->ninit = N;
xxx.list = list(xxx.list, n);
break;
case OLIST:
initlin(n->left);
n = n->right;
goto loop;
switch(n->op) {
default:
print("o = %O\n", n->op);
break;
case OCALL:
// call to mapassign1
case OAS:
break;
}
}
}
......@@ -115,23 +105,22 @@ sametmp(Node *n1, Node *n2)
Node*
findarg(Node *n, char *arg, char *fn)
{
Iter param;
Node *a;
NodeList *l;
if(n == N || n->op != OCALL ||
n->left == N || n->left->sym == S ||
strcmp(n->left->sym->name, fn) != 0)
return N;
a = listfirst(&param, &n->right);
while(a != N) {
for(l=n->list; l; l=l->next) {
a = l->n;
if(a->op == OAS &&
a->left != N && a->right != N &&
a->left->op == OINDREG &&
a->left->sym != S)
if(strcmp(a->left->sym->name, arg) == 0)
return a->right;
a = listnext(&param);
}
return N;
}
......@@ -226,7 +215,7 @@ no:
Node*
mapindex(Node *n)
{
Node *index, *val, *key, *a, *b;
Node *index, *val, *key, *a, *b, *r;
// pull all the primatives
key = findarg(n, "key", "mapassign1");
......@@ -248,10 +237,9 @@ mapindex(Node *n)
b = nod(ODOT, b, newname(lookup("val")));
b = nod(OAS, b, val);
a = nod(OLIST, a, b);
walkexpr(a, Etop, nil);
return a;
r = liststmt(list(list1(a), b));
walkstmt(r);
return r;
}
// for a copy out reference, A = B,
......@@ -261,8 +249,8 @@ mapindex(Node *n)
void
initsub(Node *n, Node *nam)
{
Iter iter;
Node *r, *w, *c;
NodeList *l;
int class, state;
// we could probably get a little more
......@@ -287,7 +275,8 @@ initsub(Node *n, Node *nam)
return;
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)
continue;
......@@ -326,7 +315,8 @@ str:
return;
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)
continue;
......@@ -366,7 +356,8 @@ ary:
sli:
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)
continue;
......@@ -411,7 +402,8 @@ sli:
map:
return;
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) {
// middle usage "(CALL mapassign1 key, val, map)"
c = mapindex(r);
......@@ -454,27 +446,23 @@ return;
}
Node*
initfix(Node* n)
NodeList*
initfix(NodeList *l)
{
Iter iter;
Node *r;
xxx.list = N;
initlin(n);
xxx.list = rev(xxx.list);
xxx.list = nil;
initlin(l);
if(0)
return xxx.list;
// look for the copy-out reference
r = listfirst(&iter, &xxx.list);
while(r != N) {
for(l=xxx.list; l; l=l->next) {
r = l->n;
if(r->op == OAS)
if(inittmp(r->right)) {
if(inittmp(r->right))
initsub(r->left, r->right);
}
r = listnext(&iter);
}
return xxx.list;
}
......@@ -215,7 +215,7 @@ restrictlookup(char *name, char *pkg)
yyerror("cannot refer to %s.%s", pkg, name);
return pkglookup(name, pkg);
}
// find all the exported symbols in package opkg
// and make them available in the current package
......@@ -381,16 +381,6 @@ iskeytype(Type *t)
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*
typ(int et)
{
......@@ -461,80 +451,16 @@ nodbool(int b)
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*
aindex(Node *b, Type *t)
{
Node *top;
NodeList *init;
Type *r;
int bound;
bound = -1; // open bound
top = N;
walkexpr(b, Erv, &top);
init = nil;
walkexpr(b, Erv, &init);
if(b != nil) {
switch(consttype(b)) {
default:
......@@ -566,38 +492,35 @@ indent(int dep)
}
void
dodump(Node *n, int dep)
dodumplist(NodeList *l, int dep)
{
for(; l; l=l->next)
dodump(l->n, dep);
}
loop:
void
dodump(Node *n, int dep)
{
if(n == N)
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);
if(dep > 10) {
print("...\n");
return;
}
if(n->ninit != N) {
if(n->ninit != nil) {
print("%O-init\n", n->op);
dodump(n->ninit, dep+1);
dodumplist(n->ninit, dep+1);
indent(dep);
}
switch(n->op) {
default:
print("%N\n", n);
dodump(n->left, dep+1);
dodump(n->right, dep+1);
break;
case OTYPE:
......@@ -607,32 +530,32 @@ loop:
case OIF:
print("%O%J\n", n->op, n);
dodump(n->ntest, dep+1);
if(n->nbody != N) {
if(n->nbody != nil) {
indent(dep);
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);
print("%O-else\n", n->op);
dodump(n->nelse, dep+1);
dodumplist(n->nelse, dep+1);
}
return;
break;
case OSELECT:
print("%O%J\n", n->op, n);
dodump(n->nbody, dep+1);
return;
dodumplist(n->nbody, dep+1);
break;
case OSWITCH:
case OFOR:
print("%O%J\n", n->op, n);
dodump(n->ntest, dep+1);
if(n->nbody != N) {
if(n->nbody != nil) {
indent(dep);
print("%O-body\n", n->op);
dodump(n->nbody, dep+1);
dodumplist(n->nbody, dep+1);
}
if(n->nincr != N) {
......@@ -640,7 +563,7 @@ loop:
print("%O-incr\n", n->op);
dodump(n->nincr, dep+1);
}
return;
break;
case OCASE:
// the right side points to label of the body
......@@ -649,13 +572,26 @@ loop:
else
print("%O%J\n", n->op, n);
dodump(n->left, dep+1);
return;
break;
}
dodump(n->left, dep+1);
n = n->right;
dep++;
goto loop;
if(n->list != nil) {
indent(dep);
print("%O-list\n", n->op);
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
......@@ -687,7 +623,9 @@ opnames[] =
[OARRAY] = "ARRAY",
[OASOP] = "ASOP",
[OAS] = "AS",
[OAS2] = "AS2",
[OBAD] = "BAD",
[OBLOCK] = "BLOCK",
[OBREAK] = "BREAK",
[OCALLINTER] = "CALLINTER",
[OCALLMETH] = "CALLMETH",
......@@ -735,7 +673,6 @@ opnames[] =
[OLABEL] = "LABEL",
[OLEN] = "LEN",
[OLE] = "LE",
[OLIST] = "LIST",
[OLITERAL] = "LITERAL",
[OLSH] = "LSH",
[OLT] = "LT",
......@@ -1422,6 +1359,7 @@ treecopy(Node *n)
*m = *n;
m->left = treecopy(n->left);
m->right = treecopy(n->right);
m->list = listtreecopy(n->list);
break;
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
*/
......@@ -2285,63 +2195,6 @@ funcnext(Iter *s)
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**
getthis(Type *t)
{
......@@ -2475,7 +2328,7 @@ staticname(Type *t)
* return side effect-free n, appending side effects to init.
*/
Node*
saferef(Node *n, Node **init)
saferef(Node *n, NodeList **init)
{
Node *l;
Node *r;
......@@ -2657,13 +2510,13 @@ out:
Node*
adddot(Node *n)
{
Node *top;
NodeList *init;
Type *t;
Sym *s;
int c, d;
top = N;
walkexpr(n->left, Erv, &top);
init = nil;
walkexpr(n->left, Erv, &init);
t = n->left->type;
if(t == T)
goto ret;
......@@ -2691,8 +2544,7 @@ out:
n->left->right = newname(dotlist[c].field->sym);
}
ret:
if(top != N)
n->ninit = list(top, n->ninit);
n->ninit = concat(init, n->ninit);
return n;
}
......@@ -2847,16 +2699,17 @@ expandmeth(Sym *s, Type *t)
/*
* Given funarg struct list, return list of ODCLFIELD Node fn args.
*/
Node*
NodeList*
structargs(Type **tl, int mustname)
{
Iter savet;
Node *args, *a;
Node *a;
NodeList *args;
Type *t;
char nam[100];
int n;
args = N;
args = nil;
n = 0;
for(t = structfirst(&savet, tl); t != T; t = structnext(&savet)) {
if(t->sym)
......@@ -2869,7 +2722,6 @@ structargs(Type **tl, int mustname)
a = anondcl(t->type);
args = list(args, a);
}
args = rev(args);
return args;
}
......@@ -2899,9 +2751,8 @@ structargs(Type **tl, int mustname)
void
genwrapper(Type *rcvr, Type *method, Sym *newnam)
{
Node *this, *in, *out, *fn, *args, *call;
Node *l;
Iter savel;
Node *this, *fn, *call, *n;
NodeList *l, *args, *in, *out;
if(debug['r'])
print("genwrapper rcvrtype=%T method=%T newnam=%S\n",
......@@ -2920,19 +2771,22 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam)
funchdr(fn);
// arg list
args = N;
for(l = listfirst(&savel, &in); l; l = listnext(&savel))
args = list(args, l->left);
args = rev(args);
args = nil;
for(l=in; l; l=l->next)
args = list(args, l->n->left);
// generate call
call = nod(OCALL, adddot(nod(ODOT, this->left, newname(method->sym))), args);
fn->nbody = call;
if(method->type->outtuple > 0)
fn->nbody = nod(ORETURN, call, N);
call = nod(OCALL, adddot(nod(ODOT, this->left, newname(method->sym))), N);
call->list = args;
fn->nbody = list1(call);
if(method->type->outtuple > 0) {
n = nod(ORETURN, N, N);
n->list = fn->nbody;
fn->nbody = list1(n);
}
if(debug['r'])
dump("genwrapper body", fn->nbody);
dumplist("genwrapper body", fn->nbody);
funcbody(fn);
}
......@@ -3137,3 +2991,71 @@ simsimtype(Type *t)
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;
}
......@@ -305,33 +305,27 @@ sw3(Node *c, Type *place, int arg)
Type*
walkcases(Node *sw, Type*(*call)(Node*, Type*, int arg), int arg)
{
Iter save;
Node *n;
NodeList *l;
Type *place;
int32 lno;
lno = setlineno(sw);
place = call(sw->ntest, T, arg);
n = listfirst(&save, &sw->nbody->left);
if(n == N || n->op == OEMPTY)
return T;
for(l=sw->list; l; l=l->next) {
n = l->n;
loop:
if(n == N) {
lineno = lno;
return place;
}
if(n->op != OCASE)
fatal("walkcases: not case %O\n", n->op);
if(n->op != OCASE)
fatal("walkcases: not case %O\n", n->op);
if(n->left != N && !n->diag) {
setlineno(n);
place = call(n->left, place, arg);
if(n->left != N && !n->diag) {
setlineno(n);
place = call(n->left, place, arg);
}
}
n = listnext(&save);
goto loop;
lineno = lno;
return place;
}
Node*
......@@ -352,35 +346,32 @@ newlabel(void)
void
casebody(Node *sw)
{
Iter save, save1;
Node *os, *oc, *n, *n1, *c;
Node *cas, *stat, *def;
Node *os, *oc, *n, *c, *last;
Node *def;
NodeList *cas, *stat, *l, *lc;
Node *go, *br;
int32 lno;
lno = setlineno(sw);
n = listfirst(&save, &sw->nbody);
if(n == N || n->op == OEMPTY) {
sw->nbody = nod(OLIST, N, N);
if(sw->list == nil)
return;
}
cas = N; // cases
stat = N; // statements
cas = nil; // cases
stat = nil; // statements
def = N; // defaults
os = N; // last statement
oc = N; // last case
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);
if(n->op != OXCASE)
fatal("casebody %O", n->op);
n->op = OCASE;
go = nod(OGOTO, newlabel(), N);
c = n->left;
if(c == N) {
if(n->list == nil) {
if(def != N)
yyerror("more than one default case");
// reuse original default case
......@@ -388,105 +379,97 @@ casebody(Node *sw)
def = n;
}
// expand multi-valued cases
for(; c!=N; c=c->right) {
if(c->op != OLIST) {
// reuse original case
n->left = c;
n->right = go;
cas = list(cas, n);
break;
if(n->list != nil && n->list->next == nil) {
// one case - reuse OCASE node.
c = n->list->n;
n->left = c;
n->right = go;
n->list = nil;
cas = list(cas, n);
} 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));
os = N;
for(n1 = listfirst(&save1, &n->nbody); n1 != N; n1 = listnext(&save1)) {
os = n1;
stat = list(stat, n1);
}
stat = concat(stat, n->nbody);
// botch - shouldnt fall thru declaration
if(os != N && os->op == OXFALL)
os->op = OFALL;
last = stat->end->n;
if(last->op == OXFALL)
last->op = OFALL;
else
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));
//dump("case", sw->nbody->left);
//dump("stat", sw->nbody->right);
sw->list = cas;
sw->nbody = stat;
lineno = lno;
}
Case*
mkcaselist(Node *sw, int arg)
{
Iter save;
Node *n;
Case *c, *c1;
NodeList *l;
int ord;
c = C;
ord = 0;
n = listfirst(&save, &sw->nbody->left);
loop:
if(n == N)
goto done;
c1 = mal(sizeof(*c1));
c1->link = c;
c = c1;
for(l=sw->list; l; l=l->next) {
n = l->n;
c1 = mal(sizeof(*c1));
c1->link = c;
c = c1;
ord++;
c->ordinal = ord;
c->node = n;
ord++;
c->ordinal = ord;
c->node = n;
if(n->left == N) {
c->type = Tdefault;
goto next;
}
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;
if(n->left == N) {
c->type = Tdefault;
continue;
}
c->hash = typehash(n->left->left->type, 1, 0);
c->type = Ttypeconst;
goto next;
switch(arg) {
case Stype:
c->hash = 0;
if(n->left->left == N) {
c->type = Ttypenil;
continue;
}
if(istype(n->left->left->type, TINTER)) {
c->type = Ttypevar;
continue;
}
case Snorm:
case Strue:
case Sfalse:
c->type = Texprvar;
switch(consttype(n->left)) {
case CTFLT:
case CTINT:
case CTSTR:
c->type = Texprconst;
c->hash = typehash(n->left->left->type, 1, 0);
c->type = Ttypeconst;
continue;
case Snorm:
case Strue:
case Sfalse:
c->type = Texprvar;
switch(consttype(n->left)) {
case CTFLT:
case CTINT:
case CTSTR:
c->type = Texprconst;
}
continue;
}
goto next;
}
next:
n = listnext(&save);
goto loop;
done:
if(c == C)
return C;
......@@ -528,12 +511,12 @@ static Node* exprname;
Node*
exprbsw(Case *c0, int ncase, int arg)
{
Node *cas;
NodeList *cas;
Node *a, *n;
Case *c;
int i, half, lno;
cas = N;
cas = nil;
if(ncase < Ncase) {
for(i=0; i<ncase; i++) {
n = c0->node;
......@@ -543,19 +526,19 @@ exprbsw(Case *c0, int ncase, int arg)
case Strue:
a = nod(OIF, N, N);
a->ntest = n->left; // if val
a->nbody = n->right; // then goto l
a->nbody = list1(n->right); // then goto l
break;
case Sfalse:
a = nod(OIF, N, N);
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;
default:
a = nod(OIF, N, N);
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;
}
......@@ -563,7 +546,7 @@ exprbsw(Case *c0, int ncase, int arg)
c0 = c0->link;
lineno = lno;
}
return cas;
return liststmt(cas);
}
// find the middle and recur
......@@ -573,8 +556,8 @@ exprbsw(Case *c0, int ncase, int arg)
c = c->link;
a = nod(OIF, N, N);
a->ntest = nod(OLE, exprname, c->node->left);
a->nbody = exprbsw(c0, half, arg);
a->nelse = exprbsw(c->link, ncase-half, arg);
a->nbody = list1(exprbsw(c0, half, arg));
a->nelse = list1(exprbsw(c->link, ncase-half, arg));
return a;
}
......@@ -585,7 +568,8 @@ exprbsw(Case *c0, int ncase, int arg)
void
exprswitch(Node *sw)
{
Node *def, *cas;
Node *def;
NodeList *cas;
Node *a;
Case *c0, *c, *c1;
Type *t;
......@@ -620,11 +604,11 @@ exprswitch(Node *sw)
* convert the switch into OIF statements
*/
exprname = N;
cas = N;
cas = nil;
if(arg != Strue && arg != Sfalse) {
exprname = nod(OXXX, N, N);
tempname(exprname, sw->ntest->type);
cas = nod(OAS, exprname, sw->ntest);
cas = list1(nod(OAS, exprname, sw->ntest));
}
c0 = mkcaselist(sw, arg);
......@@ -638,8 +622,9 @@ exprswitch(Node *sw)
loop:
if(c0 == C) {
cas = list(cas, def);
sw->nbody->left = rev(cas);
walkstmt(sw->nbody);
sw->nbody = concat(cas, sw->nbody);
sw->list = nil;
walkstmtlist(sw->nbody);
return;
}
......@@ -680,34 +665,36 @@ static Node* boolname;
Node*
typeone(Node *t)
{
Node *a, *b, *dcl;
a = t->left->left; // var
dcl = nod(ODCL, a, N);
NodeList *init;
Node *a, *b, *var;
a = nod(OLIST, a, boolname); // var,bool
var = t->left->left;
init = list1(nod(ODCL, var, N));
a = nod(OAS2, N, N);
a->list = list(list1(var), boolname); // var,bool =
b = nod(ODOTTYPE, facename, N);
b->type = t->left->left->type; // interface.(type)
a = nod(OAS, a, b); // var,bool = interface.(type)
b->type = t->left->left->type; // interface.(type)
a->rlist = list1(b);
init = list(init, a);
b = nod(OIF, N, N);
b->ntest = boolname;
b->nbody = t->right; // if bool { goto l }
return list(list(dcl, a), b);
b->nbody = list1(t->right); // if bool { goto l }
a = liststmt(list(init, b));
return a;
}
Node*
typebsw(Case *c0, int ncase)
{
Node *cas;
NodeList *cas;
Node *a, *n;
Case *c;
int i, half;
Val v;
cas = N;
cas = nil;
if(ncase < Ncase) {
for(i=0; i<ncase; i++) {
......@@ -719,7 +706,7 @@ typebsw(Case *c0, int ncase)
v.ctype = CTNIL;
a = nod(OIF, N, N);
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);
break;
......@@ -731,13 +718,13 @@ typebsw(Case *c0, int ncase)
case Ttypeconst:
a = nod(OIF, N, N);
a->ntest = nod(OEQ, hashname, nodintconst(c0->hash));
a->nbody = rev(typeone(n));
a->nbody = list1(typeone(n));
cas = list(cas, a);
break;
}
c0 = c0->link;
}
return cas;
return liststmt(cas);
}
// find the middle and recur
......@@ -747,8 +734,8 @@ typebsw(Case *c0, int ncase)
c = c->link;
a = nod(OIF, N, N);
a->ntest = nod(OLE, hashname, nodintconst(c->hash));
a->nbody = typebsw(c0, half);
a->nelse = typebsw(c->link, ncase-half);
a->nbody = list1(typebsw(c0, half));
a->nelse = list1(typebsw(c->link, ncase-half));
return a;
}
......@@ -760,7 +747,8 @@ typebsw(Case *c0, int ncase)
void
typeswitch(Node *sw)
{
Node *cas, *def;
Node *def;
NodeList *cas;
Node *a;
Case *c, *c0, *c1;
int ncase;
......@@ -779,7 +767,7 @@ typeswitch(Node *sw)
return;
}
walkcases(sw, sw0, Stype);
cas = N;
cas = nil;
/*
* predeclare temporary variables
......@@ -802,7 +790,8 @@ typeswitch(Node *sw)
else
a = syslook("ifacethash", 1);
argtype(a, t);
a = nod(OCALL, a, facename);
a = nod(OCALL, a, N);
a->list = list1(facename);
a = nod(OAS, hashname, a);
cas = list(cas, a);
......@@ -817,8 +806,9 @@ typeswitch(Node *sw)
loop:
if(c0 == C) {
cas = list(cas, def);
sw->nbody->left = rev(cas);
walkstmt(sw->nbody);
sw->nbody = concat(cas, sw->nbody);
sw->list = nil;
walkstmtlist(sw->nbody);
return;
}
......@@ -860,7 +850,7 @@ walkswitch(Node *sw)
* cases have OGOTO into statements.
* both have inserted OBREAK statements
*/
walkstmt(sw->ninit);
walkstmtlist(sw->ninit);
if(sw->ntest == N)
sw->ntest = nodbool(1);
casebody(sw);
......
......@@ -67,7 +67,6 @@ func mapiter2(hiter *any) (key any, val any);
func newchan(elemsize int, elemalg int, hint int) (hchan chan any);
func chanrecv1(hchan <-chan any) (elem any);
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 chansend2(hchan chan<- any, elem any) (pres bool);
func closechan(hchan any);
......
This diff is collapsed.
......@@ -431,13 +431,6 @@ sys·chanrecv2(Hchan* c, ...)
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);
void
sys·newselect(int32 size, ...)
......
......@@ -99,8 +99,7 @@ throw: interface conversion
panic PC=xxx
=========== 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
=========== bugs/bug162.go
......
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