From: Russ Cox Date: Fri, 22 Oct 2010 03:17:20 +0000 (-0400) Subject: gc: implement new composite literal spec X-Git-Tag: weekly.2010-10-27~47 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=8ffc4ec5d0c3d17d633c277ba5102da838834f03;p=gostls13.git gc: implement new composite literal spec R=ken2 CC=golang-dev https://golang.org/cl/2350041 --- diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y index 8a98d24017..7960a22640 100644 --- a/src/cmd/gc/go.y +++ b/src/cmd/gc/go.y @@ -52,7 +52,7 @@ static void fixlbrace(int); %type stmt ntype %type arg_type %type case caseblock -%type compound_stmt dotname embed expr +%type compound_stmt dotname embed expr complitexpr %type expr_or_type %type fndcl fnliteral %type for_body for_header for_stmt if_header if_stmt non_dcl_stmt @@ -889,6 +889,20 @@ pexpr_no_paren: } | fnliteral +keyval: + expr ':' complitexpr + { + $$ = nod(OKEY, $1, $3); + } + +complitexpr: + expr +| '{' braced_keyval_list '}' + { + $$ = nod(OCOMPLIT, N, N); + $$->list = $2; + } + pexpr: pexpr_no_paren | '(' expr_or_type ')' @@ -1094,13 +1108,6 @@ interfacetype: fixlbrace($2); } -keyval: - expr ':' expr - { - $$ = nod(OKEY, $1, $3); - } - - /* * function stuff * all in one place to show how crappy it all is @@ -1552,7 +1559,7 @@ keyval_list: { $$ = list1($1); } -| expr +| complitexpr { $$ = list1($1); } @@ -1560,7 +1567,7 @@ keyval_list: { $$ = list($1, $3); } -| keyval_list ',' expr +| keyval_list ',' complitexpr { $$ = list($1, $3); } diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index 89cd1d6591..43cf4a7c36 100644 --- a/src/cmd/gc/typecheck.c +++ b/src/cmd/gc/typecheck.c @@ -1776,7 +1776,7 @@ typecheckcomplit(Node **np) int bad, i, len, nerr; Node *l, *n, *hash[101]; NodeList *ll; - Type *t, *f; + Type *t, *f, *pushtype; Sym *s; int32 lno; @@ -1784,11 +1784,38 @@ typecheckcomplit(Node **np) lno = lineno; memset(hash, 0, sizeof hash); + if(n->right == N) { + if(n->list != nil) + setlineno(n->list->n); + yyerror("missing type in composite literal"); + goto error; + } + setlineno(n->right); l = typecheck(&n->right /* sic */, Etype); if((t = l->type) == T) goto error; nerr = nerrors; + + // can omit type on composite literal values if the outer + // composite literal is array, slice, or map, and the + // element type is itself a struct, array, slice, or map. + pushtype = T; + if(t->etype == TARRAY || t->etype == TMAP) { + pushtype = t->type; + if(pushtype != T) { + switch(pushtype->etype) { + case TSTRUCT: + case TARRAY: + case TMAP: + break; + default: + pushtype = T; + break; + } + } + } + switch(t->etype) { default: yyerror("invalid type for composite literal: %T", t); @@ -1801,27 +1828,22 @@ typecheckcomplit(Node **np) for(ll=n->list; ll; ll=ll->next) { l = ll->n; setlineno(l); - if(l->op == OKEY) { - typecheck(&l->left, Erv); - evconst(l->left); - i = nonnegconst(l->left); - if(i < 0) { - yyerror("array index must be non-negative integer constant"); - i = -(1<<30); // stay negative for a while - } - typecheck(&l->right, Erv); - defaultlit(&l->right, t->type); - l->right = assignconv(l->right, t->type, "array index"); - } else { - typecheck(&ll->n, Erv); - defaultlit(&ll->n, t->type); - ll->n = assignconv(ll->n, t->type, "array index"); - ll->n = nod(OKEY, nodintconst(i), ll->n); - ll->n->left->type = types[TINT]; - ll->n->left->typecheck = 1; + if(l->op != OKEY) { + l = nod(OKEY, nodintconst(i), l); + l->left->type = types[TINT]; + l->left->typecheck = 1; + ll->n = l; + } + + typecheck(&l->left, Erv); + evconst(l->left); + i = nonnegconst(l->left); + if(i < 0) { + yyerror("array index must be non-negative integer constant"); + i = -(1<<30); // stay negative for a while } if(i >= 0) - indexdup(ll->n->left, hash, nelem(hash)); + indexdup(l->left, hash, nelem(hash)); i++; if(i > len) { len = i; @@ -1831,6 +1853,12 @@ typecheckcomplit(Node **np) t->bound = -1; // no more errors } } + + if(l->right->op == OCOMPLIT && l->right->right == N && pushtype != T) + l->right->right = typenod(pushtype); + typecheck(&l->right, Erv); + defaultlit(&l->right, t->type); + l->right = assignconv(l->right, t->type, "array index"); } if(t->bound == -100) t->bound = len; @@ -1848,13 +1876,17 @@ typecheckcomplit(Node **np) yyerror("missing key in map literal"); continue; } + typecheck(&l->left, Erv); - typecheck(&l->right, Erv); defaultlit(&l->left, t->down); - defaultlit(&l->right, t->type); l->left = assignconv(l->left, t->down, "map key"); - l->right = assignconv(l->right, t->type, "map value"); keydup(l->left, hash, nelem(hash)); + + if(l->right->op == OCOMPLIT && l->right->right == N && pushtype != T) + l->right->right = typenod(pushtype); + typecheck(&l->right, Erv); + defaultlit(&l->right, t->type); + l->right = assignconv(l->right, t->type, "map value"); } n->op = OMAPLIT; break;