mirror of
https://github.com/golang/go.git
synced 2025-05-14 11:54:38 +00:00
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:
parent
9b475bd2a4
commit
e52e9ca82e
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
350
src/cmd/gc/dcl.c
350
src/cmd/gc/dcl.c
@ -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;
|
|
||||||
|
|
||||||
while(v != N) {
|
|
||||||
if(ee != N && e == N) {
|
|
||||||
yyerror("missing expr in var dcl");
|
yyerror("missing expr in var dcl");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
e = el->n;
|
||||||
|
el = el->next;
|
||||||
|
} 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);
|
||||||
|
if(a != N)
|
||||||
r = list(r, a);
|
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,40 +1665,33 @@ 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 = cc;
|
lastconst = cl;
|
||||||
lasttype = t;
|
lasttype = t;
|
||||||
vv = rev(vv);
|
|
||||||
cc = rev(treecopy(cc));
|
|
||||||
|
|
||||||
v = listfirst(&viter, &vv);
|
|
||||||
c = listfirst(&citer, &cc);
|
|
||||||
|
|
||||||
loop:
|
|
||||||
if(v == N && c == N) {
|
|
||||||
iota += 1;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
cl = listtreecopy(cl);
|
||||||
|
|
||||||
if(v == N || c == N) {
|
for(; vl; vl=vl->next) {
|
||||||
yyerror("shape error in const dcl");
|
if(cl == nil) {
|
||||||
iota += 1;
|
yyerror("missing expr in const dcl");
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
c = cl->n;
|
||||||
|
cl = cl->next;
|
||||||
|
|
||||||
init = N;
|
init = nil;
|
||||||
gettype(c, &init);
|
gettype(c, &init);
|
||||||
if(init != N) {
|
if(init != nil) {
|
||||||
// the expression had extra code to run.
|
// the expression had extra code to run.
|
||||||
// dodclconst is going to print an error
|
// dodclconst is going to print an error
|
||||||
// because the expression isn't constant,
|
// because the expression isn't constant,
|
||||||
@ -1770,11 +1703,13 @@ loop:
|
|||||||
convlit(c, t);
|
convlit(c, t);
|
||||||
if(t == T)
|
if(t == T)
|
||||||
lasttype = c->type;
|
lasttype = c->type;
|
||||||
dodclconst(v, c);
|
|
||||||
|
|
||||||
v = listnext(&viter);
|
v = vl->n;
|
||||||
c = listnext(&citer);
|
dodclconst(v, c);
|
||||||
goto loop;
|
}
|
||||||
|
if(cl != nil)
|
||||||
|
yyerror("extra expr in const dcl");
|
||||||
|
iota += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -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));
|
||||||
|
@ -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)
|
||||||
|
120
src/cmd/gc/go.h
120
src/cmd/gc/go.h
@ -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);
|
||||||
|
697
src/cmd/gc/go.y
697
src/cmd/gc/go.y
File diff suppressed because it is too large
Load Diff
@ -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();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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;
|
||||||
|
xxx.list = list(xxx.list, n);
|
||||||
switch(n->op) {
|
switch(n->op) {
|
||||||
default:
|
default:
|
||||||
print("o = %O\n", n->op);
|
print("o = %O\n", n->op);
|
||||||
n->ninit = N;
|
|
||||||
xxx.list = list(xxx.list, n);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OCALL:
|
case OCALL:
|
||||||
// call to mapassign1
|
// call to mapassign1
|
||||||
n->ninit = N;
|
|
||||||
xxx.list = list(xxx.list, n);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OAS:
|
case OAS:
|
||||||
n->ninit = N;
|
|
||||||
xxx.list = list(xxx.list, n);
|
|
||||||
break;
|
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(¶m, &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(¶m);
|
|
||||||
}
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
174
src/cmd/gc/swt.c
174
src/cmd/gc/swt.c
@ -305,23 +305,16 @@ 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 == N) {
|
|
||||||
lineno = lno;
|
|
||||||
return place;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(n->op != OCASE)
|
if(n->op != OCASE)
|
||||||
fatal("walkcases: not case %O\n", n->op);
|
fatal("walkcases: not case %O\n", n->op);
|
||||||
@ -330,8 +323,9 @@ loop:
|
|||||||
setlineno(n);
|
setlineno(n);
|
||||||
place = call(n->left, place, arg);
|
place = call(n->left, place, arg);
|
||||||
}
|
}
|
||||||
n = listnext(&save);
|
}
|
||||||
goto loop;
|
lineno = lno;
|
||||||
|
return place;
|
||||||
}
|
}
|
||||||
|
|
||||||
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,59 +379,54 @@ 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);
|
||||||
|
if(def)
|
||||||
cas = list(cas, 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;
|
||||||
loop:
|
|
||||||
if(n == N)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
c1 = mal(sizeof(*c1));
|
c1 = mal(sizeof(*c1));
|
||||||
c1->link = c;
|
c1->link = c;
|
||||||
c = c1;
|
c = c1;
|
||||||
@ -451,7 +437,7 @@ loop:
|
|||||||
|
|
||||||
if(n->left == N) {
|
if(n->left == N) {
|
||||||
c->type = Tdefault;
|
c->type = Tdefault;
|
||||||
goto next;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(arg) {
|
switch(arg) {
|
||||||
@ -459,16 +445,16 @@ loop:
|
|||||||
c->hash = 0;
|
c->hash = 0;
|
||||||
if(n->left->left == N) {
|
if(n->left->left == N) {
|
||||||
c->type = Ttypenil;
|
c->type = Ttypenil;
|
||||||
goto next;
|
continue;
|
||||||
}
|
}
|
||||||
if(istype(n->left->left->type, TINTER)) {
|
if(istype(n->left->left->type, TINTER)) {
|
||||||
c->type = Ttypevar;
|
c->type = Ttypevar;
|
||||||
goto next;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->hash = typehash(n->left->left->type, 1, 0);
|
c->hash = typehash(n->left->left->type, 1, 0);
|
||||||
c->type = Ttypeconst;
|
c->type = Ttypeconst;
|
||||||
goto next;
|
continue;
|
||||||
|
|
||||||
case Snorm:
|
case Snorm:
|
||||||
case Strue:
|
case Strue:
|
||||||
@ -480,13 +466,10 @@ loop:
|
|||||||
case CTSTR:
|
case CTSTR:
|
||||||
c->type = Texprconst;
|
c->type = Texprconst;
|
||||||
}
|
}
|
||||||
goto next;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
@ -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);
|
||||||
|
1594
src/cmd/gc/walk.c
1594
src/cmd/gc/walk.c
File diff suppressed because it is too large
Load Diff
@ -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, ...)
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user