]> Cypherpunks repositories - gostls13.git/commitdiff
assignment in select
authorKen Thompson <ken@golang.org>
Wed, 17 Sep 2008 03:51:50 +0000 (20:51 -0700)
committerKen Thompson <ken@golang.org>
Wed, 17 Sep 2008 03:51:50 +0000 (20:51 -0700)
with new select operator

R=r
OCL=15418
CL=15418

src/cmd/gc/go.h
src/cmd/gc/go.y
src/cmd/gc/walk.c

index 1d776d4813a9906c72cb3c3a94576857dccee2c5..639aa9236d14832ed6a3319655529b02a2829552 100644 (file)
@@ -702,6 +702,8 @@ Node*       reorder4(Node*);
 Node*  structlit(Node*);
 Node*  arraylit(Node*);
 Node*  maplit(Node*);
+Node*  selectas(Node*, Node*);
+Node*  old2new(Node*, Type*);
 
 /*
  *     const.c
index 8204b6d21d5d5fb45c6074cb752788747f138b2d..15b0b8bd54f17af727fda2167ac13007a2f6963b 100644 (file)
@@ -427,7 +427,7 @@ complex_stmt:
                // right will point to next case
                // done in casebody()
                poptodcl();
-               $$ = nod(OAS, colas($2, $4), $4);
+               $$ = nod(OAS, selectas($2,$4), $4);
                $$ = nod(OXCASE, $$, N);
        }
 |      LDEFAULT ':'
index 503f9260e55efba52f448520dcdb338fb6de1458..7349915b2f9e1154f2edd9f044a3ebb2ec2cbd3f 100644 (file)
@@ -1232,6 +1232,30 @@ out:
        return r;
 }
 
+Node*
+selectas(Node *name, Node *expr)
+{
+       Node *a;
+       Type *t;
+
+       if(expr == N || expr->op != ORECV)
+               goto bad;
+       t = expr->left->type;
+       if(t == T)
+               goto bad;
+       if(isptr[t->etype])
+               t = t->type;
+       if(t == T)
+               goto bad;
+       if(t->etype != TCHAN)
+               goto bad;
+       a = old2new(name, t->type);
+       return a;
+
+bad:
+       return name;
+}
+
 void
 walkselect(Node *sel)
 {
@@ -1270,6 +1294,16 @@ walkselect(Node *sel)
                                yyerror("select cases must be send or recv");
                                break;
 
+                       case OAS:
+                               // convert new syntax (a=recv(chan)) to (recv(a,chan))
+                               if(n->left->right == N || n->left->right->op != ORECV) {
+                                       yyerror("select cases must be send or recv");
+                                       break;
+                               }
+                               n->left->right->right = n->left->right->left;
+                               n->left->right->left = n->left->left;
+                               n->left = n->left->right;
+
                        case OSEND:
                        case ORECV:
                                if(oc != N) {