]> Cypherpunks repositories - gostls13.git/commitdiff
allowed syntax for range
authorKen Thompson <ken@golang.org>
Sat, 6 Dec 2008 21:40:30 +0000 (13:40 -0800)
committerKen Thompson <ken@golang.org>
Sat, 6 Dec 2008 21:40:30 +0000 (13:40 -0800)
a range m (implies :=)
a,b range m (implies :=)
a:b range m (implies :=)

a := range m
a,b := range m
a:b := range m

a = range m
a,b = range m
a:b = range m

R=r
OCL=20676
CL=20676

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

index b8429c3bd02ed574e7f54d3bbe4bd8130b8c6f4d..68898c998845cc2290737c1b4eaa600ca6bf8d8c 100644 (file)
@@ -300,7 +300,7 @@ enum
        ONAME, ONONAME,
        ODOT, ODOTPTR, ODOTMETH, ODOTINTER,
        ODCLFUNC, ODCLFIELD, ODCLARG,
-       OLIST, OCMP, OPTR, OARRAY,
+       OLIST, OCMP, OPTR, OARRAY, ORANGE,
        ORETURN, OFOR, OIF, OSWITCH,
        OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL,
        OGOTO, OPROC, ONEW, OEMPTY, OSELECT,
@@ -806,7 +806,7 @@ int isandss(Type*, Node*);
 Node*  convas(Node*);
 void   arrayconv(Type*, Node*);
 Node*  colas(Node*, Node*);
-Node*  dorange(Node*, Node*, Node*, int);
+Node*  dorange(Node*);
 Node*  reorder1(Node*);
 Node*  reorder2(Node*);
 Node*  reorder3(Node*);
index 2944d55101d973d57400cf321ffcb193db87564b..bcee5ec5b3859e4448a8eb545fce604127ff71a2 100644 (file)
@@ -52,7 +52,7 @@
 %type  <node>          Astmt Bstmt
 %type  <node>          for_stmt for_body for_header
 %type  <node>          if_stmt if_body if_header select_stmt
-%type  <node>          simple_stmt osimple_stmt semi_stmt
+%type  <node>          simple_stmt osimple_stmt orange_stmt semi_stmt
 %type  <node>          expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r
 %type  <node>          exprsym3_list_r exprsym3
 %type  <node>          name onew_name new_name new_name_list_r new_field
@@ -416,7 +416,6 @@ simple_stmt:
        {
                if(addtop != N)
                        fatal("exprsym3_list_r LCOLAS expr_list");
-
                $$ = rev($1);
                $$ = colas($$, $3);
                $$ = nod(OAS, $$, $3);
@@ -555,31 +554,62 @@ compound_stmt:
                popdcl();
        }
 
+ocolas:
+|      LCOLAS
+
+orange_stmt:
+       osimple_stmt
+|      exprsym3_list_r '=' LRANGE expr
+       {
+               $$ = nod(ORANGE, $1, $4);
+               $$->etype = 0;  // := flag
+       }
+|      exprsym3 ':' exprsym3 '=' LRANGE expr
+       {
+               $$ = nod(OLIST, $1, $3);
+               $$ = nod(ORANGE, $$, $6);
+               $$->etype = 0;
+       }
+|      exprsym3_list_r ocolas LRANGE expr
+       {
+               $$ = nod(ORANGE, $1, $4);
+               $$->etype = 1;
+       }
+|      exprsym3 ':' exprsym3 ocolas LRANGE expr
+       {
+               $$ = nod(OLIST, $1, $3);
+               $$ = nod(ORANGE, $$, $6);
+               $$->etype = 1;
+       }
+
 for_header:
-       osimple_stmt ';' osimple_stmt ';' osimple_stmt
+       osimple_stmt ';' orange_stmt ';' osimple_stmt
        {
+               if($3 != N && $3->op == ORANGE) {
+                       $$ = dorange($3);
+                       $$->ninit = list($$->ninit, $1);
+                       $$->nincr = list($$->nincr, $5);
+                       break;
+               }
                // init ; test ; incr
                $$ = nod(OFOR, N, N);
                $$->ninit = $1;
                $$->ntest = $3;
                $$->nincr = $5;
        }
-|      osimple_stmt
+|      orange_stmt
        {
-               // test
+               // range
+               if($1 != N && $1->op == ORANGE) {
+                       $$ = dorange($1);
+                       break;
+               }
+               // normal test
                $$ = nod(OFOR, N, N);
                $$->ninit = N;
                $$->ntest = $1;
                $$->nincr = N;
        }
-|      new_name ':' new_name LRANGE expr
-       {
-               $$ = dorange($1, $3, $5, 1);
-       }
-|      new_name LRANGE expr
-       {
-               $$ = dorange($1, N, $3, 1);
-       }
 
 for_body:
        for_header compound_stmt
index 851f17404f6128eb54c5ec9a35663e36dffe6f9d..cd2fc4d2d53440a78e0cafe804c08b872b633a60 100644 (file)
@@ -687,6 +687,7 @@ opnames[] =
        [OREGISTER]     = "REGISTER",
        [OINDREG]       = "INDREG",
        [OSEND]         = "SEND",
+       [ORANGE]        = "RANGE",
        [ORECV]         = "RECV",
        [OPTR]          = "PTR",
        [ORETURN]       = "RETURN",
index 68cf9123dec1a0aefeb2a8a157f4c14b1e79dcde..067aed49d4847654fbe2c35d3662dc73bcfd10ff 100644 (file)
@@ -3033,14 +3033,32 @@ badt:
        return nl;
 }
 
+/*
+ * rewrite a range statement
+ * k and v are names/new_names
+ * m is an array or map
+ * local is =/0 or :=/1
+ */
 Node*
-dorange(Node *k, Node *v, Node *m, int local)
+dorange(Node *nn)
 {
+       Node *k, *v, *m;
        Node *n, *hk, *on, *r, *a;
        Type *t, *th;
+       int local;
 
-       if(!local)
-               fatal("only local varables now");
+       if(nn->op != ORANGE)
+               fatal("dorange not ORANGE");
+
+       k = nn->left;
+       m = nn->right;
+       local = nn->etype;
+
+       v = N;
+       if(k->op == OLIST) {
+               v = k->right;
+               k = k->left;
+       }
 
        n = nod(OFOR, N, N);
 
@@ -3073,11 +3091,13 @@ ary:
        n->nincr = nod(OASOP, hk, literal(1));
        n->nincr->etype = OADD;
 
-       k = old2new(k, hk->type);
+       if(local)
+               k = old2new(k, hk->type);
        n->nbody = nod(OAS, k, hk);
 
        if(v != N) {
-               v = old2new(v, t->type);
+               if(local)
+                       v = old2new(v, t->type);
                n->nbody = list(n->nbody,
                        nod(OAS, v, nod(OINDEX, m, hk)) );
        }
@@ -3112,7 +3132,8 @@ map:
        r = nod(OCALL, on, r);
        n->nincr = r;
 
-       k = old2new(k, t->down);
+       if(local)
+               k = old2new(k, t->down);
        if(v == N) {
                on = syslook("mapiter1", 1);
                argtype(on, th);
@@ -3122,7 +3143,8 @@ map:
                n->nbody = nod(OAS, k, r);
                goto out;
        }
-       v = old2new(v, t->type);
+       if(local)
+               v = old2new(v, t->type);
        on = syslook("mapiter2", 1);
        argtype(on, th);
        argtype(on, t->down);