Commit db508ccb authored by Russ Cox's avatar Russ Cox

baby step: const decls can refer to future

consts in the same factored block

	const (
		X = Y;
		Y = 2;
	)

R=ken
OCL=31782
CL=31782
parent 2ac1528e
...@@ -618,7 +618,7 @@ bgen(Node *n, int true, Prog *to) ...@@ -618,7 +618,7 @@ bgen(Node *n, int true, Prog *to)
nr = n->right; nr = n->right;
if(n->type == T) { if(n->type == T) {
convlit(n, types[TBOOL]); convlit(&n, types[TBOOL]);
if(n->type == T) if(n->type == T)
goto ret; goto ret;
} }
......
...@@ -53,24 +53,39 @@ truncfltlit(Mpflt *oldv, Type *t) ...@@ -53,24 +53,39 @@ truncfltlit(Mpflt *oldv, Type *t)
* implicit conversion. * implicit conversion.
*/ */
void void
convlit(Node *n, Type *t) convlit(Node **np, Type *t)
{ {
convlit1(n, t, 0); return convlit1(np, t, 0);
} }
/* /*
* convert n, if literal, to type t. * convert n, if literal, to type t.
* return a new node if necessary
* (if n is a named constant, can't edit n->type directly).
*/ */
void void
convlit1(Node *n, Type *t, int explicit) convlit1(Node **np, Type *t, int explicit)
{ {
int et, ct; int et, ct;
Node *n, *nn;
n = *np;
if(n == N || t == T || n->type == T) if(n == N || t == T || n->type == T)
return; return;
et = t->etype; et = t->etype;
if(et == TIDEAL || et == TNIL) if(et == TIDEAL || et == TNIL)
return; return;
if(eqtype(t, n->type))
return;
//dump("convlit1", n);
if(n->op == OLITERAL) {
nn = nod(OXXX, N, N);
*nn = *n;
n = nn;
*np = n;
}
//dump("convlit2", n);
switch(n->op) { switch(n->op) {
default: default:
...@@ -79,7 +94,7 @@ convlit1(Node *n, Type *t, int explicit) ...@@ -79,7 +94,7 @@ convlit1(Node *n, Type *t, int explicit)
break; break;
case OLSH: case OLSH:
case ORSH: case ORSH:
convlit(n->left, t); convlit(&n->left, t);
n->type = n->left->type; n->type = n->left->type;
return; return;
} }
...@@ -98,7 +113,7 @@ convlit1(Node *n, Type *t, int explicit) ...@@ -98,7 +113,7 @@ convlit1(Node *n, Type *t, int explicit)
n->type = t; n->type = t;
return; return;
} }
defaultlit(n, T); defaultlit(np, T);
return; return;
} }
...@@ -172,8 +187,10 @@ convlit1(Node *n, Type *t, int explicit) ...@@ -172,8 +187,10 @@ convlit1(Node *n, Type *t, int explicit)
return; return;
bad: bad:
if(n->type->etype == TIDEAL) if(n->type->etype == TIDEAL) {
defaultlit(n, T); defaultlit(&n, T);
*np = n;
}
yyerror("cannot convert %T constant to %T", n->type, t); yyerror("cannot convert %T constant to %T", n->type, t);
n->diag = 1; n->diag = 1;
return; return;
...@@ -332,10 +349,14 @@ evconst(Node *n) ...@@ -332,10 +349,14 @@ evconst(Node *n)
switch(n->op) { switch(n->op) {
default: default:
// ideal const mixes with anything but otherwise must match. // ideal const mixes with anything but otherwise must match.
if(nl->type->etype != TIDEAL) if(nl->type->etype != TIDEAL) {
defaultlit(nr, nl->type); defaultlit(&nr, nl->type);
if(nr->type->etype != TIDEAL) n->right = nr;
defaultlit(nl, nr->type); }
if(nr->type->etype != TIDEAL) {
defaultlit(&nl, nr->type);
n->left = nl;
}
if(nl->type->etype != nr->type->etype) if(nl->type->etype != nr->type->etype)
goto illegal; goto illegal;
break; break;
...@@ -344,7 +365,8 @@ evconst(Node *n) ...@@ -344,7 +365,8 @@ evconst(Node *n)
case ORSH: case ORSH:
// right must be unsigned. // right must be unsigned.
// left can be ideal. // left can be ideal.
defaultlit(nr, types[TUINT]); defaultlit(&nr, types[TUINT]);
n->right = nr;
if(nr->type && (issigned[nr->type->etype] || !isint[nr->type->etype])) if(nr->type && (issigned[nr->type->etype] || !isint[nr->type->etype]))
goto illegal; goto illegal;
break; break;
...@@ -656,10 +678,12 @@ nodlit(Val v) ...@@ -656,10 +678,12 @@ nodlit(Val v)
} }
void void
defaultlit(Node *n, Type *t) defaultlit(Node **np, Type *t)
{ {
int lno; int lno;
Node *n, *nn;
n = *np;
if(n == N) if(n == N)
return; return;
if(n->type == T || n->type->etype != TIDEAL) if(n->type == T || n->type->etype != TIDEAL)
...@@ -667,10 +691,14 @@ defaultlit(Node *n, Type *t) ...@@ -667,10 +691,14 @@ defaultlit(Node *n, Type *t)
switch(n->op) { switch(n->op) {
case OLITERAL: case OLITERAL:
nn = nod(OXXX, N, N);
*nn = *n;
n = nn;
*np = n;
break; break;
case OLSH: case OLSH:
case ORSH: case ORSH:
defaultlit(n->left, t); defaultlit(&n->left, t);
n->type = n->left->type; n->type = n->left->type;
return; return;
} }
...@@ -715,25 +743,29 @@ defaultlit(Node *n, Type *t) ...@@ -715,25 +743,29 @@ defaultlit(Node *n, Type *t)
* get the same type going out. * get the same type going out.
*/ */
void void
defaultlit2(Node *l, Node *r) defaultlit2(Node **lp, Node **rp)
{ {
Node *l, *r;
l = *lp;
r = *rp;
if(l->type == T || r->type == T) if(l->type == T || r->type == T)
return; return;
if(l->type->etype != TIDEAL && l->type->etype != TNIL) { if(l->type->etype != TIDEAL && l->type->etype != TNIL) {
convlit(r, l->type); convlit(rp, l->type);
return; return;
} }
if(r->type->etype != TIDEAL && r->type->etype != TNIL) { if(r->type->etype != TIDEAL && r->type->etype != TNIL) {
convlit(l, r->type); convlit(lp, r->type);
return; return;
} }
if(isconst(l, CTFLT) || isconst(r, CTFLT)) { if(isconst(l, CTFLT) || isconst(r, CTFLT)) {
convlit(l, types[TFLOAT]); convlit(lp, types[TFLOAT]);
convlit(r, types[TFLOAT]); convlit(rp, types[TFLOAT]);
return; return;
} }
convlit(l, types[TINT]); convlit(lp, types[TINT]);
convlit(r, types[TINT]); convlit(rp, types[TINT]);
} }
int int
......
...@@ -43,6 +43,7 @@ dodclvar(Node *n, Type *t, NodeList **init) ...@@ -43,6 +43,7 @@ dodclvar(Node *n, Type *t, NodeList **init)
*init = list(*init, nod(ODCL, n, N)); *init = list(*init, nod(ODCL, n, N));
} }
// TODO(rsc): cut
void void
dodclconst(Node *n, Node *e) dodclconst(Node *n, Node *e)
{ {
...@@ -513,8 +514,8 @@ funcbody(Node *n) ...@@ -513,8 +514,8 @@ funcbody(Node *n)
dclcontext = PEXTERN; dclcontext = PEXTERN;
} }
void Node*
funclit0(Type *t) funclit0(Node *t)
{ {
Node *n; Node *n;
...@@ -527,19 +528,23 @@ funclit0(Type *t) ...@@ -527,19 +528,23 @@ funclit0(Type *t)
autodcl = dcl(); autodcl = dcl();
autodcl->back = autodcl; autodcl->back = autodcl;
funcargs(t); walkexpr(t, Etype, &t->ninit);
funcargs(t->type);
return t;
} }
Node* Node*
funclit1(Type *type, NodeList *body) funclit1(Node *ntype, NodeList *body)
{ {
Node *func; Node *func;
Type *type;
Node *a, *d, *f, *n, *clos; 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; NodeList *args, *l, *in, *out;
type = ntype->type;
popdcl(); popdcl();
func = funclit; func = funclit;
funclit = func->outer; funclit = func->outer;
...@@ -957,7 +962,7 @@ addvar(Node *n, Type *t, int ctxt) ...@@ -957,7 +962,7 @@ addvar(Node *n, Type *t, int ctxt)
Sym *s; Sym *s;
int gen; int gen;
if(n==N || n->sym == S || n->op != ONAME || t == T) if(n==N || n->sym == S || (n->op != ONAME && n->op != ONONAME) || t == T)
fatal("addvar: n=%N t=%T nil", n, t); fatal("addvar: n=%N t=%T nil", n, t);
s = n->sym; s = n->sym;
...@@ -973,6 +978,7 @@ addvar(Node *n, Type *t, int ctxt) ...@@ -973,6 +978,7 @@ addvar(Node *n, Type *t, int ctxt)
} }
redeclare("variable", s); redeclare("variable", s);
n->op = ONAME;
s->vargen = gen; s->vargen = gen;
s->def = n; s->def = n;
s->offset = 0; s->offset = 0;
...@@ -1049,6 +1055,7 @@ addtyp(Type *n, int ctxt) ...@@ -1049,6 +1055,7 @@ addtyp(Type *n, int ctxt)
} }
} }
// TODO(rsc): cut
void void
addconst(Node *n, Node *e, int ctxt) addconst(Node *n, Node *e, int ctxt)
{ {
...@@ -1142,6 +1149,29 @@ newname(Sym *s) ...@@ -1142,6 +1149,29 @@ newname(Sym *s)
return n; return n;
} }
Node*
dclname(Sym *s)
{
Node *n;
// top-level name: might already have been
// referred to, in which case s->def is already
// set to an ONONAME.
if(dclcontext == PEXTERN && s->block == 0) {
// toss predefined name like "close"
// TODO(rsc): put close in at the end.
if(s->def != N && s->def->etype)
s->def = N;
if(s->def == N)
oldname(s);
return s->def;
}
n = newname(s);
n->op = ONONAME; // caller will correct it
return n;
}
Node* Node*
typenod(Type *t) typenod(Type *t)
{ {
...@@ -1168,19 +1198,11 @@ oldname(Sym *s) ...@@ -1168,19 +1198,11 @@ oldname(Sym *s)
n = s->def; n = s->def;
if(n == N) { if(n == N) {
n = nod(ONONAME, N, N); // maybe a top-level name will come along
n->sym = s; // to give this a definition later.
n->type = T; n = newname(s);
n->addable = 1; n->op = ONONAME;
n->ullman = 1; s->def = n;
}
if(n->op == OLITERAL) {
c = nod(OLITERAL, N, N);
c->sym = s;
c->val = n->val;
c->type = n->type;
c->iota = n->iota;
return c;
} }
if(n->funcdepth > 0 && n->funcdepth != funcdepth && n->op == ONAME) { if(n->funcdepth > 0 && n->funcdepth != funcdepth && n->op == ONAME) {
// inner func is referring to var // inner func is referring to var
...@@ -1648,7 +1670,7 @@ variter(NodeList *vl, Type *t, NodeList *el) ...@@ -1648,7 +1670,7 @@ variter(NodeList *vl, Type *t, NodeList *el)
tv = t; tv = t;
if(t == T) { if(t == T) {
gettype(e, &r); gettype(e, &r);
defaultlit(e, T); defaultlit(&e, T);
tv = e->type; tv = e->type;
} }
dodclvar(v, tv, &r); dodclvar(v, tv, &r);
...@@ -1664,14 +1686,16 @@ variter(NodeList *vl, Type *t, NodeList *el) ...@@ -1664,14 +1686,16 @@ variter(NodeList *vl, Type *t, NodeList *el)
* declare constants from grammar * declare constants from grammar
* new_name_list [[type] = expr_list] * new_name_list [[type] = expr_list]
*/ */
void NodeList*
constiter(NodeList *vl, Type *t, NodeList *cl) constiter(NodeList *vl, Node *t, NodeList *cl)
{ {
Node *v, *c; Node *v, *c;
NodeList *init; NodeList *vv;
Sym *s;
vv = vl;
if(cl == nil) { if(cl == nil) {
if(t != T) if(t != N)
yyerror("constdcl cannot have type without expr"); yyerror("constdcl cannot have type without expr");
cl = lastconst; cl = lastconst;
t = lasttype; t = lasttype;
...@@ -1689,27 +1713,22 @@ constiter(NodeList *vl, Type *t, NodeList *cl) ...@@ -1689,27 +1713,22 @@ constiter(NodeList *vl, Type *t, NodeList *cl)
c = cl->n; c = cl->n;
cl = cl->next; cl = cl->next;
init = nil;
gettype(c, &init);
if(init != nil) {
// the expression had extra code to run.
// dodclconst is going to print an error
// because the expression isn't constant,
// but out of paranoia, bump nerrors so
// that compile cannot succeed accidentally
nerrors++;
}
if(t != T)
convlit(c, t);
if(t == T)
lasttype = c->type;
v = vl->n; v = vl->n;
dodclconst(v, c); s = v->sym;
if(dclcontext != PEXTERN)
pushdcl(s);
redeclare("constant", s);
s->def = v;
v->op = OLITERAL;
v->ntype = t;
v->defn = c;
autoexport(s);
} }
if(cl != nil) if(cl != nil)
yyerror("extra expr in const dcl"); yyerror("extra expr in const dcl");
iota += 1; iota += 1;
return vv;
} }
/* /*
......
...@@ -324,7 +324,7 @@ importconst(Sym *s, Type *t, Node *n) ...@@ -324,7 +324,7 @@ importconst(Sym *s, Type *t, Node *n)
if(!exportname(s->name) && !mypackage(s)) if(!exportname(s->name) && !mypackage(s))
return; return;
importsym(s, OLITERAL); importsym(s, OLITERAL);
convlit(n, t); convlit(&n, t);
if(s->def != N) { if(s->def != N) {
// TODO: check if already the same. // TODO: check if already the same.
return; return;
......
...@@ -227,6 +227,10 @@ struct Node ...@@ -227,6 +227,10 @@ struct Node
// OTFUNC // OTFUNC
Node* rcvr; Node* rcvr;
// ONAME
Node* ntype;
Node* defn;
// ONAME func param with PHEAP // ONAME func param with PHEAP
Node* heapaddr; // temp holding heap address of param Node* heapaddr; // temp holding heap address of param
Node* stackparam; // OPARAM node referring to stack copy of param Node* stackparam; // OPARAM node referring to stack copy of param
...@@ -601,7 +605,7 @@ EXTERN int loophack; ...@@ -601,7 +605,7 @@ EXTERN int loophack;
EXTERN uint32 iota; EXTERN uint32 iota;
EXTERN NodeList* lastconst; EXTERN NodeList* lastconst;
EXTERN Type* lasttype; EXTERN Node* lasttype;
EXTERN int32 vargen; EXTERN int32 vargen;
EXTERN int32 exportgen; EXTERN int32 exportgen;
EXTERN int32 maxarg; EXTERN int32 maxarg;
...@@ -831,8 +835,8 @@ void dodclvar(Node*, Type*, NodeList**); ...@@ -831,8 +835,8 @@ 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 structcount(Type*); int structcount(Type*);
void addmethod(Node*, Type*, int); void addmethod(Node*, Type*, int);
Node* methodname(Node*, Type*); Node* methodname(Node*, Type*);
...@@ -860,6 +864,7 @@ void addtyp(Type*, int); ...@@ -860,6 +864,7 @@ void addtyp(Type*, int);
void addconst(Node*, Node*, int); void addconst(Node*, Node*, int);
Node* fakethis(void); Node* fakethis(void);
int isifacemethod(Type*); int isifacemethod(Type*);
Node* dclname(Sym*);
Node* newname(Sym*); Node* newname(Sym*);
Node* oldname(Sym*); Node* oldname(Sym*);
Type* newtype(Sym*); Type* newtype(Sym*);
...@@ -873,10 +878,10 @@ void defercheckwidth(void); ...@@ -873,10 +878,10 @@ void defercheckwidth(void);
void resumecheckwidth(void); void resumecheckwidth(void);
Node* embedded(Sym*); Node* embedded(Sym*);
NodeList* variter(NodeList*, Type*, NodeList*); NodeList* variter(NodeList*, Type*, NodeList*);
void constiter(NodeList*, Type*, NodeList*); NodeList* constiter(NodeList*, Node*, NodeList*);
void funclit0(Type*); Node* funclit0(Node*);
Node* funclit1(Type*, NodeList*); Node* funclit1(Node*, NodeList*);
Node* unsafenmagic(Node*, NodeList*); Node* unsafenmagic(Node*, NodeList*);
/* /*
...@@ -929,7 +934,7 @@ void walkexprlist(NodeList*, int, NodeList**); ...@@ -929,7 +934,7 @@ void walkexprlist(NodeList*, int, NodeList**);
void walkconv(Node*, NodeList**); void walkconv(Node*, NodeList**);
void walkdottype(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*, NodeList**); void walkdot(Node*, NodeList**);
...@@ -968,12 +973,14 @@ Node* selectas(Node*, Node*, NodeList**); ...@@ -968,12 +973,14 @@ Node* selectas(Node*, Node*, NodeList**);
Node* old2new(Node*, Type*, NodeList**); Node* old2new(Node*, Type*, NodeList**);
void addrescapes(Node*); void addrescapes(Node*);
void heapmoves(void); void heapmoves(void);
void walkdeflist(NodeList*);
void walkdef(Node*);
/* /*
* const.c * const.c
*/ */
void convlit1(Node*, Type*, int); void convlit1(Node**, Type*, int);
void convlit(Node*, Type*); void convlit(Node**, Type*);
void evconst(Node*); void evconst(Node*);
int cmpslit(Node *l, Node *r); int cmpslit(Node *l, Node *r);
int smallintconst(Node*); int smallintconst(Node*);
......
...@@ -64,24 +64,25 @@ ...@@ -64,24 +64,25 @@
%type <node> for_body for_header for_stmt if_header if_stmt %type <node> for_body for_header for_stmt if_header if_stmt
%type <node> keyval labelname name %type <node> keyval labelname name
%type <node> name_or_type %type <node> name_or_type
%type <node> new_name oexpr %type <node> new_name dcl_name oexpr
%type <node> onew_name %type <node> onew_name
%type <node> osimple_stmt pexpr %type <node> osimple_stmt pexpr
%type <node> pseudocall range_stmt select_stmt %type <node> pseudocall range_stmt select_stmt
%type <node> simple_stmt %type <node> simple_stmt
%type <node> switch_stmt uexpr %type <node> switch_stmt uexpr
%type <node> xfndcl %type <node> xfndcl typedcl
%type <list> xdcl fnbody common_dcl fnres switch_body loop_body %type <list> xdcl fnbody fnres switch_body loop_body dcl_name_list
%type <list> name_list expr_list keyval_list braced_keyval_list expr_or_type_list xdcl_list %type <list> new_name_list expr_list keyval_list braced_keyval_list expr_or_type_list xdcl_list
%type <list> oexpr_list oexpr_or_type_list caseblock_list stmt_list oarg_type_list arg_type_list %type <list> oexpr_list oexpr_or_type_list caseblock_list stmt_list oarg_type_list arg_type_list
%type <list> interfacedcl_list interfacedcl vardcl vardcl_list structdcl structdcl_list %type <list> interfacedcl_list interfacedcl vardcl vardcl_list structdcl structdcl_list
%type <list> common_dcl constdcl constdcl1 constdcl_list typedcl_list
%type <type> type %type <type> type
%type <node> convtype dotdotdot %type <node> convtype dotdotdot
%type <node> indcl interfacetype structtype %type <node> indcl interfacetype structtype
%type <type> new_type typedclname fnlitdcl fntype %type <type> new_type typedclname
%type <node> chantype non_chan_type othertype non_fn_type %type <node> chantype non_chan_type othertype non_fn_type fntype fnlitdcl
%type <sym> hidden_importsym hidden_pkg_importsym %type <sym> hidden_importsym hidden_pkg_importsym
...@@ -266,6 +267,7 @@ import_done: ...@@ -266,6 +267,7 @@ import_done:
} }
my->def = nod(OPACK, N, N); my->def = nod(OPACK, N, N);
my->def->sym = import; my->def->sym = import;
import->block = -1; // above top level
} }
/* /*
...@@ -298,11 +300,13 @@ common_dcl: ...@@ -298,11 +300,13 @@ common_dcl:
$$ = $2; $$ = $2;
if(yylast == LSEMIBRACE) if(yylast == LSEMIBRACE)
yyoptsemi(0); yyoptsemi(0);
// walkdeflist($2);
} }
| LVAR '(' vardcl_list osemi ')' | LVAR '(' vardcl_list osemi ')'
{ {
$$ = $3; $$ = $3;
yyoptsemi(0); yyoptsemi(0);
// walkdeflist($3);
} }
| LVAR '(' ')' | LVAR '(' ')'
{ {
...@@ -314,6 +318,7 @@ common_dcl: ...@@ -314,6 +318,7 @@ common_dcl:
$$ = nil; $$ = nil;
iota = 0; iota = 0;
lastconst = nil; lastconst = nil;
walkdeflist($2);
} }
| LCONST '(' constdcl osemi ')' | LCONST '(' constdcl osemi ')'
{ {
...@@ -321,6 +326,7 @@ common_dcl: ...@@ -321,6 +326,7 @@ common_dcl:
iota = 0; iota = 0;
lastconst = nil; lastconst = nil;
yyoptsemi(0); yyoptsemi(0);
walkdeflist($3);
} }
| LCONST '(' constdcl ';' constdcl_list osemi ')' | LCONST '(' constdcl ';' constdcl_list osemi ')'
{ {
...@@ -328,6 +334,7 @@ common_dcl: ...@@ -328,6 +334,7 @@ common_dcl:
iota = 0; iota = 0;
lastconst = nil; lastconst = nil;
yyoptsemi(0); yyoptsemi(0);
walkdeflist(concat($3, $5));
} }
| LCONST '(' ')' | LCONST '(' ')'
{ {
...@@ -337,12 +344,14 @@ common_dcl: ...@@ -337,12 +344,14 @@ common_dcl:
| LTYPE typedcl | LTYPE typedcl
{ {
$$ = nil; $$ = nil;
// $$ = list1($2);
if(yylast == LSEMIBRACE) if(yylast == LSEMIBRACE)
yyoptsemi(0); yyoptsemi(0);
} }
| LTYPE '(' typedcl_list osemi ')' | LTYPE '(' typedcl_list osemi ')'
{ {
$$ = nil; $$ = nil;
// $$ = $3;
yyoptsemi(0); yyoptsemi(0);
} }
| LTYPE '(' ')' | LTYPE '(' ')'
...@@ -358,38 +367,38 @@ varoptsemi: ...@@ -358,38 +367,38 @@ varoptsemi:
} }
vardcl: vardcl:
name_list type varoptsemi dcl_name_list type varoptsemi
{ {
$$ = variter($1, $2, nil); $$ = variter($1, $2, nil);
} }
| name_list type varoptsemi '=' expr_list | dcl_name_list type varoptsemi '=' expr_list
{ {
$$ = variter($1, $2, $5); $$ = variter($1, $2, $5);
} }
| name_list '=' expr_list | dcl_name_list '=' expr_list
{ {
$$ = variter($1, T, $3); $$ = variter($1, T, $3);
} }
constdcl: constdcl:
name_list type '=' expr_list dcl_name_list ntype '=' expr_list
{ {
constiter($1, $2, $4); $$ = constiter($1, $2, $4);
} }
| name_list '=' expr_list | dcl_name_list '=' expr_list
{ {
constiter($1, T, $3); $$ = constiter($1, N, $3);
} }
constdcl1: constdcl1:
constdcl constdcl
| name_list type | dcl_name_list ntype
{ {
constiter($1, $2, nil); $$ = constiter($1, $2, nil);
} }
| name_list | dcl_name_list
{ {
constiter($1, T, nil); $$ = constiter($1, N, nil);
} }
typedclname: typedclname:
...@@ -944,6 +953,12 @@ new_name: ...@@ -944,6 +953,12 @@ new_name:
$$ = newname($1); $$ = newname($1);
} }
dcl_name:
sym
{
$$ = dclname($1);
}
new_type: new_type:
sym sym
{ {
...@@ -1015,7 +1030,7 @@ type: ...@@ -1015,7 +1030,7 @@ type:
ntype: ntype:
chantype chantype
| fntype { $$ = typenod($1); } | fntype
| othertype | othertype
| '(' ntype ')' | '(' ntype ')'
{ {
...@@ -1023,7 +1038,7 @@ ntype: ...@@ -1023,7 +1038,7 @@ ntype:
} }
non_chan_type: non_chan_type:
fntype { $$ = typenod($1); } fntype
| othertype | othertype
| '(' ntype ')' | '(' ntype ')'
{ {
...@@ -1135,7 +1150,7 @@ xfndcl: ...@@ -1135,7 +1150,7 @@ xfndcl:
} }
fndcl: fndcl:
new_name '(' oarg_type_list ')' fnres dcl_name '(' oarg_type_list ')' fnres
{ {
b0stack = dclstack; // mark base for fn literals b0stack = dclstack; // mark base for fn literals
$$ = nod(ODCLFUNC, N, N); $$ = nod(ODCLFUNC, N, N);
...@@ -1168,15 +1183,16 @@ fndcl: ...@@ -1168,15 +1183,16 @@ fndcl:
fntype: fntype:
LFUNC '(' oarg_type_list ')' fnres LFUNC '(' oarg_type_list ')' fnres
{ {
$$ = functype(N, $3, $5); $$ = nod(OTFUNC, N, N);
$$->list = $3;
$$->rlist = $5;
} }
fnlitdcl: fnlitdcl:
fntype fntype
{ {
markdcl(); markdcl();
$$ = $1; $$ = funclit0($$);
funclit0($$);
} }
fnliteral: fnliteral:
...@@ -1236,10 +1252,19 @@ vardcl_list: ...@@ -1236,10 +1252,19 @@ vardcl_list:
constdcl_list: constdcl_list:
constdcl1 constdcl1
| constdcl_list ';' constdcl1 | constdcl_list ';' constdcl1
{
$$ = concat($1, $3);
}
typedcl_list: typedcl_list:
typedcl typedcl
{
$$ = list1($1);
}
| typedcl_list ';' typedcl | typedcl_list ';' typedcl
{
$$ = list($1, $3);
}
structdcl_list: structdcl_list:
structdcl structdcl
...@@ -1256,7 +1281,7 @@ interfacedcl_list: ...@@ -1256,7 +1281,7 @@ interfacedcl_list:
} }
structdcl: structdcl:
name_list ntype oliteral new_name_list ntype oliteral
{ {
NodeList *l; NodeList *l;
...@@ -1298,7 +1323,7 @@ embed: ...@@ -1298,7 +1323,7 @@ embed:
} }
interfacedcl: interfacedcl:
name_list indcl new_name_list indcl
{ {
NodeList *l; NodeList *l;
...@@ -1447,14 +1472,24 @@ stmt_list: ...@@ -1447,14 +1472,24 @@ stmt_list:
$$ = list($$, $3); $$ = list($$, $3);
} }
name_list: new_name_list:
name new_name
{ {
$$ = list1(newname($1->sym)); $$ = list1($1);
} }
| name_list ',' name | new_name_list ',' new_name
{ {
$$ = list($1, newname($3->sym)); $$ = list($1, $3);
}
dcl_name_list:
dcl_name
{
$$ = list1($1);
}
| dcl_name_list ',' dcl_name
{
$$ = list($1, $3);
} }
expr_list: expr_list:
......
...@@ -1345,18 +1345,22 @@ lexinit(void) ...@@ -1345,18 +1345,22 @@ lexinit(void)
v.ctype = CTNIL; v.ctype = CTNIL;
s->def = nodlit(v); s->def = nodlit(v);
s->def->sym = s; s->def->sym = s;
s->block = -1; // above top level
s = lookup("true"); s = lookup("true");
s->def = nodbool(1); s->def = nodbool(1);
s->def->sym = s; s->def->sym = s;
s->block = -1; // above top level
s = lookup("false"); s = lookup("false");
s->def = nodbool(0); s->def = nodbool(0);
s->def->sym = s; s->def->sym = s;
s->block = -1; // above top level
s = lookup("iota"); s = lookup("iota");
s->def = nodintconst(iota); s->def = nodintconst(iota);
s->def->iota = 1; // flag to reevaluate on copy s->def->iota = 1; // flag to reevaluate on copy
s->block = -1; // above top level
// logically, the type of a string literal. // logically, the type of a string literal.
// types[TSTRING] is the named type string // types[TSTRING] is the named type string
...@@ -1450,6 +1454,7 @@ mkpackage(char* pkg) ...@@ -1450,6 +1454,7 @@ mkpackage(char* pkg)
s = lookup(package); s = lookup(package);
s->def = nod(OPACK, N, N); s->def = nod(OPACK, N, N);
s->def->sym = s; s->def->sym = s;
s->block = -1; // above top level
if(outfile == nil) { if(outfile == nil) {
p = strrchr(infile, '/'); p = strrchr(infile, '/');
......
...@@ -575,6 +575,16 @@ dodump(Node *n, int dep) ...@@ -575,6 +575,16 @@ dodump(Node *n, int dep)
break; break;
} }
if(n->ntype != nil) {
indent(dep);
print("%O-ntype\n", n->op);
dodump(n->ntype, dep+1);
}
if(n->defn != nil) {
indent(dep);
print("%O-defn\n", n->op);
dodump(n->defn, dep+1);
}
if(n->list != nil) { if(n->list != nil) {
indent(dep); indent(dep);
print("%O-list\n", n->op); print("%O-list\n", n->op);
...@@ -597,7 +607,7 @@ dumplist(char *s, NodeList *l) ...@@ -597,7 +607,7 @@ dumplist(char *s, NodeList *l)
void void
dump(char *s, Node *n) dump(char *s, Node *n)
{ {
print("%s\n", s); print("%s [%p]\n", s, n);
dodump(n, 1); dodump(n, 1);
} }
...@@ -1360,6 +1370,8 @@ treecopy(Node *n) ...@@ -1360,6 +1370,8 @@ treecopy(Node *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); m->list = listtreecopy(n->list);
if(m->defn)
abort();
break; break;
case OLITERAL: case OLITERAL:
...@@ -1367,13 +1379,11 @@ treecopy(Node *n) ...@@ -1367,13 +1379,11 @@ treecopy(Node *n)
m = nodintconst(iota); m = nodintconst(iota);
break; break;
} }
m = nod(OXXX, N, N); // fall through
*m = *n; case ONONAME:
break;
case ONAME: case ONAME:
m = nod(OXXX, N, N); case OTYPE:
*m = *n; m = n;
break; break;
} }
return m; return m;
......
...@@ -237,8 +237,11 @@ csort(Case *l, int(*f)(Case*, Case*)) ...@@ -237,8 +237,11 @@ csort(Case *l, int(*f)(Case*, Case*))
* walktype * walktype
*/ */
Type* Type*
sw0(Node *c, Type *place, int arg) sw0(Node **cp, Type *place, int arg)
{ {
Node *c;
c = *cp;
if(c == N) if(c == N)
return T; return T;
switch(c->op) { switch(c->op) {
...@@ -264,8 +267,11 @@ sw0(Node *c, Type *place, int arg) ...@@ -264,8 +267,11 @@ sw0(Node *c, Type *place, int arg)
* return the first type * return the first type
*/ */
Type* Type*
sw1(Node *c, Type *place, int arg) sw1(Node **cp, Type *place, int arg)
{ {
Node *c;
c = *cp;
if(place != T) if(place != T)
return notideal(c->type); return notideal(c->type);
return place; return place;
...@@ -275,7 +281,7 @@ sw1(Node *c, Type *place, int arg) ...@@ -275,7 +281,7 @@ sw1(Node *c, Type *place, int arg)
* return a suitable type * return a suitable type
*/ */
Type* Type*
sw2(Node *c, Type *place, int arg) sw2(Node **cp, Type *place, int arg)
{ {
return types[TINT]; // botch return types[TINT]; // botch
} }
...@@ -285,13 +291,17 @@ sw2(Node *c, Type *place, int arg) ...@@ -285,13 +291,17 @@ sw2(Node *c, Type *place, int arg)
* is compat with all the cases * is compat with all the cases
*/ */
Type* Type*
sw3(Node *c, Type *place, int arg) sw3(Node **cp, Type *place, int arg)
{ {
Node *c;
c = *cp;
if(place == T) if(place == T)
return c->type; return c->type;
if(c->type == T) if(c->type == T)
c->type = place; c->type = place;
convlit(c, place); convlit(cp, place);
c = *cp;
if(!ascompat(place, c->type)) if(!ascompat(place, c->type))
badtype(OSWITCH, place, c->type); badtype(OSWITCH, place, c->type);
return place; return place;
...@@ -303,7 +313,7 @@ sw3(Node *c, Type *place, int arg) ...@@ -303,7 +313,7 @@ sw3(Node *c, Type *place, int arg)
* types to cases and switch * types to cases and switch
*/ */
Type* Type*
walkcases(Node *sw, Type*(*call)(Node*, Type*, int arg), int arg) walkcases(Node *sw, Type*(*call)(Node**, Type*, int arg), int arg)
{ {
Node *n; Node *n;
NodeList *l; NodeList *l;
...@@ -311,7 +321,7 @@ walkcases(Node *sw, Type*(*call)(Node*, Type*, int arg), int arg) ...@@ -311,7 +321,7 @@ walkcases(Node *sw, Type*(*call)(Node*, Type*, int arg), int arg)
int32 lno; int32 lno;
lno = setlineno(sw); lno = setlineno(sw);
place = call(sw->ntest, T, arg); place = call(&sw->ntest, T, arg);
for(l=sw->list; l; l=l->next) { for(l=sw->list; l; l=l->next) {
n = l->n; n = l->n;
...@@ -321,7 +331,7 @@ walkcases(Node *sw, Type*(*call)(Node*, Type*, int arg), int arg) ...@@ -321,7 +331,7 @@ walkcases(Node *sw, Type*(*call)(Node*, Type*, int arg), int arg)
if(n->left != N && !n->diag) { if(n->left != N && !n->diag) {
setlineno(n); setlineno(n);
place = call(n->left, place, arg); place = call(&n->left, place, arg);
} }
} }
lineno = lno; lineno = lno;
...@@ -597,7 +607,7 @@ exprswitch(Node *sw) ...@@ -597,7 +607,7 @@ exprswitch(Node *sw)
if(t == T) if(t == T)
return; return;
walkcases(sw, sw3, arg); walkcases(sw, sw3, arg);
convlit(sw->ntest, t); convlit(&sw->ntest, t);
/* /*
......
...@@ -103,6 +103,75 @@ gettype(Node *n, NodeList **init) ...@@ -103,6 +103,75 @@ gettype(Node *n, NodeList **init)
dump("after gettype", n); dump("after gettype", n);
} }
void
walkdeflist(NodeList *l)
{
for(; l; l=l->next)
walkdef(l->n);
}
void
walkdef(Node *n)
{
int lno;
NodeList *init;
Node *e;
Type *t;
lno = lineno;
setlineno(n);
if(n->op == ONONAME) {
if(!n->diag) {
n->diag = 1;
yyerror("undefined: %S", n->sym);
}
return;
}
if(n->type != T || n->diag)
return;
if(n->trecur) {
// TODO(rsc): better loop message
fatal("loop");
}
n->trecur = 1;
init = nil;
switch(n->op) {
case OLITERAL:
if(n->ntype != N) {
walkexpr(n->ntype, Etype, &init);
n->type = n->ntype->type;
n->ntype = N;
if(n->type == T) {
n->diag = 1;
goto ret;
}
}
e = n->defn;
if(e == N) {
dump("walkdef", n);
}
walkexpr(e, Erv, &init);
if(e->op != OLITERAL) {
yyerror("const initializer must be constant");
goto ret;
}
t = n->type;
if(t != T)
convlit(&e, t);
n->val = e->val;
n->type = e->type;
break;
}
ret:
lineno = lno;
n->trecur = 0;
}
void void
walkstmtlist(NodeList *l) walkstmtlist(NodeList *l)
{ {
...@@ -129,6 +198,7 @@ walkstmt(Node *n) ...@@ -129,6 +198,7 @@ walkstmt(Node *n)
yyerror("%S is not a top level statement", n->sym); yyerror("%S is not a top level statement", n->sym);
else else
yyerror("%O is not a top level statement", n->op); yyerror("%O is not a top level statement", n->op);
dump("nottop", n);
break; break;
case OASOP: case OASOP:
...@@ -177,14 +247,14 @@ walkstmt(Node *n) ...@@ -177,14 +247,14 @@ walkstmt(Node *n)
case OFOR: case OFOR:
walkstmtlist(n->ninit); walkstmtlist(n->ninit);
walkbool(n->ntest); walkbool(&n->ntest);
walkstmt(n->nincr); walkstmt(n->nincr);
walkstmtlist(n->nbody); walkstmtlist(n->nbody);
break; break;
case OIF: case OIF:
walkstmtlist(n->ninit); walkstmtlist(n->ninit);
walkbool(n->ntest); walkbool(&n->ntest);
walkstmtlist(n->nbody); walkstmtlist(n->nbody);
walkstmtlist(n->nelse); walkstmtlist(n->nelse);
break; break;
...@@ -290,6 +360,16 @@ reswitch: ...@@ -290,6 +360,16 @@ reswitch:
t = T; t = T;
et = Txxx; et = Txxx;
switch(n->op) {
case ONAME:
case OTYPE:
case OLITERAL:
case ONONAME:
if(n->sym != S && n->type == T)
walkdef(n);
break;
}
switch(n->op) { switch(n->op) {
default: default:
dump("walk", n); dump("walk", n);
...@@ -367,6 +447,11 @@ reswitch: ...@@ -367,6 +447,11 @@ reswitch:
n->type = sortinter(n->type); n->type = sortinter(n->type);
goto ret; goto ret;
case OTFUNC:
n->op = OTYPE;
n->type = functype(n->left, n->list, n->rlist);
goto ret;
case OKEY: case OKEY:
walkexpr(n->left, top | typeok, init); walkexpr(n->left, top | typeok, init);
n = n->right; n = n->right;
...@@ -408,7 +493,7 @@ reswitch: ...@@ -408,7 +493,7 @@ reswitch:
case ONONAME: case ONONAME:
s = n->sym; s = n->sym;
if(s->undef == 0) { if(n->diag == 0) {
s->undef = 1; s->undef = 1;
n->diag = 1; n->diag = 1;
yyerror("undefined: %S", s); yyerror("undefined: %S", s);
...@@ -455,7 +540,7 @@ reswitch: ...@@ -455,7 +540,7 @@ reswitch:
} }
walkexpr(n->left, Erv | Etype, init); walkexpr(n->left, Erv | Etype, init);
defaultlit(n->left, T); defaultlit(&n->left, T);
t = n->left->type; t = n->left->type;
if(t == T) if(t == T)
...@@ -766,7 +851,7 @@ reswitch: ...@@ -766,7 +851,7 @@ reswitch:
goto ret; goto ret;
// do NOT defaultlit n->left. // do NOT defaultlit n->left.
// let parent defaultlit or convlit instead. // let parent defaultlit or convlit instead.
defaultlit(n->right, types[TUINT]); defaultlit(&n->right, types[TUINT]);
if(n->left->type == T || n->right->type == T) if(n->left->type == T || n->right->type == T)
goto ret; goto ret;
if(issigned[n->right->type->etype] || !isint[n->right->type->etype]) if(issigned[n->right->type->etype] || !isint[n->right->type->etype])
...@@ -802,7 +887,7 @@ reswitch: ...@@ -802,7 +887,7 @@ reswitch:
evconst(n); evconst(n);
if(n->op == OLITERAL) if(n->op == OLITERAL)
goto ret; goto ret;
defaultlit2(n->left, n->right); defaultlit2(&n->left, &n->right);
if(n->left->type == T || n->right->type == T) if(n->left->type == T || n->right->type == T)
goto ret; goto ret;
if(!eqtype(n->left->type, n->right->type)) if(!eqtype(n->left->type, n->right->type))
...@@ -869,7 +954,7 @@ reswitch: ...@@ -869,7 +954,7 @@ reswitch:
n->left = n->list->n; n->left = n->list->n;
} }
walkexpr(n->left, Erv, init); walkexpr(n->left, Erv, init);
defaultlit(n->left, T); defaultlit(&n->left, T);
implicitstar(&n->left); implicitstar(&n->left);
t = n->left->type; t = n->left->type;
if(t == T) if(t == T)
...@@ -904,7 +989,7 @@ reswitch: ...@@ -904,7 +989,7 @@ reswitch:
n->left = n->list->n; n->left = n->list->n;
} }
walkexpr(n->left, Erv, init); walkexpr(n->left, Erv, init);
defaultlit(n->left, T); defaultlit(&n->left, T);
implicitstar(&n->left); implicitstar(&n->left);
t = n->left->type; t = n->left->type;
if(t == T) if(t == T)
...@@ -930,7 +1015,7 @@ reswitch: ...@@ -930,7 +1015,7 @@ reswitch:
if(n->left == N || n->right == N) if(n->left == N || n->right == N)
goto ret; goto ret;
defaultlit(n->left, T); defaultlit(&n->left, T);
implicitstar(&n->left); implicitstar(&n->left);
t = n->left->type; t = n->left->type;
...@@ -939,14 +1024,14 @@ reswitch: ...@@ -939,14 +1024,14 @@ reswitch:
switch(t->etype) { switch(t->etype) {
default: default:
defaultlit(n->right, T); defaultlit(&n->right, T);
goto badt; goto badt;
case TSTRING: case TSTRING:
// right side must be an int // right side must be an int
if(top != Erv) if(top != Erv)
goto nottop; goto nottop;
defaultlit(n->right, types[TINT]); defaultlit(&n->right, types[TINT]);
if(n->right->type == T) if(n->right->type == T)
break; break;
if(!isint[n->right->type->etype]) if(!isint[n->right->type->etype])
...@@ -956,7 +1041,7 @@ reswitch: ...@@ -956,7 +1041,7 @@ reswitch:
case TMAP: case TMAP:
// right side must be map type // right side must be map type
defaultlit(n->right, t->down); defaultlit(&n->right, t->down);
if(n->right->type == T) if(n->right->type == T)
break; break;
if(!eqtype(n->right->type, t->down)) if(!eqtype(n->right->type, t->down))
...@@ -968,7 +1053,7 @@ reswitch: ...@@ -968,7 +1053,7 @@ reswitch:
case TARRAY: case TARRAY:
// right side must be an int // right side must be an int
defaultlit(n->right, types[TINT]); defaultlit(&n->right, types[TINT]);
if(n->right->type == T) if(n->right->type == T)
break; break;
if(!isint[n->right->type->etype]) if(!isint[n->right->type->etype])
...@@ -1021,9 +1106,9 @@ reswitch: ...@@ -1021,9 +1106,9 @@ reswitch:
walkexpr(n->right, Erv, init); walkexpr(n->right, Erv, init);
if(n->left == N || n->right == N) if(n->left == N || n->right == N)
goto ret; goto ret;
defaultlit(n->left, T); defaultlit(&n->left, T);
defaultlit(n->right->left, types[TUINT]); defaultlit(&n->right->left, types[TUINT]);
defaultlit(n->right->right, types[TUINT]); defaultlit(&n->right->right, types[TUINT]);
implicitstar(&n->left); implicitstar(&n->left);
t = n->left->type; t = n->left->type;
if(t == T) if(t == T)
...@@ -1045,14 +1130,14 @@ reswitch: ...@@ -1045,14 +1130,14 @@ reswitch:
case ODOTINTER: case ODOTINTER:
if(top == Etop) if(top == Etop)
goto nottop; goto nottop;
defaultlit(n->left, T); defaultlit(&n->left, T);
walkdot(n, init); walkdot(n, init);
goto ret; goto ret;
case OADDR: case OADDR:
if(top != Erv) if(top != Erv)
goto nottop; goto nottop;
defaultlit(n->left, T); defaultlit(&n->left, T);
if(n->left->op == OCOMPOS) { if(n->left->op == OCOMPOS) {
walkexpr(n->left->right, Etype, init); walkexpr(n->left->right, Etype, init);
n->left->type = n->left->right->type; n->left->type = n->left->right->type;
...@@ -1121,7 +1206,7 @@ reswitch: ...@@ -1121,7 +1206,7 @@ reswitch:
if(n->left == N) if(n->left == N)
goto ret; goto ret;
walkexpr(n->left, top | Etype, init); walkexpr(n->left, top | Etype, init);
defaultlit(n->left, T); defaultlit(&n->left, T);
if(n->left->op == OTYPE) { if(n->left->op == OTYPE) {
n->op = OTYPE; n->op = OTYPE;
n->type = ptrto(n->left->type); n->type = ptrto(n->left->type);
...@@ -1361,12 +1446,16 @@ ret: ...@@ -1361,12 +1446,16 @@ ret:
} }
void void
walkbool(Node *n) walkbool(Node **np)
{ {
Node *n;
n = *np;
if(n == N) if(n == N)
return; return;
walkexpr(n, Erv, &n->ninit); walkexpr(n, Erv, &n->ninit);
defaultlit(n, T); defaultlit(np, T);
n = *np;
if(n->type != T && !eqtype(n->type, types[TBOOL])) if(n->type != T && !eqtype(n->type, types[TBOOL]))
yyerror("IF and FOR require a boolean type"); yyerror("IF and FOR require a boolean type");
} }
...@@ -1377,7 +1466,7 @@ walkdottype(Node *n, NodeList **init) ...@@ -1377,7 +1466,7 @@ walkdottype(Node *n, NodeList **init)
walkexpr(n->left, Erv, init); walkexpr(n->left, Erv, init);
if(n->left == N) if(n->left == N)
return; return;
defaultlit(n->left, T); defaultlit(&n->left, T);
if(!isinter(n->left->type)) if(!isinter(n->left->type))
yyerror("type assertion requires interface on left, have %T", n->left->type); yyerror("type assertion requires interface on left, have %T", n->left->type);
if(n->right != N) { if(n->right != N) {
...@@ -1418,7 +1507,8 @@ walkconv(Node *n, NodeList **init) ...@@ -1418,7 +1507,8 @@ walkconv(Node *n, NodeList **init)
} }
// otherwise, conversion. // otherwise, conversion.
convlit1(l, t, 1); convlit1(&n->left, t, 1);
l = n->left;
if(l->type == T) if(l->type == T)
return; return;
...@@ -1543,7 +1633,7 @@ selcase(Node *n, Node *var, NodeList **init) ...@@ -1543,7 +1633,7 @@ selcase(Node *n, Node *var, NodeList **init)
return N; return N;
} }
convlit(c->right, t->type); convlit(&c->right, t->type);
if(!ascompat(t->type, c->right->type)) { if(!ascompat(t->type, c->right->type)) {
badtype(c->op, t->type, c->right->type); badtype(c->op, t->type, c->right->type);
return N; return N;
...@@ -1608,7 +1698,7 @@ recv2: ...@@ -1608,7 +1698,7 @@ recv2:
} }
walkexpr(c->left, Elv, init); // check elem walkexpr(c->left, Elv, init); // check elem
convlit(c->left, t->type); convlit(&c->left, t->type);
if(!ascompat(t->type, c->left->type)) { if(!ascompat(t->type, c->left->type)) {
badtype(c->op, t->type, c->left->type); badtype(c->op, t->type, c->left->type);
return N; return N;
...@@ -1931,7 +2021,7 @@ ascompatee1(int op, Node *l, Node *r, NodeList **init) ...@@ -1931,7 +2021,7 @@ ascompatee1(int op, Node *l, Node *r, NodeList **init)
* a expression. called in * a expression. called in
* expr = expr * expr = expr
*/ */
convlit(r, l->type); convlit(&r, l->type);
if(!ascompat(l->type, r->type)) { if(!ascompat(l->type, r->type)) {
badtype(op, l->type, r->type); badtype(op, l->type, r->type);
return nil; return nil;
...@@ -2087,7 +2177,8 @@ mkdotargs(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init) ...@@ -2087,7 +2177,8 @@ mkdotargs(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init)
return nil; return nil;
} }
} }
defaultlit(r, T); defaultlit(&r, T);
lr->n = r;
if(r->type == T) // type check failed if(r->type == T) // type check failed
return nil; return nil;
...@@ -2254,7 +2345,7 @@ loop: ...@@ -2254,7 +2345,7 @@ loop:
} }
return nn; return nn;
} }
convlit(r, l->type); convlit(&r, l->type);
if(!ascompat(l->type, r->type)) { if(!ascompat(l->type, r->type)) {
badtype(op, l->type, r->type); badtype(op, l->type, r->type);
return nil; return nil;
...@@ -2398,10 +2489,12 @@ prcompat(NodeList *all, int fmt, int dopanic) ...@@ -2398,10 +2489,12 @@ prcompat(NodeList *all, int fmt, int dopanic)
if(n->op == OLITERAL) { if(n->op == OLITERAL) {
switch(n->val.ctype) { switch(n->val.ctype) {
case CTINT: case CTINT:
defaultlit(n, types[TINT64]); defaultlit(&n, types[TINT64]);
l->n = n;
break; break;
case CTFLT: case CTFLT:
defaultlit(n, types[TFLOAT64]); defaultlit(&n, types[TFLOAT64]);
l->n = n;
break; break;
} }
} }
...@@ -2773,7 +2866,7 @@ mapop(Node *n, int top, NodeList **init) ...@@ -2773,7 +2866,7 @@ mapop(Node *n, int top, NodeList **init)
if(t == T) if(t == T)
break; break;
convlit(n->right, t->down); convlit(&n->right, t->down);
if(!eqtype(n->right->type, t->down)) { if(!eqtype(n->right->type, t->down)) {
badtype(n->op, n->right->type, t->down); badtype(n->op, n->right->type, t->down);
...@@ -3029,7 +3122,7 @@ chanop(Node *n, int top, NodeList **init) ...@@ -3029,7 +3122,7 @@ chanop(Node *n, int top, NodeList **init)
// chanrecv2(hchan *chan any) (elem any, pres bool); // chanrecv2(hchan *chan any) (elem any, pres bool);
r = n->rlist->n; r = n->rlist->n;
defaultlit(r->left, T); defaultlit(&r->left, T);
t = fixchan(r->left->type); t = fixchan(r->left->type);
if(t == T) if(t == T)
break; break;
...@@ -3061,7 +3154,7 @@ chanop(Node *n, int top, NodeList **init) ...@@ -3061,7 +3154,7 @@ chanop(Node *n, int top, NodeList **init)
} }
// chanrecv1(hchan *chan any) (elem any); // chanrecv1(hchan *chan any) (elem any);
defaultlit(n->left, T); defaultlit(&n->left, T);
t = fixchan(n->left->type); t = fixchan(n->left->type);
if(t == T) if(t == T)
break; break;
...@@ -3673,7 +3766,7 @@ colas(NodeList *ll, NodeList *lr) ...@@ -3673,7 +3766,7 @@ colas(NodeList *ll, NodeList *lr)
case OCALLINTER: case OCALLINTER:
walkexpr(nr->left, Erv, &init); walkexpr(nr->left, Erv, &init);
call: call:
convlit(nr->left, types[TFUNC]); convlit(&nr->left, types[TFUNC]);
t = nr->left->type; t = nr->left->type;
if(t == T) if(t == T)
goto outl; // error already printed goto outl; // error already printed
...@@ -3714,7 +3807,8 @@ colas(NodeList *ll, NodeList *lr) ...@@ -3714,7 +3807,8 @@ colas(NodeList *ll, NodeList *lr)
r = saver->n; r = saver->n;
walkexpr(r, Erv, &init); walkexpr(r, Erv, &init);
defaultlit(r, T); defaultlit(&r, T);
saver->n = r;
a = mixedoldnew(l, r->type); a = mixedoldnew(l, r->type);
n = list(n, a); n = list(n, a);
} }
......
...@@ -145,7 +145,7 @@ fixedbugs/bug049.go:6: illegal types for operand: EQ ...@@ -145,7 +145,7 @@ fixedbugs/bug049.go:6: illegal types for operand: EQ
fixedbugs/bug050.go:3: package statement must be first fixedbugs/bug050.go:3: package statement must be first
=========== fixedbugs/bug051.go =========== fixedbugs/bug051.go
fixedbugs/bug051.go:10: expression must be a constant fixedbugs/bug051.go:10: const initializer must be constant
=========== fixedbugs/bug062.go =========== fixedbugs/bug062.go
fixedbugs/bug062.go:6: illegal types for operand: AS fixedbugs/bug062.go:6: illegal types for operand: AS
...@@ -184,7 +184,7 @@ fixedbugs/bug074.go:6: invalid type for composite literal: string ...@@ -184,7 +184,7 @@ fixedbugs/bug074.go:6: invalid type for composite literal: string
fixedbugs/bug074.go:6: invalid type for composite literal: string fixedbugs/bug074.go:6: invalid type for composite literal: string
=========== fixedbugs/bug081.go =========== fixedbugs/bug081.go
fixedbugs/bug081.go:5: undefined: x fixedbugs/bug081.go:5: fatal error: loop
=========== fixedbugs/bug083.go =========== fixedbugs/bug083.go
fixedbugs/bug083.dir/bug1.go:9: cannot refer to bug0.t0 fixedbugs/bug083.dir/bug1.go:9: cannot refer to bug0.t0
...@@ -202,7 +202,6 @@ M ...@@ -202,7 +202,6 @@ M
=========== fixedbugs/bug103.go =========== fixedbugs/bug103.go
fixedbugs/bug103.go:8: assignment count mismatch: 1 = 0 fixedbugs/bug103.go:8: assignment count mismatch: 1 = 0
fixedbugs/bug103.go:8: undefined: x
fixedbugs/bug103.go:8: function requires a return type fixedbugs/bug103.go:8: function requires a return type
fixedbugs/bug103.go:8: illegal types for operand: AS fixedbugs/bug103.go:8: illegal types for operand: AS
int int
......
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