From b79272d9a24256bee2755a21d6ee666e6eb6b9cb Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Sat, 6 Dec 2008 13:40:30 -0800 Subject: [PATCH] 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 --- src/cmd/gc/go.h | 4 ++-- src/cmd/gc/go.y | 58 +++++++++++++++++++++++++++++++++++------------ src/cmd/gc/subr.c | 1 + src/cmd/gc/walk.c | 36 +++++++++++++++++++++++------ 4 files changed, 76 insertions(+), 23 deletions(-) diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index b8429c3bd02..68898c99884 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 2944d55101d..bcee5ec5b38 100644 --- a/src/cmd/gc/go.y +++ b/src/cmd/gc/go.y @@ -52,7 +52,7 @@ %type Astmt Bstmt %type for_stmt for_body for_header %type if_stmt if_body if_header select_stmt -%type simple_stmt osimple_stmt semi_stmt +%type simple_stmt osimple_stmt orange_stmt semi_stmt %type expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r %type exprsym3_list_r exprsym3 %type 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(); } -for_header: - osimple_stmt ';' osimple_stmt ';' osimple_stmt +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 ';' 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 851f17404f6..cd2fc4d2d53 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 68cf9123dec..067aed49d48 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);