mirror of
https://github.com/golang/go
synced 2024-11-20 10:14:43 -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 @\"\".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 @\"\".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 @\"\".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 @\"\".mapiternext (hiter *any)\n"
|
||||||
"func @\"\".mapiter1 (hiter *any) any\n"
|
"func @\"\".mapiter1 (hiter *any) any\n"
|
||||||
"func @\"\".mapiter2 (hiter *any) (key any, val any)\n"
|
"func @\"\".mapiter2 (hiter *any) (key any, val any)\n"
|
||||||
|
@ -425,7 +425,8 @@ enum
|
|||||||
OAPPEND,
|
OAPPEND,
|
||||||
OARRAYBYTESTR, OARRAYRUNESTR,
|
OARRAYBYTESTR, OARRAYRUNESTR,
|
||||||
OSTRARRAYBYTE, OSTRARRAYRUNE,
|
OSTRARRAYBYTE, OSTRARRAYRUNE,
|
||||||
OAS, OAS2, OAS2MAPW, OAS2FUNC, OAS2RECV, OAS2MAPR, OAS2DOTTYPE, OASOP,
|
OAS, OAS2, OAS2MAPW, OAS2FUNC, OAS2RECV, OAS2MAPR, OAS2DOTTYPE,
|
||||||
|
OASOP,
|
||||||
OBAD,
|
OBAD,
|
||||||
OCALL, OCALLFUNC, OCALLMETH, OCALLINTER,
|
OCALL, OCALLFUNC, OCALLMETH, OCALLINTER,
|
||||||
OCAP,
|
OCAP,
|
||||||
@ -436,6 +437,7 @@ enum
|
|||||||
OCONV, OCONVIFACE, OCONVNOP,
|
OCONV, OCONVIFACE, OCONVNOP,
|
||||||
OCOPY,
|
OCOPY,
|
||||||
ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE,
|
ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE,
|
||||||
|
ODELETE,
|
||||||
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT,
|
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT,
|
||||||
ODOTTYPE,
|
ODOTTYPE,
|
||||||
ODOTTYPE2,
|
ODOTTYPE2,
|
||||||
|
@ -1624,6 +1624,7 @@ static struct
|
|||||||
"close", LNAME, Txxx, OCLOSE,
|
"close", LNAME, Txxx, OCLOSE,
|
||||||
"complex", LNAME, Txxx, OCOMPLEX,
|
"complex", LNAME, Txxx, OCOMPLEX,
|
||||||
"copy", LNAME, Txxx, OCOPY,
|
"copy", LNAME, Txxx, OCOPY,
|
||||||
|
"delete", LNAME, Txxx, ODELETE,
|
||||||
"imag", LNAME, Txxx, OIMAG,
|
"imag", LNAME, Txxx, OIMAG,
|
||||||
"len", LNAME, Txxx, OLEN,
|
"len", LNAME, Txxx, OLEN,
|
||||||
"make", LNAME, Txxx, OMAKE,
|
"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 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 mapassign2(mapType *byte, hmap map[any]any, key any, val any, pres bool)
|
||||||
func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
|
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 mapiternext(hiter *any)
|
||||||
func mapiter1(hiter *any) (key any)
|
func mapiter1(hiter *any) (key any)
|
||||||
func mapiter2(hiter *any) (key any, val any)
|
func mapiter2(hiter *any) (key any, val any)
|
||||||
|
@ -923,6 +923,7 @@ goopnames[] =
|
|||||||
[OCOPY] = "copy",
|
[OCOPY] = "copy",
|
||||||
[ODEC] = "--",
|
[ODEC] = "--",
|
||||||
[ODEFER] = "defer",
|
[ODEFER] = "defer",
|
||||||
|
[ODELETE] = "delete",
|
||||||
[ODIV] = "/",
|
[ODIV] = "/",
|
||||||
[OEQ] = "==",
|
[OEQ] = "==",
|
||||||
[OFALL] = "fallthrough",
|
[OFALL] = "fallthrough",
|
||||||
|
@ -991,6 +991,31 @@ reswitch:
|
|||||||
ok |= Etop;
|
ok |= Etop;
|
||||||
goto ret;
|
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:
|
case OAPPEND:
|
||||||
ok |= Erv;
|
ok |= Erv;
|
||||||
args = n->list;
|
args = n->list;
|
||||||
@ -2284,7 +2309,7 @@ typecheckas2(Node *n)
|
|||||||
{
|
{
|
||||||
int cl, cr;
|
int cl, cr;
|
||||||
NodeList *ll, *lr;
|
NodeList *ll, *lr;
|
||||||
Node *l, *r;
|
Node *l, *r, *rr;
|
||||||
Iter s;
|
Iter s;
|
||||||
Type *t;
|
Type *t;
|
||||||
|
|
||||||
@ -2325,8 +2350,14 @@ typecheckas2(Node *n)
|
|||||||
goto out;
|
goto out;
|
||||||
n->op = OAS2MAPW;
|
n->op = OAS2MAPW;
|
||||||
n->rlist->n = assignconv(r, l->type, "assignment");
|
n->rlist->n = assignconv(r, l->type, "assignment");
|
||||||
r = n->rlist->next->n;
|
rr = n->rlist->next->n;
|
||||||
n->rlist->next->n = assignconv(r, types[TBOOL], "assignment");
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
static Node* walkprint(Node*, NodeList**, int);
|
static Node* walkprint(Node*, NodeList**, int);
|
||||||
static Node* conv(Node*, Type*);
|
static Node* conv(Node*, Type*);
|
||||||
static Node* mapfn(char*, Type*);
|
static Node* mapfn(char*, Type*);
|
||||||
|
static Node* mapfndel(char*, Type*);
|
||||||
static Node* makenewvar(Type*, NodeList**, Node**);
|
static Node* makenewvar(Type*, NodeList**, Node**);
|
||||||
static Node* ascompatee1(int, Node*, Node*, NodeList**);
|
static Node* ascompatee1(int, Node*, Node*, NodeList**);
|
||||||
static NodeList* ascompatee(int, NodeList*, NodeList*, NodeList**);
|
static NodeList* ascompatee(int, NodeList*, NodeList*, NodeList**);
|
||||||
@ -173,6 +174,7 @@ walkstmt(Node **np)
|
|||||||
case OCALLINTER:
|
case OCALLINTER:
|
||||||
case OCALL:
|
case OCALL:
|
||||||
case OCALLFUNC:
|
case OCALLFUNC:
|
||||||
|
case ODELETE:
|
||||||
case OSEND:
|
case OSEND:
|
||||||
case ORECV:
|
case ORECV:
|
||||||
case OPRINT:
|
case OPRINT:
|
||||||
@ -610,6 +612,21 @@ walkexpr(Node **np, NodeList **init)
|
|||||||
n->op = OAS2FUNC;
|
n->op = OAS2FUNC;
|
||||||
goto as2func;
|
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:
|
case OAS2MAPW:
|
||||||
// map[] = a,b - mapassign2
|
// map[] = a,b - mapassign2
|
||||||
// a,b = m[i];
|
// a,b = m[i];
|
||||||
@ -2254,6 +2271,20 @@ mapfn(char *name, Type *t)
|
|||||||
return fn;
|
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*
|
static Node*
|
||||||
addstr(Node *n, NodeList **init)
|
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:
|
// For reflect:
|
||||||
// func mapassign(t type h map, key, val iword, pres bool)
|
// func mapassign(t type h map, key, val iword, pres bool)
|
||||||
// where an iword is the same word an interface value would use:
|
// where an iword is the same word an interface value would use:
|
||||||
|
Loading…
Reference in New Issue
Block a user