mirror of
https://github.com/golang/go
synced 2024-09-24 11:20:20 -06:00
gc: implement new composite literal spec
R=ken2 CC=golang-dev https://golang.org/cl/2350041
This commit is contained in:
parent
e5bd12ea90
commit
8ffc4ec5d0
@ -52,7 +52,7 @@ static void fixlbrace(int);
|
|||||||
%type <node> stmt ntype
|
%type <node> stmt ntype
|
||||||
%type <node> arg_type
|
%type <node> arg_type
|
||||||
%type <node> case caseblock
|
%type <node> case caseblock
|
||||||
%type <node> compound_stmt dotname embed expr
|
%type <node> compound_stmt dotname embed expr complitexpr
|
||||||
%type <node> expr_or_type
|
%type <node> expr_or_type
|
||||||
%type <node> fndcl fnliteral
|
%type <node> fndcl fnliteral
|
||||||
%type <node> for_body for_header for_stmt if_header if_stmt non_dcl_stmt
|
%type <node> for_body for_header for_stmt if_header if_stmt non_dcl_stmt
|
||||||
@ -889,6 +889,20 @@ pexpr_no_paren:
|
|||||||
}
|
}
|
||||||
| fnliteral
|
| fnliteral
|
||||||
|
|
||||||
|
keyval:
|
||||||
|
expr ':' complitexpr
|
||||||
|
{
|
||||||
|
$$ = nod(OKEY, $1, $3);
|
||||||
|
}
|
||||||
|
|
||||||
|
complitexpr:
|
||||||
|
expr
|
||||||
|
| '{' braced_keyval_list '}'
|
||||||
|
{
|
||||||
|
$$ = nod(OCOMPLIT, N, N);
|
||||||
|
$$->list = $2;
|
||||||
|
}
|
||||||
|
|
||||||
pexpr:
|
pexpr:
|
||||||
pexpr_no_paren
|
pexpr_no_paren
|
||||||
| '(' expr_or_type ')'
|
| '(' expr_or_type ')'
|
||||||
@ -1094,13 +1108,6 @@ interfacetype:
|
|||||||
fixlbrace($2);
|
fixlbrace($2);
|
||||||
}
|
}
|
||||||
|
|
||||||
keyval:
|
|
||||||
expr ':' expr
|
|
||||||
{
|
|
||||||
$$ = nod(OKEY, $1, $3);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* function stuff
|
* function stuff
|
||||||
* all in one place to show how crappy it all is
|
* all in one place to show how crappy it all is
|
||||||
@ -1552,7 +1559,7 @@ keyval_list:
|
|||||||
{
|
{
|
||||||
$$ = list1($1);
|
$$ = list1($1);
|
||||||
}
|
}
|
||||||
| expr
|
| complitexpr
|
||||||
{
|
{
|
||||||
$$ = list1($1);
|
$$ = list1($1);
|
||||||
}
|
}
|
||||||
@ -1560,7 +1567,7 @@ keyval_list:
|
|||||||
{
|
{
|
||||||
$$ = list($1, $3);
|
$$ = list($1, $3);
|
||||||
}
|
}
|
||||||
| keyval_list ',' expr
|
| keyval_list ',' complitexpr
|
||||||
{
|
{
|
||||||
$$ = list($1, $3);
|
$$ = list($1, $3);
|
||||||
}
|
}
|
||||||
|
@ -1776,7 +1776,7 @@ typecheckcomplit(Node **np)
|
|||||||
int bad, i, len, nerr;
|
int bad, i, len, nerr;
|
||||||
Node *l, *n, *hash[101];
|
Node *l, *n, *hash[101];
|
||||||
NodeList *ll;
|
NodeList *ll;
|
||||||
Type *t, *f;
|
Type *t, *f, *pushtype;
|
||||||
Sym *s;
|
Sym *s;
|
||||||
int32 lno;
|
int32 lno;
|
||||||
|
|
||||||
@ -1784,11 +1784,38 @@ typecheckcomplit(Node **np)
|
|||||||
lno = lineno;
|
lno = lineno;
|
||||||
|
|
||||||
memset(hash, 0, sizeof hash);
|
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);
|
setlineno(n->right);
|
||||||
l = typecheck(&n->right /* sic */, Etype);
|
l = typecheck(&n->right /* sic */, Etype);
|
||||||
if((t = l->type) == T)
|
if((t = l->type) == T)
|
||||||
goto error;
|
goto error;
|
||||||
nerr = nerrors;
|
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) {
|
switch(t->etype) {
|
||||||
default:
|
default:
|
||||||
yyerror("invalid type for composite literal: %T", t);
|
yyerror("invalid type for composite literal: %T", t);
|
||||||
@ -1801,27 +1828,22 @@ typecheckcomplit(Node **np)
|
|||||||
for(ll=n->list; ll; ll=ll->next) {
|
for(ll=n->list; ll; ll=ll->next) {
|
||||||
l = ll->n;
|
l = ll->n;
|
||||||
setlineno(l);
|
setlineno(l);
|
||||||
if(l->op == OKEY) {
|
if(l->op != OKEY) {
|
||||||
typecheck(&l->left, Erv);
|
l = nod(OKEY, nodintconst(i), l);
|
||||||
evconst(l->left);
|
l->left->type = types[TINT];
|
||||||
i = nonnegconst(l->left);
|
l->left->typecheck = 1;
|
||||||
if(i < 0) {
|
ll->n = l;
|
||||||
yyerror("array index must be non-negative integer constant");
|
}
|
||||||
i = -(1<<30); // stay negative for a while
|
|
||||||
}
|
typecheck(&l->left, Erv);
|
||||||
typecheck(&l->right, Erv);
|
evconst(l->left);
|
||||||
defaultlit(&l->right, t->type);
|
i = nonnegconst(l->left);
|
||||||
l->right = assignconv(l->right, t->type, "array index");
|
if(i < 0) {
|
||||||
} else {
|
yyerror("array index must be non-negative integer constant");
|
||||||
typecheck(&ll->n, Erv);
|
i = -(1<<30); // stay negative for a while
|
||||||
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(i >= 0)
|
if(i >= 0)
|
||||||
indexdup(ll->n->left, hash, nelem(hash));
|
indexdup(l->left, hash, nelem(hash));
|
||||||
i++;
|
i++;
|
||||||
if(i > len) {
|
if(i > len) {
|
||||||
len = i;
|
len = i;
|
||||||
@ -1831,6 +1853,12 @@ typecheckcomplit(Node **np)
|
|||||||
t->bound = -1; // no more errors
|
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)
|
if(t->bound == -100)
|
||||||
t->bound = len;
|
t->bound = len;
|
||||||
@ -1848,13 +1876,17 @@ typecheckcomplit(Node **np)
|
|||||||
yyerror("missing key in map literal");
|
yyerror("missing key in map literal");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
typecheck(&l->left, Erv);
|
typecheck(&l->left, Erv);
|
||||||
typecheck(&l->right, Erv);
|
|
||||||
defaultlit(&l->left, t->down);
|
defaultlit(&l->left, t->down);
|
||||||
defaultlit(&l->right, t->type);
|
|
||||||
l->left = assignconv(l->left, t->down, "map key");
|
l->left = assignconv(l->left, t->down, "map key");
|
||||||
l->right = assignconv(l->right, t->type, "map value");
|
|
||||||
keydup(l->left, hash, nelem(hash));
|
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;
|
n->op = OMAPLIT;
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user