n->type = n->left->type;
return;
}
+
et = t->etype;
+ switch(et) {
+ case TARRAY:
+ case TFUNC:
+ case TCHAN:
+ case TMAP:
+// case TPTR32:
+// case TPTR64:
+ return;
+ }
+
switch(whatis(n)) {
default:
goto bad1;
OLIST, OCMP,
OPTR, OARRAY,
ORETURN, OFOR, OIF, OSWITCH, OI2S, OS2I, OI2I,
- OAS, OASOP, OCASE, OXCASE, OSCASE, OFALL, OXFALL,
+ OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL,
OGOTO, OPROC, ONEW, OEMPTY, OSELECT,
OLEN, OCAP, OPANIC, OPRINT, OTYPEOF,
* walk.c
*/
void walk(Node*);
+void walkstate(Node*);
void walktype(Node*, int);
+void walkas(Node*);
void walkbool(Node*);
Type* walkswitch(Node*, Type*(*)(Node*, Type*));
int casebody(Node*);
%type <node> range_header range_body range_stmt select_stmt
%type <node> simple_stmt osimple_stmt semi_stmt
%type <node> expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r
-%type <node> name name_name onew_name new_name new_name_list_r conexpr
+%type <node> name name_name onew_name new_name new_name_list_r
%type <node> vardcl_list_r vardcl Avardcl Bvardcl
%type <node> interfacedcl_list_r interfacedcl
%type <node> structdcl_list_r structdcl
{
$$ = rev($3);
}
-| LCONST '(' constdcl_list_r osemi ')'
+| LCONST '(' constdcl osemi ')'
+ {
+ iota = 0;
+ lastconst = N;
+ $$ = N;
+ }
+| LCONST '(' constdcl ';' constdcl_list_r osemi ')'
{
iota = 0;
lastconst = N;
$$ = nod(OAS, $$, N);
}
-| new_name_list_r type '=' oexpr_list
+| new_name_list_r type '=' expr_list
{
$$ = rev($1);
dodclvar($$, $2);
}
constdcl:
- new_name conexpr
+ new_name type '=' expr
{
- walktype($2, Erv);
- dodclconst($1, $2);
+ Node *c = treecopy($4);
+ walktype(c, Erv);
+ convlit(c, $2);
+ dodclconst($1, c);
+
+ lastconst = $4;
+ iota += 1;
}
-| new_name type conexpr
+| new_name '=' expr
{
- walktype($3, Erv);
- convlit($3, $2);
- dodclconst($1, $3);
+ Node *c = treecopy($3);
+ walktype(c, Erv);
+ dodclconst($1, c);
+
+ lastconst = $3;
+ iota += 1;
}
-conexpr:
+constdcl1:
+ constdcl
+| new_name type
{
- if(lastconst == N)
- yyerror("first constant must evaluate an expression");
- $$ = treecopy(lastconst);
+ Node *c = treecopy(lastconst);
+ walktype(c, Erv);
+ convlit(c, $2);
+ dodclconst($1, c);
+
iota += 1;
}
-| '=' expr
+| new_name
{
- lastconst = $2;
- $$ = treecopy(lastconst);
+ Node *c = treecopy(lastconst);
+ walktype(c, Erv);
+ dodclconst($1, c);
+
iota += 1;
}
$$ = functype(N, $3, $5);
funcnam($$, nil);
}
-| LFUNC '(' oarg_type_list ')' '.' '(' oarg_type_list ')' Afnres
- /* i dont believe that this form is useful for anything */
- {
- if($3 == N || $3->op == OLIST)
- yyerror("syntax error in method receiver");
- $$ = functype($3, $7, $9);
- funcnam($$, nil);
- }
Bfntypeh:
LFUNC '(' oarg_type_list ')' Bfnres
$$ = functype(N, $3, $5);
funcnam($$, nil);
}
-| LFUNC '(' oarg_type_list ')' '.' '(' oarg_type_list ')' Bfnres
- /* i dont believe that this form is useful for anything */
- {
- if($3 == N || $3->op == OLIST)
- yyerror("syntax error in method receiver");
- $$ = functype($3, $7, $9);
- funcnam($$, nil);
- }
fntype:
fntypeh
}
constdcl_list_r:
- constdcl
-| constdcl_list_r ';' constdcl
+ constdcl1
+| constdcl_list_r ';' constdcl1
typedcl_list_r:
typedcl
{
$$ = rev($1);
}
-| expr_list
+| oexpr_list
/*
* the one compromise of a
[OCALLINTER] = "CALLINTER",
[OCASE] = "CASE",
[OXCASE] = "XCASE",
- [OSCASE] = "SCASE",
[OCMP] = "CMP",
[OFALL] = "FALL",
[OCONV] = "CONV",
if(debug['W'])
dump("fn-before", fn->nbody);
curfn = fn;
- walktype(fn->nbody, Etop);
+ walkstate(fn->nbody);
if(debug['W'])
dump("fn", fn->nbody);
}
void
-walktype1(Node *n, int top)
+walkstate(Node *n)
+{
+ Node *l, *more;
+
+loop:
+ if(n == N)
+ return;
+
+ more = N;
+ switch(n->op) {
+
+ case OLIST:
+ walkstate(n->left);
+ more = n->right;
+ break;
+
+ default:
+ yyerror("walkstate: %O not a top level statement", n->op);
+
+ case OASOP:
+ case OAS:
+ case OCALLMETH:
+ case OCALLINTER:
+ case OCALL:
+ case OSEND:
+ case ORECV:
+ case OPRINT:
+ case OPANIC:
+ case OFOR:
+ case OIF:
+ case OSWITCH:
+ case OSELECT:
+ case OEMPTY:
+ case OBREAK:
+ case OCONTINUE:
+ case OGOTO:
+ case OLABEL:
+ case OFALL:
+ case OXCASE:
+ case OCASE:
+ case OXFALL:
+ case ORETURN:
+ case OPROC:
+ walktype(n, Etop);
+ break;
+ }
+
+ while(addtop != N) {
+ l = addtop;
+ addtop = N;
+ walktype(l, Etop);
+ n->ninit = list(n->ninit, l);
+ }
+
+ if(more != N) {
+ n = more;
+ goto loop;
+ }
+}
+
+void
+walktype(Node *n, int top)
{
Node *r, *l;
Type *t;
case OFOR:
if(top != Etop)
goto nottop;
- walktype(n->ninit, Etop);
+ walkstate(n->ninit);
walkbool(n->ntest);
- walktype(n->nincr, Etop);
- n = n->nbody;
- goto loop;
+ walkstate(n->nincr);
+ walkstate(n->nbody);
+ goto ret;
case OSWITCH:
if(top != Etop)
if(n->ntest == N)
n->ntest = booltrue;
- walktype(n->ninit, Etop);
+ walkstate(n->ninit);
walktype(n->ntest, Erv);
- walktype(n->nbody, Etop);
+ walkstate(n->nbody);
// find common type
if(n->ntest->type == T)
walkselect(n);
goto ret;
- case OSCASE:
- if(top != Etop)
- goto nottop;
-// walktype(n->left, Erv); SPECIAL
- n = n->right;
- goto loop;
-
case OEMPTY:
if(top != Etop)
goto nottop;
case OIF:
if(top != Etop)
goto nottop;
- walktype(n->ninit, Etop);
+ walkstate(n->ninit);
walkbool(n->ntest);
- walktype(n->nelse, Etop);
- n = n->nbody;
- goto loop;
+ walkstate(n->nelse);
+ walkstate(n->nbody);
+ goto ret;
case OPROC:
if(top != Etop)
goto nottop;
- walktype(n->left, Etop);
+ walkstate(n->left);
goto ret;
case OCALLMETH:
if(top != Etop)
goto nottop;
walktype(n->left, Erv);
- n = n->right;
- goto loop;
+ walkstate(n->right);
+ goto ret;
case OXFALL:
if(top != Etop)
if(!isptrto(l->left->type, TMAP))
goto com;
*n = *mapop(n, top);
- goto loop;
+ goto ret;
case OLSH:
case ORSH:
sel->nbody = rev(res);
sel->left = N;
- walktype(sel->ninit, Etop);
- walktype(sel->nbody, Etop);
+ walkstate(sel->ninit);
+ walkstate(sel->nbody);
//dump("sel", sel);
loop:
if(l == N) {
- walktype(r, Etop);
+ walktype(r, Erv);
return r;
}
on = syslook("panicl", 0);
n = nodintconst(lineno);
n = nod(OCALL, on, n);
- walktype(n, Etop);
+ walktype(n, Erv);
return n;
}
argtype(on, t->type); // any-1
argtype(on, t->type); // any-2
r = nod(OCALL, on, r);
- walktype(r, top);
+ walktype(r, Etop);
break;
send2:
argtype(on, t->type); // any-1
argtype(on, t->type); // any-2
r = nod(OCALL, on, r);
- walktype(r, top);
+ walktype(r, Etop);
break;
}
return r;
return r;
}
-void
-walktype(Node *n, int top)
-{
- Node *r;
-
- walktype1(n, top);
- while(top == Etop && addtop != N) {
- r = addtop;
- addtop = N;
- walktype1(r, top);
- n->ninit = list(n->ninit, r);
- }
-}
-
void
diagnamed(Type *t)
{