mirror of
https://github.com/golang/go
synced 2024-11-21 22:24:40 -07:00
gc: add delete(m, x) but leave in m[x] = 0, false.
The old m[x] = 0, false syntax will be deleted in a month or so, once people have had time to change their code (there is a gofix in a separate CL). R=ken2 CC=golang-dev https://golang.org/cl/5265048
This commit is contained in:
parent
1095305232
commit
1d687c742d
@ -64,6 +64,7 @@ char *runtimeimport =
|
||||
"func @\"\".mapassign1 (mapType *uint8, hmap map[any] any, key any, val any)\n"
|
||||
"func @\"\".mapassign2 (mapType *uint8, hmap map[any] any, key any, val any, pres bool)\n"
|
||||
"func @\"\".mapiterinit (mapType *uint8, hmap map[any] any, hiter *any)\n"
|
||||
"func @\"\".mapdelete (mapType *uint8, hmap map[any] any, key any)\n"
|
||||
"func @\"\".mapiternext (hiter *any)\n"
|
||||
"func @\"\".mapiter1 (hiter *any) any\n"
|
||||
"func @\"\".mapiter2 (hiter *any) (key any, val any)\n"
|
||||
|
@ -425,7 +425,8 @@ enum
|
||||
OAPPEND,
|
||||
OARRAYBYTESTR, OARRAYRUNESTR,
|
||||
OSTRARRAYBYTE, OSTRARRAYRUNE,
|
||||
OAS, OAS2, OAS2MAPW, OAS2FUNC, OAS2RECV, OAS2MAPR, OAS2DOTTYPE, OASOP,
|
||||
OAS, OAS2, OAS2MAPW, OAS2FUNC, OAS2RECV, OAS2MAPR, OAS2DOTTYPE,
|
||||
OASOP,
|
||||
OBAD,
|
||||
OCALL, OCALLFUNC, OCALLMETH, OCALLINTER,
|
||||
OCAP,
|
||||
@ -436,6 +437,7 @@ enum
|
||||
OCONV, OCONVIFACE, OCONVNOP,
|
||||
OCOPY,
|
||||
ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE,
|
||||
ODELETE,
|
||||
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT,
|
||||
ODOTTYPE,
|
||||
ODOTTYPE2,
|
||||
|
@ -1624,6 +1624,7 @@ static struct
|
||||
"close", LNAME, Txxx, OCLOSE,
|
||||
"complex", LNAME, Txxx, OCOMPLEX,
|
||||
"copy", LNAME, Txxx, OCOPY,
|
||||
"delete", LNAME, Txxx, ODELETE,
|
||||
"imag", LNAME, Txxx, OIMAG,
|
||||
"len", LNAME, Txxx, OLEN,
|
||||
"make", LNAME, Txxx, OMAKE,
|
||||
|
@ -87,6 +87,7 @@ func mapaccess2(mapType *byte, hmap map[any]any, key any) (val any, pres bool)
|
||||
func mapassign1(mapType *byte, hmap map[any]any, key any, val any)
|
||||
func mapassign2(mapType *byte, hmap map[any]any, key any, val any, pres bool)
|
||||
func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
|
||||
func mapdelete(mapType *byte, hmap map[any]any, key any)
|
||||
func mapiternext(hiter *any)
|
||||
func mapiter1(hiter *any) (key any)
|
||||
func mapiter2(hiter *any) (key any, val any)
|
||||
|
@ -923,6 +923,7 @@ goopnames[] =
|
||||
[OCOPY] = "copy",
|
||||
[ODEC] = "--",
|
||||
[ODEFER] = "defer",
|
||||
[ODELETE] = "delete",
|
||||
[ODIV] = "/",
|
||||
[OEQ] = "==",
|
||||
[OFALL] = "fallthrough",
|
||||
|
@ -991,6 +991,31 @@ reswitch:
|
||||
ok |= Etop;
|
||||
goto ret;
|
||||
|
||||
case ODELETE:
|
||||
args = n->list;
|
||||
if(args == nil) {
|
||||
yyerror("missing arguments to delete");
|
||||
goto error;
|
||||
}
|
||||
if(args->next == nil) {
|
||||
yyerror("missing second (key) argument to delete");
|
||||
goto error;
|
||||
}
|
||||
if(args->next->next != nil) {
|
||||
yyerror("too many arguments to delete");
|
||||
goto error;
|
||||
}
|
||||
ok |= Etop;
|
||||
typechecklist(args, Erv);
|
||||
l = args->n;
|
||||
r = args->next->n;
|
||||
if(l->type != T && l->type->etype != TMAP) {
|
||||
yyerror("first argument to delete must be map; have %lT", l->type);
|
||||
goto error;
|
||||
}
|
||||
args->next->n = assignconv(r, l->type->down, "delete");
|
||||
goto ret;
|
||||
|
||||
case OAPPEND:
|
||||
ok |= Erv;
|
||||
args = n->list;
|
||||
@ -2284,7 +2309,7 @@ typecheckas2(Node *n)
|
||||
{
|
||||
int cl, cr;
|
||||
NodeList *ll, *lr;
|
||||
Node *l, *r;
|
||||
Node *l, *r, *rr;
|
||||
Iter s;
|
||||
Type *t;
|
||||
|
||||
@ -2325,8 +2350,14 @@ typecheckas2(Node *n)
|
||||
goto out;
|
||||
n->op = OAS2MAPW;
|
||||
n->rlist->n = assignconv(r, l->type, "assignment");
|
||||
r = n->rlist->next->n;
|
||||
n->rlist->next->n = assignconv(r, types[TBOOL], "assignment");
|
||||
rr = n->rlist->next->n;
|
||||
n->rlist->next->n = assignconv(rr, types[TBOOL], "assignment");
|
||||
if(isconst(rr, CTBOOL) && !rr->val.u.bval) {
|
||||
n->op = ODELETE;
|
||||
n->list = list(list1(l->left), l->right);
|
||||
n->right = n->rlist->n;
|
||||
n->rlist = nil;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
static Node* walkprint(Node*, NodeList**, int);
|
||||
static Node* conv(Node*, Type*);
|
||||
static Node* mapfn(char*, Type*);
|
||||
static Node* mapfndel(char*, Type*);
|
||||
static Node* makenewvar(Type*, NodeList**, Node**);
|
||||
static Node* ascompatee1(int, Node*, Node*, NodeList**);
|
||||
static NodeList* ascompatee(int, NodeList*, NodeList*, NodeList**);
|
||||
@ -173,6 +174,7 @@ walkstmt(Node **np)
|
||||
case OCALLINTER:
|
||||
case OCALL:
|
||||
case OCALLFUNC:
|
||||
case ODELETE:
|
||||
case OSEND:
|
||||
case ORECV:
|
||||
case OPRINT:
|
||||
@ -610,6 +612,21 @@ walkexpr(Node **np, NodeList **init)
|
||||
n->op = OAS2FUNC;
|
||||
goto as2func;
|
||||
|
||||
case ODELETE:
|
||||
*init = concat(*init, n->ninit);
|
||||
n->ninit = nil;
|
||||
l = n->list->n;
|
||||
r = n->list->next->n;
|
||||
if(n->right != N) {
|
||||
// TODO: Remove once two-element map assigment is gone.
|
||||
l = safeexpr(l, init);
|
||||
r = safeexpr(r, init);
|
||||
safeexpr(n->right, init); // cause side effects from n->right
|
||||
}
|
||||
t = l->type;
|
||||
n = mkcall1(mapfndel("mapdelete", t), t->down, init, typename(t), l, r);
|
||||
goto ret;
|
||||
|
||||
case OAS2MAPW:
|
||||
// map[] = a,b - mapassign2
|
||||
// a,b = m[i];
|
||||
@ -2254,6 +2271,20 @@ mapfn(char *name, Type *t)
|
||||
return fn;
|
||||
}
|
||||
|
||||
static Node*
|
||||
mapfndel(char *name, Type *t)
|
||||
{
|
||||
Node *fn;
|
||||
|
||||
if(t->etype != TMAP)
|
||||
fatal("mapfn %T", t);
|
||||
fn = syslook(name, 1);
|
||||
argtype(fn, t->down);
|
||||
argtype(fn, t->type);
|
||||
argtype(fn, t->down);
|
||||
return fn;
|
||||
}
|
||||
|
||||
static Node*
|
||||
addstr(Node *n, NodeList **init)
|
||||
{
|
||||
|
@ -1028,6 +1028,28 @@ runtime·mapassign2(MapType *t, Hmap *h, ...)
|
||||
}
|
||||
}
|
||||
|
||||
// mapdelete(mapType *type, hmap *map[any]any, key any)
|
||||
#pragma textflag 7
|
||||
void
|
||||
runtime·mapdelete(MapType *t, Hmap *h, ...)
|
||||
{
|
||||
byte *ak;
|
||||
|
||||
if(h == nil)
|
||||
runtime·panicstring("deletion of entry in nil map");
|
||||
|
||||
ak = (byte*)&h + h->ko2;
|
||||
runtime·mapassign(t, h, ak, nil);
|
||||
|
||||
if(debug) {
|
||||
runtime·prints("mapdelete: map=");
|
||||
runtime·printpointer(h);
|
||||
runtime·prints("; key=");
|
||||
h->keyalg->print(h->keysize, ak);
|
||||
runtime·prints("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// For reflect:
|
||||
// func mapassign(t type h map, key, val iword, pres bool)
|
||||
// where an iword is the same word an interface value would use:
|
||||
|
Loading…
Reference in New Issue
Block a user