diff options
author | Ken Thompson <ken@golang.org> | 2008-12-06 13:40:30 -0800 |
---|---|---|
committer | Ken Thompson <ken@golang.org> | 2008-12-06 13:40:30 -0800 |
commit | 1fc79f74b49c144cc137f7da6cfbe514fabcac88 (patch) | |
tree | a5799d590d4b08857ded5ebf74570c170653bc55 /src | |
parent | 7d7b7fb2a8cab5426c3454ff32eff9ff23967c36 (diff) | |
download | golang-1fc79f74b49c144cc137f7da6cfbe514fabcac88.tar.gz |
allowed syntax for range
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
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/gc/go.h | 4 | ||||
-rw-r--r-- | src/cmd/gc/go.y | 56 | ||||
-rw-r--r-- | src/cmd/gc/subr.c | 1 | ||||
-rw-r--r-- | src/cmd/gc/walk.c | 36 |
4 files changed, 75 insertions, 22 deletions
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index b8429c3bd..68898c998 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -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*); diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y index 2944d5510..bcee5ec5b 100644 --- a/src/cmd/gc/go.y +++ b/src/cmd/gc/go.y @@ -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 diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 851f17404..cd2fc4d2d 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -687,6 +687,7 @@ opnames[] = [OREGISTER] = "REGISTER", [OINDREG] = "INDREG", [OSEND] = "SEND", + [ORANGE] = "RANGE", [ORECV] = "RECV", [OPTR] = "PTR", [ORETURN] = "RETURN", diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 68cf9123d..067aed49d 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -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); |