$$ = typ(TMAP);
$$->down = $3;
$$->type = $5;
+ $$ = ptrto($$);
}
| structtype
$$ = typ(TCHAN);
$$->type = $3;
$$->chan = Crecv;
+ $$ = ptrto($$);
}
| LCHAN LCOMM Anon_chan_type
{
$$ = typ(TCHAN);
$$->type = $3;
$$->chan = Csend;
+ $$ = ptrto($$);
}
| LMAP '[' type ']' Atype
{
$$ = typ(TMAP);
$$->down = $3;
$$->type = $5;
+ $$ = ptrto($$);
}
| '*' Atype
{
$$ = typ(TCHAN);
$$->type = $3;
$$->chan = Crecv;
+ $$ = ptrto($$);
}
| LCHAN LCOMM Bnon_chan_type
{
$$ = typ(TCHAN);
$$->type = $3;
$$->chan = Csend;
+ $$ = ptrto($$);
}
| LMAP '[' type ']' Btype
{
$$ = typ(TMAP);
$$->down = $3;
$$->type = $5;
+ $$ = ptrto($$);
}
| '*' Btype
{
$$ = typ(TCHAN);
$$->type = $2;
$$->chan = Cboth;
+ $$ = ptrto($$);
}
Bchantype:
$$ = typ(TCHAN);
$$->type = $2;
$$->chan = Cboth;
+ $$ = ptrto($$);
}
structtype:
$$ = typ(TMAP);
$$->down = $3;
$$->type = $5;
+ $$ = ptrto($$);
}
| LSTRUCT '{' ohidden_structdcl_list '}'
{
$$ = typ(TCHAN);
$$->type = $3;
$$->chan = Crecv;
+ $$ = ptrto($$);
}
| LCHAN LCOMM hidden_type1
{
$$ = typ(TCHAN);
$$->type = $3;
$$->chan = Csend;
+ $$ = ptrto($$);
}
| LDDD
{
$$ = typ(TCHAN);
$$->type = $2;
$$->chan = Cboth;
+ $$ = ptrto($$);
}
| '(' ohidden_funarg_list ')' ohidden_funres
{
switch(t->etype) {
case TPTR32:
case TPTR64:
- if(t->type && t->type->etype == TSTRING)
- return fmtprint(fp, "string");
- return fmtprint(fp, "*%T", t->type);
+ t1 = t->type;
+ if(t1 != T) {
+ switch(t1->etype) {
+ case TSTRING:
+ return fmtprint(fp, "string");
+ case TMAP:
+ return fmtprint(fp, "map[%T] %T", t1->down, t1->type);
+ case TCHAN:
+ return fmtprint(fp, "chan %T", t1->type);
+ }
+ }
+ return fmtprint(fp, "*%T", t1);
+
+ // Should not see these: should see ptr instead, handled above.
+ case TSTRING:
+ return fmtprint(fp, "STRING", t->type);
+ case TCHAN:
+ return fmtprint(fp, "CHAN %T", t->type);
+ case TMAP:
+ return fmtprint(fp, "MAP[%T] %T", t->down, t->type);
case TFUNC:
// t->type is method struct
return fmtprint(fp, "[%d]%T", (int)t->bound, t->type);
return fmtprint(fp, "[]%T", t->type);
- case TCHAN:
- return fmtprint(fp, "chan %T", t->type);
-
- case TMAP:
- return fmtprint(fp, "map[%T] %T", t->down, t->type);
-
case TINTER:
fmtprint(fp, "interface {");
for(t1=t->type; t1!=T; t1=t1->down) {
if(t == T)
return 0;
switch(t->etype) {
- case TMAP:
case TARRAY:
case TSTRUCT:
return 1;
}
+ if(isptr[t->etype] && t->type != T && t->type->etype == TMAP)
+ return 1;
return 0;
}
if(t->etype == TINTER)
e = "sigi";
+ // don't allow arrays in interfaces
+ if(t->etype == TARRAY)
+ goto bad;
+
// name is exported name, like *[]byte or *Struct or Interface
// (special symbols don't bother the linker).
snprint(buf, sizeof(buf), "%#T", t);
export func newmap(keysize int, valsize int,
keyalg int, valalg int,
- hint int) (hmap *map[any]any);
-export func mapaccess1(hmap *map[any]any, key any) (val any);
-export func mapaccess2(hmap *map[any]any, key any) (val any, pres bool);
-export func mapassign1(hmap *map[any]any, key any, val any);
-export func mapassign2(hmap *map[any]any, key any, val any, pres bool);
-export func mapiterinit(hmap *map[any]any, hiter *any);
+ hint int) (hmap map[any]any);
+export func mapaccess1(hmap map[any]any, key any) (val any);
+export func mapaccess2(hmap map[any]any, key any) (val any, pres bool);
+export func mapassign1(hmap map[any]any, key any, val any);
+export func mapassign2(hmap map[any]any, key any, val any, pres bool);
+export func mapiterinit(hmap map[any]any, hiter *any);
export func mapiternext(hiter *any);
export func mapiter1(hiter *any) (key any);
export func mapiter2(hiter *any) (key any, val any);
-export func newchan(elemsize int, elemalg int, hint int) (hchan *chan any);
-export func chanrecv1(hchan *chan any) (elem any);
-export func chanrecv2(hchan *chan any) (elem any, pres bool);
-export func chanrecv3(hchan *chan any, elem *any) (pres bool);
-export func chansend1(hchan *chan any, elem any);
-export func chansend2(hchan *chan any, elem any) (pres bool);
+export func newchan(elemsize int, elemalg int, hint int) (hchan chan any);
+export func chanrecv1(hchan chan any) (elem any);
+export func chanrecv2(hchan chan any) (elem any, pres bool);
+export func chanrecv3(hchan chan any, elem *any) (pres bool);
+export func chansend1(hchan chan any, elem any);
+export func chansend2(hchan chan any, elem any) (pres bool);
export func newselect(size int) (sel *byte);
-export func selectsend(sel *byte, hchan *chan any, elem any) (selected bool);
-export func selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
+export func selectsend(sel *byte, hchan chan any, elem any) (selected bool);
+export func selectrecv(sel *byte, hchan chan any, elem *any) (selected bool);
export func selectdefault(sel *byte) (selected bool);
export func selectgo(sel *byte);
"export func sys.float64bits (? float64) (? uint64)\n"
"export func sys.float32frombits (? uint32) (? float32)\n"
"export func sys.float64frombits (? uint64) (? float64)\n"
- "export func sys.newmap (keysize int, valsize int, keyalg int, valalg int, hint int) (hmap *map[any] any)\n"
- "export func sys.mapaccess1 (hmap *map[any] any, key any) (val any)\n"
- "export func sys.mapaccess2 (hmap *map[any] any, key any) (val any, pres bool)\n"
- "export func sys.mapassign1 (hmap *map[any] any, key any, val any)\n"
- "export func sys.mapassign2 (hmap *map[any] any, key any, val any, pres bool)\n"
- "export func sys.mapiterinit (hmap *map[any] any, hiter *any)\n"
+ "export func sys.newmap (keysize int, valsize int, keyalg int, valalg int, hint int) (hmap map[any] any)\n"
+ "export func sys.mapaccess1 (hmap map[any] any, key any) (val any)\n"
+ "export func sys.mapaccess2 (hmap map[any] any, key any) (val any, pres bool)\n"
+ "export func sys.mapassign1 (hmap map[any] any, key any, val any)\n"
+ "export func sys.mapassign2 (hmap map[any] any, key any, val any, pres bool)\n"
+ "export func sys.mapiterinit (hmap map[any] any, hiter *any)\n"
"export func sys.mapiternext (hiter *any)\n"
"export func sys.mapiter1 (hiter *any) (key any)\n"
"export func sys.mapiter2 (hiter *any) (key any, val any)\n"
- "export func sys.newchan (elemsize int, elemalg int, hint int) (hchan *chan any)\n"
- "export func sys.chanrecv1 (hchan *chan any) (elem any)\n"
- "export func sys.chanrecv2 (hchan *chan any) (elem any, pres bool)\n"
- "export func sys.chanrecv3 (hchan *chan any, elem *any) (pres bool)\n"
- "export func sys.chansend1 (hchan *chan any, elem any)\n"
- "export func sys.chansend2 (hchan *chan any, elem any) (pres bool)\n"
+ "export func sys.newchan (elemsize int, elemalg int, hint int) (hchan chan any)\n"
+ "export func sys.chanrecv1 (hchan chan any) (elem any)\n"
+ "export func sys.chanrecv2 (hchan chan any) (elem any, pres bool)\n"
+ "export func sys.chanrecv3 (hchan chan any, elem *any) (pres bool)\n"
+ "export func sys.chansend1 (hchan chan any, elem any)\n"
+ "export func sys.chansend2 (hchan chan any, elem any) (pres bool)\n"
"export func sys.newselect (size int) (sel *uint8)\n"
- "export func sys.selectsend (sel *uint8, hchan *chan any, elem any) (selected bool)\n"
- "export func sys.selectrecv (sel *uint8, hchan *chan any, elem *any) (selected bool)\n"
+ "export func sys.selectsend (sel *uint8, hchan chan any, elem any) (selected bool)\n"
+ "export func sys.selectrecv (sel *uint8, hchan chan any, elem *any) (selected bool)\n"
"export func sys.selectdefault (sel *uint8) (selected bool)\n"
"export func sys.selectgo (sel *uint8)\n"
"export func sys.newarray (nel int, cap int, width int) (ary []any)\n"
"export func sys.bytestorune (? *uint8, ? int, ? int) (? int, ? int)\n"
"export func sys.stringtorune (? string, ? int) (? int, ? int)\n"
"export func sys.exit (? int)\n"
- "export func sys.symdat () (symtab *[]uint8, pclntab *[]uint8)\n"
+ "export func sys.symdat () (symtab []uint8, pclntab []uint8)\n"
"export func sys.semacquire (sema *int32)\n"
"export func sys.semrelease (sema *int32)\n"
"\n"
}
// map literal
- if(t->etype == TMAP) {
+ if(isptr[t->etype] && t->type != t && t->type->etype == TMAP) {
r = maplit(n);
indir(n, r);
goto ret;
case OADDR:
if(top != Erv)
goto nottop;
- if(n->left->op == OCONV && iscomposite(n->left->type)) {
+ if(n->left->op == OCONV && n->left->type != T)
+ if(n->left->type->etype == TSTRUCT) {
// turn &Point{1, 2} into allocation.
// initialize with
- // nvar := new(Point);
+ // nvar := new(*Point);
// *nvar = Point{1, 2};
// and replace expression with nvar
// TODO(rsc): might do a better job (fewer copies) later
Node *nnew, *nvar, *nas;
+ t = ptrto(n->left->type);
walktype(n->left, Elv);
if(n->left == N)
goto ret;
nvar = nod(0, N, N);
- tempname(nvar, ptrto(n->left->type));
+ tempname(nvar, t);
nnew = nod(ONEW, N, N);
- nnew->type = n->left->type;
+ nnew->type = t;
nnew = newcompat(nnew);
nas = nod(OAS, nvar, nnew);
if(t == T)
goto bad;
-/*
- if(isptr[t->etype]) {
- if(t->type == T)
- goto bad;
- t = t->type;
+ if(t->etype == TARRAY)
+ return arrayop(n, Erv);
- dowidth(t);
+ if(!isptr[t->etype] || t->type == T)
+ goto bad;
- on = syslook("mal", 1);
- argtype(on, t);
+ t = t->type;
+ switch(t->etype) {
+ case TSTRING:
+ goto bad;
- r = nodintconst(t->width);
- r = nod(OCALL, on, r);
- walktype(r, Erv);
+ // the call looks like new(map[int]int)
+ // but internally we see new(*MAP[int]int)
+ case TMAP:
+ r = mapop(n, Erv);
+ break;
- r->type = n->type;
- goto ret;
- }
-*/
+ // the call looks like new(chan int)
+ // but internally we see new(*CHAN int)
+ case TCHAN:
+ r = chanop(n, Erv);
+ break;
- switch(t->etype) {
default:
-// goto bad;
-//
-// case TSTRUCT:
if(n->left != N)
- yyerror("dont know what new(,e) means");
-
+ yyerror("cannot new(*%T, expr)", t);
dowidth(t);
-
on = syslook("mal", 1);
-
argtype(on, t);
-
r = nodintconst(t->width);
r = nod(OCALL, on, r);
walktype(r, Erv);
-
- r->type = ptrto(n->type);
-
- return r;
- case TMAP:
- n->type = ptrto(n->type);
- r = mapop(n, Erv);
- break;
-
- case TCHAN:
- n->type = ptrto(n->type);
- r = chanop(n, Erv);
- break;
-
- case TARRAY:
- r = arrayop(n, Erv);
break;
}
-ret:
return r;
bad:
- fatal("cannot make new %T", t);
+ yyerror("cannot new(*%T)", t);
return n;
}
// newmap(keysize int, valsize int,
// keyalg int, valalg int,
- // hint int) (hmap *map[any-1]any-2);
+ // hint int) (hmap map[any-1]any-2);
t = fixmap(n->type);
if(t == T)
case OINDEX:
if(top != Erv)
goto nottop;
- // mapaccess1(hmap *map[any]any, key any) (val any);
+ // mapaccess1(hmap map[any]any, key any) (val any);
t = fixmap(n->left->type);
if(t == T)
if(cl != 1 || cr != 1)
goto shape;
- // mapassign1(hmap *map[any-1]any-2, key any-3, val any-4);
+ // mapassign1(hmap map[any-1]any-2, key any-3, val any-4);
if(n->left->op != OINDEX)
goto shape;
break;
assign2:
- // mapassign2(hmap *map[any]any, key any, val any, pres bool);
+ // mapassign2(hmap map[any]any, key any, val any, pres bool);
if(n->left->op != OINDEX)
goto shape;
break;
access2:
- // mapaccess2(hmap *map[any-1]any-2, key any-3) (val-4 any, pres bool);
+ // mapaccess2(hmap map[any-1]any-2, key any-3) (val-4 any, pres bool);
//dump("access2", n);
if(n->right->op != OINDEX)
{
Iter saver;
Type *t;
- Node *var, *r, *a, *nas, *nnew, *ncon;
+ Node *var, *r, *a, *nas, *nnew;
int idx;
t = n->type;
if(t->bound >= 0)
fatal("arraylit: literal fixed arrays not implemented");
-
+
var = nod(OXXX, N, N);
tempname(var, t);
-
+
nnew = nod(ONEW, N, N);
nnew->type = t;
-
+
nas = nod(OAS, var, nnew);
addtop = list(addtop, nas);
Node *var, *r, *a;
t = n->type;
- if(t->etype != TMAP)
- fatal("maplit: not array");
- t = ptrto(t);
+ if(!isptr[t->etype] || t->type == T || t->type->etype != TMAP)
+ fatal("maplit: not map");
var = nod(OXXX, N, N);
tempname(var, t);
a = nod(ONEW, N, N);
- a->type = t->type;
+ a->type = t;
a = nod(OAS, var, a);
addtop = list(addtop, a);